@marcel91200 / caddy Mirror · read-only / commits / 0c8ad52b
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

Experimental IETF-standard HTTP/3 support (known issue exists) (#2727)

* Begin WIP integration of HTTP/3 support * http3: Set actual Handler, make fakeClosePacketConn type for UDP sockets Also use latest quic-go for ALPN fix * Manually keep track of and close HTTP/3 listeners * Update quic-go after working through some http3 bugs * Fix go mod * Make http3 optional for now

Matt Holt committed Sep 10, 2019 at 08:03 UTC 0c8ad52be127add6f2c050230f1f166ecbde813c
6 files changed +153 -6
cmd/main.go
+1 -1
@@ -33,7 +33,7 @@ import (
33 func Main() {
34 caddy.TrapSignals()
35
36 - if len(os.Args) <= 1 {
36 + if len(os.Args) < 2 {
37 fmt.Println(usageString())
38 return
39 }
go.mod
+1 -1
@@ -17,6 +17,7 @@ require (
17 github.com/imdario/mergo v0.3.7 // indirect
18 github.com/klauspost/compress v1.7.1-0.20190613161414-0b31f265a57b
19 github.com/klauspost/cpuid v1.2.1
20 + github.com/lucas-clemente/quic-go v0.7.1-0.20190908032346-fc962d18373a
21 github.com/mholt/certmagic v0.6.2
22 github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936
23 github.com/muhammadmuzzammil1998/jsonc v0.0.0-20190902132743-e4903c4dea48
@@ -26,7 +27,6 @@ require (
27 github.com/starlight-go/starlight v0.0.0-20181207205707-b06f321544f3
28 go.starlark.net v0.0.0-20190604130855-6ddc71c0ba77
29 golang.org/x/net v0.0.0-20190603091049-60506f45cf65
29 - golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e // indirect
30 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
31 gopkg.in/yaml.v2 v2.2.2 // indirect
32 )
go.sum
+42 -2
@@ -6,23 +6,36 @@ github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITg
6 github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
7 github.com/Masterminds/sprig v2.20.0+incompatible h1:dJTKKuUkYW3RMFdQFXPU/s6hg10RgctmTjRcbZ98Ap8=
8 github.com/Masterminds/sprig v2.20.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
9 +github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75 h1:3ILjVyslFbc4jl1w5TWuvvslFD/nDfR2H8tVaMVLrEY=
10 +github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE=
11 github.com/andybalholm/brotli v0.0.0-20190704151324-71eb68cc467c h1:pBKtfXLqKZ+GPHGjlBheGaXK2lddydUG3XhWGrYjxOA=
12 github.com/andybalholm/brotli v0.0.0-20190704151324-71eb68cc467c/go.mod h1:+lx6/Aqd1kLJ1GQfkvOnaZ1WGmLpMpbprPuIOOZX30U=
13 github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
14 github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
15 +github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
16 +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
17 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
18 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
19 github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
20 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
21 +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
22 +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
23 github.com/go-acme/lego v2.5.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M=
24 github.com/go-acme/lego v2.6.0+incompatible h1:KxcEWOF5hKtgou4xIqPaXSRF9DoO4OJ90ndwdK6YH/k=
25 github.com/go-acme/lego v2.6.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M=
26 github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 h1:KRMr9A3qfbVM7iV/WcLY/rL5LICqwMHLhwRXKu99fXw=
27 github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4=
28 +github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
29 +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
30 +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
31 +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
32 +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
33 github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
34 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
35 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
36 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
37 +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
38 +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
39 github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0=
40 github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
41 github.com/ilibs/json5 v1.0.1 h1:3e14wUQM8PyK6Hf1bM+zAQFxfG+N5oZj35x5vCNeQ58=
@@ -34,6 +47,14 @@ github.com/klauspost/compress v1.7.1-0.20190613161414-0b31f265a57b/go.mod h1:RyI
47 github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
48 github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
49 github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
50 +github.com/lucas-clemente/quic-go v0.7.1-0.20190908032346-fc962d18373a h1:4NDhBYEqjdNTQhlkLK8u4FGq1mMDQv4V4MLDSS5oCS0=
51 +github.com/lucas-clemente/quic-go v0.7.1-0.20190908032346-fc962d18373a/go.mod h1:iP3S21xvg0qlsEAz+goZ/qfptsfhshjzkbhEK6Ka3Fg=
52 +github.com/marten-seemann/chacha20 v0.2.0 h1:f40vqzzx+3GdOmzQoItkLX5WLvHgPgyYqFFIO5Gh4hQ=
53 +github.com/marten-seemann/chacha20 v0.2.0/go.mod h1:HSdjFau7GzYRj+ahFNwsO3ouVJr1HFkWoEwNDb4TMtE=
54 +github.com/marten-seemann/qpack v0.1.0 h1:/0M7lkda/6mus9B8u34Asqm8ZhHAAt9Ho0vniNuVSVg=
55 +github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI=
56 +github.com/marten-seemann/qtls v0.4.0 h1:HM9ftULNeuhGiCliIfPKvp5VDJw6pvi/Ghq6PYf7B0E=
57 +github.com/marten-seemann/qtls v0.4.0/go.mod h1:pxVXcHHw1pNIt8Qo0pwSYQEoZ8yYOOPXTCZLQQunvRc=
58 github.com/mholt/certmagic v0.6.2 h1:yy9cKm3rtxdh12SW4E51lzG3Eo6N59LEOfBQ0CTnMms=
59 github.com/mholt/certmagic v0.6.2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY=
60 github.com/miekg/dns v1.1.3 h1:1g0r1IvskvgL8rR+AcHzUA+oFmGcQlaIm4IqakufeMM=
@@ -42,6 +63,11 @@ github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 h1:kw1v0NlnN+GZcU8
63 github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
64 github.com/muhammadmuzzammil1998/jsonc v0.0.0-20190902132743-e4903c4dea48 h1:BM/fjd7MfvZuyoHXLv3YlWNIuNb47PLp6EyFBL1KIMg=
65 github.com/muhammadmuzzammil1998/jsonc v0.0.0-20190902132743-e4903c4dea48/go.mod h1:saF2fIVw4banK0H4+/EuqfFLpRnoy5S+ECwTOCcRcSU=
66 +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
67 +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
68 +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
69 +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
70 +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
71 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
72 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
73 github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
@@ -60,23 +86,37 @@ go.starlark.net v0.0.0-20190604130855-6ddc71c0ba77/go.mod h1:c1/X6cHgvdXj6pUlmWK
86 golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
87 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
88 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
89 +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
90 +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
91 +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
92 golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
93 +golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
94 +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
95 golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
96 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
97 +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
98 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
99 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
100 +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
101 golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
102 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
103 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
71 -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c=
72 -golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
104 +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
105 +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0=
106 +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
107 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
108 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
109 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
110 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
111 +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
112 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
113 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
114 +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
115 +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
116 gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA=
117 gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
118 +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
119 +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
120 +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
121 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
122 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
listeners.go
+59 -1
@@ -16,6 +16,7 @@ package caddy
16
17 import (
18 "fmt"
19 + "log"
20 "net"
21 "strconv"
22 "strings"
@@ -53,13 +54,41 @@ func Listen(network, addr string) (net.Listener, error) {
54 return &fakeCloseListener{usage: &lnUsage.usage, key: lnKey, Listener: ln}, nil
55 }
56
57 +// ListenPacket returns a net.PacketConn suitable for use in a Caddy module.
58 +// Always be sure to close the PacketConn when you are done.
59 +func ListenPacket(network, addr string) (net.PacketConn, error) {
60 + lnKey := network + "/" + addr
61 +
62 + listenersMu.Lock()
63 + defer listenersMu.Unlock()
64 +
65 + // if listener already exists, increment usage counter, then return listener
66 + if lnUsage, ok := listeners[lnKey]; ok {
67 + atomic.AddInt32(&lnUsage.usage, 1)
68 + log.Printf("[DEBUG] %s: Usage counter should not go above 2 or maybe 3, is now: %d", lnKey, atomic.LoadInt32(&lnUsage.usage)) // TODO: remove
69 + return &fakeClosePacketConn{usage: &lnUsage.usage, key: lnKey, PacketConn: lnUsage.pc}, nil
70 + }
71 +
72 + // or, create new one and save it
73 + pc, err := net.ListenPacket(network, addr)
74 + if err != nil {
75 + return nil, err
76 + }
77 +
78 + // make sure to start its usage counter at 1
79 + lnUsage := &listenerUsage{usage: 1, pc: pc}
80 + listeners[lnKey] = lnUsage
81 +
82 + return &fakeClosePacketConn{usage: &lnUsage.usage, key: lnKey, PacketConn: pc}, nil
83 +}
84 +
85 // fakeCloseListener's Close() method is a no-op. This allows
86 // stopping servers that are using the listener without giving
87 // up the socket; thus, servers become hot-swappable while the
88 // listener remains running. Listeners should be re-wrapped in
89 // a new fakeCloseListener each time the listener is reused.
90 type fakeCloseListener struct {
62 - closed int32 // accessed atomically
91 + closed int32 // accessed atomically - TODO: this needs to be shared across the whole app instance, not to cross instance boundaries... hmmm... see #2658 (still relevant?)
92 usage *int32 // accessed atomically
93 key string
94 net.Listener
@@ -146,6 +175,34 @@ func (fcl *fakeCloseListener) fakeClosedErr() error {
175 }
176 }
177
178 +type fakeClosePacketConn struct {
179 + closed int32 // accessed atomically - TODO: this needs to be shared across the whole app instance, not to cross instance boundaries... hmmm... see #2658 (still relevant?)
180 + usage *int32 // accessed atomically
181 + key string
182 + net.PacketConn
183 +}
184 +
185 +func (fcpc *fakeClosePacketConn) Close() error {
186 + log.Println("[DEBUG] Fake-closing underlying packet conn") // TODO: remove this
187 +
188 + if atomic.CompareAndSwapInt32(&fcpc.closed, 0, 1) {
189 + // since we're no longer using this listener,
190 + // decrement the usage counter and, if no one
191 + // else is using it, close underlying listener
192 + if atomic.AddInt32(fcpc.usage, -1) == 0 {
193 + listenersMu.Lock()
194 + delete(listeners, fcpc.key)
195 + listenersMu.Unlock()
196 + err := fcpc.PacketConn.Close()
197 + if err != nil {
198 + return err
199 + }
200 + }
201 + }
202 +
203 + return nil
204 +}
205 +
206 // ErrFakeClosed is the underlying error value returned by
207 // fakeCloseListener.Accept() after Close() has been called,
208 // indicating that it is pretending to be closed so that the
@@ -158,6 +215,7 @@ var errFakeClosed = fmt.Errorf("listener 'closed' 😉")
215 type listenerUsage struct {
216 usage int32 // accessed atomically
217 ln net.Listener
218 + pc net.PacketConn
219 }
220
221 var (
modules/caddyhttp/caddyhttp.go
+47 -1
@@ -31,6 +31,7 @@ import (
31
32 "github.com/caddyserver/caddy/v2"
33 "github.com/caddyserver/caddy/v2/modules/caddytls"
34 + "github.com/lucas-clemente/quic-go/http3"
35 "github.com/mholt/certmagic"
36 )
37
@@ -50,7 +51,9 @@ type App struct {
51 GracePeriod caddy.Duration `json:"grace_period,omitempty"`
52 Servers map[string]*Server `json:"servers,omitempty"`
53
53 - servers []*http.Server
54 + servers []*http.Server
55 + h3servers []*http3.Server
56 + h3listeners []net.PacketConn
57
58 ctx caddy.Context
59 }
@@ -187,6 +190,27 @@ func (app *App) Start() error {
190 return fmt.Errorf("%s/%s: making TLS configuration: %v", network, addr, err)
191 }
192 ln = tls.NewListener(ln, tlsCfg)
193 +
194 + /////////
195 + // TODO: HTTP/3 support is experimental for now
196 + if srv.ExperimentalHTTP3 {
197 + log.Printf("[INFO] Enabling experimental HTTP/3 listener on %s", addr)
198 + h3ln, err := caddy.ListenPacket("udp", addr)
199 + if err != nil {
200 + return fmt.Errorf("getting HTTP/3 UDP listener: %v", err)
201 + }
202 + h3srv := &http3.Server{
203 + Server: &http.Server{
204 + Addr: addr,
205 + Handler: srv,
206 + TLSConfig: tlsCfg,
207 + },
208 + }
209 + go h3srv.Serve(h3ln)
210 + app.h3servers = append(app.h3servers, h3srv)
211 + app.h3listeners = append(app.h3listeners, h3ln)
212 + }
213 + /////////
214 }
215
216 go s.Serve(ln)
@@ -212,6 +236,28 @@ func (app *App) Stop() error {
236 return err
237 }
238 }
239 + // TODO: Closing the http3.Server is the right thing to do,
240 + // however, doing so sometimes causes connections from clients
241 + // to fail after config reloads due to a bug that is yet
242 + // unsolved: https://github.com/caddyserver/caddy/pull/2727
243 + // for _, s := range app.h3servers {
244 + // // TODO: CloseGracefully, once implemented upstream
245 + // // (see https://github.com/lucas-clemente/quic-go/issues/2103)
246 + // err := s.Close()
247 + // if err != nil {
248 + // return err
249 + // }
250 + // }
251 + // as of September 2019, closing the http3.Server
252 + // instances doesn't close their underlying listeners
253 + // so we have todo that ourselves
254 + // (see https://github.com/lucas-clemente/quic-go/issues/2103)
255 + for _, pc := range app.h3listeners {
256 + err := pc.Close()
257 + if err != nil {
258 + return err
259 + }
260 + }
261 return nil
262 }
263
modules/caddyhttp/server.go
+3
@@ -43,6 +43,9 @@ type Server struct {
43 MaxRehandles *int `json:"max_rehandles,omitempty"`
44 StrictSNIHost bool `json:"strict_sni_host,omitempty"`
45
46 + // This field is not subject to compatibility promises
47 + ExperimentalHTTP3 bool `json:"experimental_http3,omitempty"`
48 +
49 tlsApp *caddytls.TLS
50 }
51