From 43359d7be41bed7c24c20767c8def61fce26d92c Mon Sep 17 00:00:00 2001 From: roc Date: Fri, 5 Jan 2024 11:56:44 +0800 Subject: [PATCH] update go modules, support quic-go v0.40.1 --- go.mod | 31 +++++++------ go.sum | 32 +++++++++++++ internal/http3/body.go | 4 +- internal/http3/client.go | 43 +++++++++--------- internal/http3/error.go | 58 +++++++++++++++++++++++ internal/http3/error_codes.go | 86 +++++++++++++++++++---------------- internal/http3/server.go | 8 ++-- 7 files changed, 181 insertions(+), 81 deletions(-) create mode 100644 internal/http3/error.go diff --git a/go.mod b/go.mod index 69f81ba5..6f0b6ce4 100644 --- a/go.mod +++ b/go.mod @@ -5,26 +5,27 @@ go 1.20 require ( github.com/hashicorp/go-multierror v1.1.1 github.com/quic-go/qpack v0.4.0 - github.com/quic-go/quic-go v0.38.1 - github.com/refraction-networking/utls v1.5.3 - golang.org/x/net v0.14.0 - golang.org/x/text v0.13.0 + github.com/quic-go/quic-go v0.40.1 + github.com/refraction-networking/utls v1.6.0 + golang.org/x/net v0.19.0 + golang.org/x/text v0.14.0 ) require ( - github.com/andybalholm/brotli v1.0.5 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/andybalholm/brotli v1.0.6 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/gaukas/godicttls v0.0.4 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/golang/mock v1.6.0 // indirect - github.com/google/pprof v0.0.0-20230901174712-0191c66da455 // indirect + github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/onsi/ginkgo/v2 v2.12.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + github.com/klauspost/compress v1.17.4 // indirect + github.com/onsi/ginkgo/v2 v2.13.2 // indirect + github.com/quic-go/qtls-go1-20 v0.4.1 // indirect + go.uber.org/mock v0.4.0 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/tools v0.16.1 // indirect ) diff --git a/go.sum b/go.sum index cf811594..b71b469e 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,12 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= +github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -30,6 +34,8 @@ github.com/google/pprof v0.0.0-20230811205829-9131a7e9cc17 h1:0h35ESZ02+hN/MFZb7 github.com/google/pprof v0.0.0-20230811205829-9131a7e9cc17/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/pprof v0.0.0-20230901174712-0191c66da455 h1:YhRUmI1ttDC4sxKY2V62BTI8hCXnyZBV9h38eAanInE= github.com/google/pprof v0.0.0-20230901174712-0191c66da455/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -39,6 +45,8 @@ github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7y github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/ginkgo/v2 v2.10.0 h1:sfUl4qgLdvkChZrWCYndY2EAu9BRIw1YphNAzy1VNWs= @@ -47,6 +55,8 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= +github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= +github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -62,6 +72,8 @@ github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQ github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= +github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/quic-go v0.35.0 h1:JXIf219xJK+4qGeY52rlnrVqeB2AXUAwfLU9JSoWXwg= github.com/quic-go/quic-go v0.35.0/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g= github.com/quic-go/quic-go v0.35.1 h1:b0kzj6b/cQAf05cT0CkQubHM31wiA+xH3IBkxP62poo= @@ -72,6 +84,8 @@ github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= +github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= +github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8= github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= @@ -84,10 +98,14 @@ github.com/refraction-networking/utls v1.4.3 h1:BdWS3BSzCwWCFfMIXP3mjLAyQkdmog7d github.com/refraction-networking/utls v1.4.3/go.mod h1:4u9V/awOSBrRw6+federGmVJQfPtemEqLBXkML1b0bo= github.com/refraction-networking/utls v1.5.3 h1:Ds5Ocg1+MC1ahNx5iBEcHe0jHeLaA/fLey61EENm7ro= github.com/refraction-networking/utls v1.5.3/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw= +github.com/refraction-networking/utls v1.6.0 h1:X5vQMqVx7dY7ehxxqkFER/W6DSjy8TMqSItXm8hRDYQ= +github.com/refraction-networking/utls v1.6.0/go.mod h1:kHJ6R9DFFA0WsRgBM35iiDku4O7AqPR6y79iuzW7b10= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= @@ -98,6 +116,8 @@ golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY= @@ -110,6 +130,8 @@ golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb h1:mIKbk8weKhSeLH2GmUTrvx8Cj golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -117,6 +139,8 @@ golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= @@ -128,6 +152,8 @@ golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -145,6 +171,8 @@ golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -158,6 +186,8 @@ golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -171,6 +201,8 @@ golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/http3/body.go b/internal/http3/body.go index 15985a1c..63ff4366 100644 --- a/internal/http3/body.go +++ b/internal/http3/body.go @@ -67,7 +67,7 @@ func (r *body) Read(b []byte) (int, error) { } func (r *body) Close() error { - r.str.CancelRead(quic.StreamErrorCode(errorRequestCanceled)) + r.str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)) return nil } @@ -126,7 +126,7 @@ func (r *body) StreamID() quic.StreamID { func (r *hijackableBody) Close() error { r.requestDone() // If the EOF was read, CancelRead() is a no-op. - r.str.CancelRead(quic.StreamErrorCode(errorRequestCanceled)) + r.str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)) return nil } diff --git a/internal/http3/client.go b/internal/http3/client.go index 4ba9e9bb..673c85df 100644 --- a/internal/http3/client.go +++ b/internal/http3/client.go @@ -140,7 +140,7 @@ func (c *client) dial(ctx context.Context) error { go func() { if err := c.setupConn(conn); err != nil { c.opt.Debugf("setting up http3 connection failed: %s", err) - conn.CloseWithError(quic.ApplicationErrorCode(errorInternalError), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeInternalError), "") } }() @@ -182,7 +182,7 @@ func (c *client) handleBidirectionalStreams(conn quic.EarlyConnection) { if err != nil { c.opt.Debugf("error handling stream: %s", err) } - conn.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "received HTTP/3 frame on bidirectional stream") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "received HTTP/3 frame on bidirectional stream") }(str) } } @@ -213,23 +213,23 @@ func (c *client) handleUnidirectionalStreams(conn quic.EarlyConnection) { return case streamTypePushStream: // We never increased the Push ID, so we don't expect any push streams. - conn.CloseWithError(quic.ApplicationErrorCode(errorIDError), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeIDError), "") return default: if c.opts.UniStreamHijacker != nil && c.opts.UniStreamHijacker(StreamType(streamType), conn, str, nil) { return } - str.CancelRead(quic.StreamErrorCode(errorStreamCreationError)) + str.CancelRead(quic.StreamErrorCode(ErrCodeStreamCreationError)) return } f, err := parseNextFrame(str, nil) if err != nil { - conn.CloseWithError(quic.ApplicationErrorCode(errorFrameError), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameError), "") return } sf, ok := f.(*settingsFrame) if !ok { - conn.CloseWithError(quic.ApplicationErrorCode(errorMissingSettings), "") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeMissingSettings), "") return } if !sf.Datagram { @@ -239,7 +239,7 @@ func (c *client) handleUnidirectionalStreams(conn quic.EarlyConnection) { // we can expect it to have been negotiated both on the transport and on the HTTP/3 layer. // Note: ConnectionState() will block until the handshake is complete (relevant when using 0-RTT). if c.opts.EnableDatagram && !conn.ConnectionState().SupportsDatagrams { - conn.CloseWithError(quic.ApplicationErrorCode(errorSettingsError), "missing QUIC Datagram support") + conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeSettingsError), "missing QUIC Datagram support") } }(str) } @@ -250,7 +250,7 @@ func (c *client) Close() error { if conn == nil { return nil } - return (*conn).CloseWithError(quic.ApplicationErrorCode(errorNoError), "") + return (*conn).CloseWithError(quic.ApplicationErrorCode(ErrCodeNoError), "") } func (c *client) maxHeaderBytes() uint64 { @@ -302,8 +302,8 @@ func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Respon defer close(done) select { case <-req.Context().Done(): - str.CancelWrite(quic.StreamErrorCode(errorRequestCanceled)) - str.CancelRead(quic.StreamErrorCode(errorRequestCanceled)) + str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)) + str.CancelRead(quic.StreamErrorCode(ErrCodeRequestCanceled)) case <-reqDone: } }() @@ -326,13 +326,14 @@ func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Respon } conn.CloseWithError(quic.ApplicationErrorCode(rerr.connErr), reason) } - return nil, rerr.err + return nil, maybeReplaceError(rerr.err) + } if opt.DontCloseRequestStream { close(reqDone) <-done } - return rsp, rerr.err + return rsp, maybeReplaceError(rerr.err) } func (c *client) sendRequestBody(str Stream, body io.ReadCloser, dumps []*dump.Dumper) error { @@ -378,7 +379,7 @@ func (c *client) sendRequestBody(str Stream, body io.ReadCloser, dumps []*dump.D } break } - str.CancelWrite(quic.StreamErrorCode(errorRequestCanceled)) + str.CancelWrite(quic.StreamErrorCode(ErrCodeRequestCanceled)) return rerr } } @@ -398,14 +399,14 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui } } if err := c.requestWriter.WriteRequestHeader(str, req, requestGzip, headerDumps); err != nil { - return nil, newStreamError(errorInternalError, err) + return nil, newStreamError(ErrCodeInternalError, err) } if req.Body == nil && !opt.DontCloseRequestStream { str.Close() } - hstr := newStream(str, func() { conn.CloseWithError(quic.ApplicationErrorCode(errorFrameUnexpected), "") }) + hstr := newStream(str, func() { conn.CloseWithError(quic.ApplicationErrorCode(ErrCodeFrameUnexpected), "") }) if req.Body != nil { // send the request body asynchronously go func() { @@ -426,18 +427,18 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui frame, err := parseNextFrame(str, nil) if err != nil { - return nil, newStreamError(errorFrameError, err) + return nil, newStreamError(ErrCodeFrameError, err) } hf, ok := frame.(*headersFrame) if !ok { - return nil, newConnError(errorFrameUnexpected, errors.New("expected first frame to be a HEADERS frame")) + return nil, newConnError(ErrCodeFrameUnexpected, errors.New("expected first frame to be a HEADERS frame")) } if hf.Length > c.maxHeaderBytes() { - return nil, newStreamError(errorFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, c.maxHeaderBytes())) + return nil, newStreamError(ErrCodeFrameError, fmt.Errorf("HEADERS frame too large: %d bytes (max: %d)", hf.Length, c.maxHeaderBytes())) } headerBlock := make([]byte, hf.Length) if _, err := io.ReadFull(str, headerBlock); err != nil { - return nil, newStreamError(errorRequestIncomplete, err) + return nil, newStreamError(ErrCodeRequestIncomplete, err) } var respHeaderDumps []*dump.Dumper for _, dump := range dumps { @@ -458,12 +459,12 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui } if err != nil { // TODO: use the right error code - return nil, newConnError(errorGeneralProtocolError, err) + return nil, newConnError(ErrCodeGeneralProtocolError, err) } res, err := responseFromHeaders(hfs) if err != nil { - return nil, newStreamError(errorMessageError, err) + return nil, newStreamError(ErrCodeMessageError, err) } res.Request = req connState := conn.ConnectionState().TLS diff --git a/internal/http3/error.go b/internal/http3/error.go new file mode 100644 index 00000000..b96ebeec --- /dev/null +++ b/internal/http3/error.go @@ -0,0 +1,58 @@ +package http3 + +import ( + "errors" + "fmt" + + "github.com/quic-go/quic-go" +) + +// Error is returned from the round tripper (for HTTP clients) +// and inside the HTTP handler (for HTTP servers) if an HTTP/3 error occurs. +// See section 8 of RFC 9114. +type Error struct { + Remote bool + ErrorCode ErrCode + ErrorMessage string +} + +var _ error = &Error{} + +func (e *Error) Error() string { + s := e.ErrorCode.string() + if s == "" { + s = fmt.Sprintf("H3 error (%#x)", uint64(e.ErrorCode)) + } + // Usually errors are remote. Only make it explicit for local errors. + if !e.Remote { + s += " (local)" + } + if e.ErrorMessage != "" { + s += ": " + e.ErrorMessage + } + return s +} + +func maybeReplaceError(err error) error { + if err == nil { + return nil + } + + var ( + e Error + strErr *quic.StreamError + appErr *quic.ApplicationError + ) + switch { + default: + return err + case errors.As(err, &strErr): + e.Remote = strErr.Remote + e.ErrorCode = ErrCode(strErr.ErrorCode) + case errors.As(err, &appErr): + e.Remote = appErr.Remote + e.ErrorCode = ErrCode(appErr.ErrorCode) + e.ErrorMessage = appErr.ErrorMessage + } + return &e +} diff --git a/internal/http3/error_codes.go b/internal/http3/error_codes.go index 148447ea..ae646586 100644 --- a/internal/http3/error_codes.go +++ b/internal/http3/error_codes.go @@ -6,68 +6,76 @@ import ( "github.com/quic-go/quic-go" ) -type errorCode quic.ApplicationErrorCode +type ErrCode quic.ApplicationErrorCode const ( - errorNoError errorCode = 0x100 - errorGeneralProtocolError errorCode = 0x101 - errorInternalError errorCode = 0x102 - errorStreamCreationError errorCode = 0x103 - errorClosedCriticalStream errorCode = 0x104 - errorFrameUnexpected errorCode = 0x105 - errorFrameError errorCode = 0x106 - errorExcessiveLoad errorCode = 0x107 - errorIDError errorCode = 0x108 - errorSettingsError errorCode = 0x109 - errorMissingSettings errorCode = 0x10a - errorRequestRejected errorCode = 0x10b - errorRequestCanceled errorCode = 0x10c - errorRequestIncomplete errorCode = 0x10d - errorMessageError errorCode = 0x10e - errorConnectError errorCode = 0x10f - errorVersionFallback errorCode = 0x110 - errorDatagramError errorCode = 0x33 + ErrCodeNoError ErrCode = 0x100 + ErrCodeGeneralProtocolError ErrCode = 0x101 + ErrCodeInternalError ErrCode = 0x102 + ErrCodeStreamCreationError ErrCode = 0x103 + ErrCodeClosedCriticalStream ErrCode = 0x104 + ErrCodeFrameUnexpected ErrCode = 0x105 + ErrCodeFrameError ErrCode = 0x106 + ErrCodeExcessiveLoad ErrCode = 0x107 + ErrCodeIDError ErrCode = 0x108 + ErrCodeSettingsError ErrCode = 0x109 + ErrCodeMissingSettings ErrCode = 0x10a + ErrCodeRequestRejected ErrCode = 0x10b + ErrCodeRequestCanceled ErrCode = 0x10c + ErrCodeRequestIncomplete ErrCode = 0x10d + ErrCodeMessageError ErrCode = 0x10e + ErrCodeConnectError ErrCode = 0x10f + ErrCodeVersionFallback ErrCode = 0x110 + ErrCodeDatagramError ErrCode = 0x33 ) -func (e errorCode) String() string { +func (e ErrCode) String() string { + s := e.string() + if s != "" { + return s + } + return fmt.Sprintf("unknown error code: %#x", uint16(e)) +} + +func (e ErrCode) string() string { switch e { - case errorNoError: + case ErrCodeNoError: return "H3_NO_ERROR" - case errorGeneralProtocolError: + case ErrCodeGeneralProtocolError: return "H3_GENERAL_PROTOCOL_ERROR" - case errorInternalError: + case ErrCodeInternalError: return "H3_INTERNAL_ERROR" - case errorStreamCreationError: + case ErrCodeStreamCreationError: return "H3_STREAM_CREATION_ERROR" - case errorClosedCriticalStream: + case ErrCodeClosedCriticalStream: return "H3_CLOSED_CRITICAL_STREAM" - case errorFrameUnexpected: + case ErrCodeFrameUnexpected: return "H3_FRAME_UNEXPECTED" - case errorFrameError: + case ErrCodeFrameError: return "H3_FRAME_ERROR" - case errorExcessiveLoad: + case ErrCodeExcessiveLoad: return "H3_EXCESSIVE_LOAD" - case errorIDError: + case ErrCodeIDError: return "H3_ID_ERROR" - case errorSettingsError: + case ErrCodeSettingsError: return "H3_SETTINGS_ERROR" - case errorMissingSettings: + case ErrCodeMissingSettings: return "H3_MISSING_SETTINGS" - case errorRequestRejected: + case ErrCodeRequestRejected: return "H3_REQUEST_REJECTED" - case errorRequestCanceled: + case ErrCodeRequestCanceled: return "H3_REQUEST_CANCELLED" - case errorRequestIncomplete: + case ErrCodeRequestIncomplete: return "H3_INCOMPLETE_REQUEST" - case errorMessageError: + case ErrCodeMessageError: return "H3_MESSAGE_ERROR" - case errorConnectError: + case ErrCodeConnectError: return "H3_CONNECT_ERROR" - case errorVersionFallback: + case ErrCodeVersionFallback: return "H3_VERSION_FALLBACK" - case errorDatagramError: + case ErrCodeDatagramError: return "H3_DATAGRAM_ERROR" default: - return fmt.Sprintf("unknown error code: %#x", uint16(e)) + return "" } } diff --git a/internal/http3/server.go b/internal/http3/server.go index 7449c3c7..2b9d8658 100644 --- a/internal/http3/server.go +++ b/internal/http3/server.go @@ -31,14 +31,14 @@ func versionToALPN(v quic.VersionNumber) string { type requestError struct { err error - streamErr errorCode - connErr errorCode + streamErr ErrCode + connErr ErrCode } -func newStreamError(code errorCode, err error) requestError { +func newStreamError(code ErrCode, err error) requestError { return requestError{err: err, streamErr: code} } -func newConnError(code errorCode, err error) requestError { +func newConnError(code ErrCode, err error) requestError { return requestError{err: err, connErr: code} }