diff --git a/go.mod b/go.mod index 71253ba..92f3458 100644 --- a/go.mod +++ b/go.mod @@ -8,13 +8,14 @@ require ( github.com/golang-jwt/jwt v3.2.2+incompatible github.com/isayme/go-bufferpool v0.1.1 github.com/isayme/go-config v0.1.0 - github.com/isayme/go-grpcpool v0.0.0-20220928145230-238f313429cc github.com/isayme/go-logger v0.3.1 github.com/pkg/errors v0.9.1 github.com/posener/h2conn v0.0.0-20180911140238-13e7df33ed15 + github.com/quic-go/quic-go v0.44.0 github.com/spf13/cobra v1.3.0 - golang.org/x/crypto v0.19.0 - golang.org/x/net v0.21.0 + github.com/vmihailenco/msgpack/v5 v5.4.1 + golang.org/x/crypto v0.23.0 + golang.org/x/net v0.25.0 google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.33.0 gopkg.in/DataDog/dd-trace-go.v1 v1.37.0 @@ -29,15 +30,20 @@ require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/rs/zerolog v1.26.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) require ( - github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/onsi/ginkgo/v2 v2.9.5 // indirect + github.com/quic-go/qpack v0.4.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/time v0.5.0 // indirect + go.uber.org/mock v0.4.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/tools v0.21.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect ) diff --git a/go.sum b/go.sum index 4064148..61b50cc 100644 --- a/go.sum +++ b/go.sum @@ -235,6 +235,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= @@ -253,6 +255,8 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= @@ -469,8 +473,6 @@ github.com/isayme/go-bufferpool v0.1.1 h1:teI/oUISJboCmNmfiS/MgOdoBZj92YSRNK95bC github.com/isayme/go-bufferpool v0.1.1/go.mod h1:cV4BzI1av86yS02pt2M3HPaz3P0fbPi3S2rLFSzt0yE= github.com/isayme/go-config v0.1.0 h1:V7Y6jUMohcokytim+2E/ZuFOB8tih7gl6XSmwGDyB78= github.com/isayme/go-config v0.1.0/go.mod h1:cROTfZ5LJpsAb0CQszCNt5PzlPUjJuXRLxqVji4nc4M= -github.com/isayme/go-grpcpool v0.0.0-20220928145230-238f313429cc h1:R73zlMEQ6IAm26t6C30QOhrUM0HoGOFrqZl7HmCTCjg= -github.com/isayme/go-grpcpool v0.0.0-20220928145230-238f313429cc/go.mod h1:K0MUH7NCLbQE4RvnP5MRzqCZ2pqmddqzmAWWCXz+PK8= github.com/isayme/go-logger v0.3.1 h1:fesAF7W9aIOCJwR6PrepjTe3ePPB2+HQEWFyiGj4l4I= github.com/isayme/go-logger v0.3.1/go.mod h1:2AFlHliE6Abc5O25bVOIm0P3SmfkG7IjV5gdOq060bk= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= @@ -661,6 +663,8 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +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/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -668,6 +672,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -719,6 +725,10 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= +github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -823,7 +833,6 @@ github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= @@ -860,6 +869,8 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -898,8 +909,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -912,6 +923,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200901203048-c4f52b2c50aa/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200908183739-ae8ad444f925/go.mod h1:1phAWC201xIgDyaFpmDeZkgf70Q4Pd/CNqfRtVPtxNw= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -939,6 +952,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -996,8 +1011,8 @@ golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1027,6 +1042,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1115,8 +1132,8 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1130,8 +1147,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -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/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1210,6 +1227,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/h3conn/client.go b/h3conn/client.go new file mode 100644 index 0000000..56edbce --- /dev/null +++ b/h3conn/client.go @@ -0,0 +1,84 @@ +package h3conn + +import ( + "context" + "io" + "net/http" + + "github.com/quic-go/quic-go/http3" +) + +// Client provides HTTP3 client side connection with special arguments +type Client struct { + // Method sets the HTTP method for the dial + // The default method, if not set, is HTTP POST. + Method string + // Header enables sending custom headers to the server + Header http.Header + // Client is a custom HTTP client to be used for the connection. + // The client must have an http3.Transport as it's transport. + Client *http.Client +} + +// Connect establishes a full duplex communication with an HTTP3 server with custom client. +// See h2conn.Connect documentation for more info. +func (c *Client) Connect(ctx context.Context, urlStr string) (*Conn, *http.Response, error) { + reader, writer := io.Pipe() + + // Create a request object to send to the server + req, err := http.NewRequest(c.Method, urlStr, reader) + if err != nil { + return nil, nil, err + } + + // Apply custom headers + if c.Header != nil { + req.Header = c.Header + } + + // Apply given context to the sent request + req = req.WithContext(ctx) + + // If an http client was not defined, use the default http client + httpClient := c.Client + if httpClient == nil { + httpClient = defaultClient.Client + } + + // Perform the request + resp, err := httpClient.Do(req) + if err != nil { + return nil, nil, err + } + + // Create a connection + conn, ctx := newConn(req.Context(), resp.Body, writer) + + // Apply the connection context on the request context + resp.Request = req.WithContext(ctx) + + return conn, resp, nil +} + +var defaultClient = Client{ + Method: http.MethodPost, + Client: &http.Client{Transport: &http3.RoundTripper{}}, +} + +// Connect establishes a full duplex communication with an HTTP3 server. +// +// Usage: +// +// conn, resp, err := h2conn.Connect(ctx, url) +// if err != nil { +// log.Fatalf("Initiate client: %s", err) +// } +// if resp.StatusCode != http.StatusOK { +// log.Fatalf("Bad status code: %d", resp.StatusCode) +// } +// defer conn.Close() +// +// // use conn +func Connect(ctx context.Context, urlStr string) (*Conn, *http.Response, error) { + return defaultClient.Connect(ctx, urlStr) +} diff --git a/h3conn/conn.go b/h3conn/conn.go new file mode 100644 index 0000000..329196d --- /dev/null +++ b/h3conn/conn.go @@ -0,0 +1,49 @@ +package h3conn + +import ( + "context" + "io" + "sync" +) + +// Conn is client/server symmetric connection. +// It implements the io.Reader/io.Writer/io.Closer to read/write or close the connection to the other side. +// It also has a Send/Recv function to use channels to communicate with the other side. +type Conn struct { + r io.Reader + wc io.WriteCloser + + cancel context.CancelFunc + + wLock sync.Mutex + rLock sync.Mutex +} + +func newConn(ctx context.Context, r io.Reader, wc io.WriteCloser) (*Conn, context.Context) { + ctx, cancel := context.WithCancel(ctx) + return &Conn{ + r: r, + wc: wc, + cancel: cancel, + }, ctx +} + +// Write writes data to the connection +func (c *Conn) Write(data []byte) (int, error) { + c.wLock.Lock() + defer c.wLock.Unlock() + return c.wc.Write(data) +} + +// Read reads data from the connection +func (c *Conn) Read(data []byte) (int, error) { + c.rLock.Lock() + defer c.rLock.Unlock() + return c.r.Read(data) +} + +// Close closes the connection +func (c *Conn) Close() error { + c.cancel() + return c.wc.Close() +} diff --git a/h3conn/server.go b/h3conn/server.go new file mode 100644 index 0000000..a75e373 --- /dev/null +++ b/h3conn/server.go @@ -0,0 +1,82 @@ +package h3conn + +import ( + "fmt" + "io" + "net/http" +) + +// ErrHTTP3NotSupported is returned by Accept if the client connection does not +// support HTTP3 connection. +// The server than can response to the client with an HTTP1.1 as he wishes. +var ErrHTTP3NotSupported = fmt.Errorf("HTTP3 not supported") + +// Server can "accept" an http3 connection to obtain a read/write object +// for full duplex communication with a client. +type Server struct { + StatusCode int +} + +// Accept is used on a server http.Handler to extract a full-duplex communication object with the client. +// See h2conn.Accept documentation for more info. +func (u *Server) Accept(w http.ResponseWriter, r *http.Request) (*Conn, error) { + if !r.ProtoAtLeast(3, 0) { + return nil, ErrHTTP3NotSupported + } + flusher, ok := w.(http.Flusher) + if !ok { + return nil, ErrHTTP3NotSupported + } + + c, ctx := newConn(r.Context(), r.Body, &flushWrite{w: w, f: flusher}) + + // Update the request context with the connection context. + // If the connection is closed by the server, it will also notify everything that waits on the request context. + *r = *r.WithContext(ctx) + + w.WriteHeader(u.StatusCode) + flusher.Flush() + + return c, nil +} + +var defaultUpgrader = Server{ + StatusCode: http.StatusOK, +} + +// Accept is used on a server http.Handler to extract a full-duplex communication object with the client. +// The server connection will be closed when the http handler function will return. +// If the client does not support HTTP3, an ErrHTTP3NotSupported is returned. +// +// Usage: +// +// func (w http.ResponseWriter, r *http.Request) { +// conn, err := h2conn.Accept(w, r) +// if err != nil { +// log.Printf("Failed creating http3 connection: %s", err) +// http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) +// return +// } +// // use conn +// } +func Accept(w http.ResponseWriter, r *http.Request) (*Conn, error) { + return defaultUpgrader.Accept(w, r) +} + +type flushWrite struct { + w io.Writer + f http.Flusher +} + +func (w *flushWrite) Write(data []byte) (int, error) { + n, err := w.w.Write(data) + w.f.Flush() + return n, err +} + +func (w *flushWrite) Close() error { + // Currently server side close of connection is not supported in Go. + // The server closes the connection when the http.Handler function returns. + // We use connection context and cancel function as a work-around. + return nil +} diff --git a/tunnel/h2/client.go b/tunnel/h2/client.go index def2b56..cc34b57 100644 --- a/tunnel/h2/client.go +++ b/tunnel/h2/client.go @@ -4,6 +4,7 @@ import ( "context" "crypto/tls" "fmt" + "io" "net" "net/http" "net/url" @@ -70,5 +71,22 @@ func (t *Client) Connect(ctx context.Context) (util.ToxConn, error) { return nil, fmt.Errorf("h2: bad status code: %d", resp.StatusCode) } - return util.NewToxConnection(remote), nil + return util.NewToxConnection(newHttp2ClientConnection(remote, resp)), nil +} + +type http2ClientConnection struct { + *h2conn.Conn + resp *http.Response +} + +func newHttp2ClientConnection(conn *h2conn.Conn, resp *http.Response) io.ReadWriteCloser { + return &http2ClientConnection{ + Conn: conn, + resp: resp, + } +} + +func (conn *http2ClientConnection) Close() error { + conn.Conn.Close() + return conn.resp.Body.Close() } diff --git a/tunnel/quic/client.go b/tunnel/quic/client.go new file mode 100644 index 0000000..80ee15d --- /dev/null +++ b/tunnel/quic/client.go @@ -0,0 +1,83 @@ +package quic + +import ( + "context" + "crypto/tls" + "fmt" + "io" + "net/http" + "net/url" + + "github.com/isayme/tox/h3conn" + "github.com/isayme/tox/util" + "github.com/quic-go/quic-go/http3" +) + +type Client struct { + serverAddr string + opts util.ToxOptions + h3Client *h3conn.Client +} + +func NewClient(opts util.ToxOptions) (*Client, error) { + URL, err := url.Parse(opts.Tunnel) + if err != nil { + return nil, err + } + + switch URL.Scheme { + case "quic", "http3": + URL.Scheme = "https" + } + + headers := http.Header{} + password := opts.Password + headers.Add("token", password) + + return &Client{ + serverAddr: URL.String(), + opts: opts, + h3Client: &h3conn.Client{ + Method: http.MethodPost, + Client: &http.Client{ + Transport: &http3.RoundTripper{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: opts.InsecureSkipVerify, + }, + }, + }, + Header: headers, + }, + }, nil +} + +func (t *Client) Connect(ctx context.Context) (util.ToxConn, error) { + remote, resp, err := t.h3Client.Connect(ctx, t.serverAddr) + if err != nil { + return nil, err + } + + if resp.StatusCode != http.StatusOK { + remote.Close() + return nil, fmt.Errorf("h3: bad status code: %d", resp.StatusCode) + } + + return util.NewToxConnection(newHttp2ClientConnection(remote, resp)), nil +} + +type http3ClientConnection struct { + *h3conn.Conn + resp *http.Response +} + +func newHttp2ClientConnection(conn *h3conn.Conn, resp *http.Response) io.ReadWriteCloser { + return &http3ClientConnection{ + Conn: conn, + resp: resp, + } +} + +func (conn *http3ClientConnection) Close() error { + conn.Conn.Close() + return conn.resp.Body.Close() +} diff --git a/tunnel/quic/server.go b/tunnel/quic/server.go new file mode 100644 index 0000000..482c07d --- /dev/null +++ b/tunnel/quic/server.go @@ -0,0 +1,83 @@ +package quic + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/isayme/go-logger" + "github.com/isayme/tox/h3conn" + "github.com/isayme/tox/util" + "github.com/quic-go/quic-go" + "github.com/quic-go/quic-go/http3" +) + +type Server struct { + opts util.ToxOptions +} + +func NewServer(opts util.ToxOptions) (*Server, error) { + return &Server{ + opts: opts, + }, nil +} + +func (s *Server) ListenAndServe(handler func(util.ToxConn)) error { + URL, err := url.Parse(s.opts.Tunnel) + if err != nil { + return err + } + + certFile := s.opts.CertFile + keyFile := s.opts.KeyFile + if certFile == "" || keyFile == "" { + return fmt.Errorf("certFile and keyFile required for http3(quic) protocol") + } + + addr := fmt.Sprintf(":%s", URL.Port()) + server := &http3.Server{ + Addr: addr, + QUICConfig: &quic.Config{ + HandshakeIdleTimeout: s.opts.ConnectTimeout, + MaxIdleTimeout: s.opts.Timeout, + }, + StreamHijacker: nil, + } + + http.HandleFunc(URL.Path, func(rw http.ResponseWriter, req *http.Request) { + if req.Header.Get("token") != s.opts.Password { + http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden) + return + } + + conn, err := h3conn.Accept(rw, req) + if err != nil { + logger.Infof("failed creating connection from %s: %s", req.RemoteAddr, err) + http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + + handler(util.NewToxConnection(conn)) + }) + + return server.ListenAndServeTLS(certFile, keyFile) +} + +func handleConnection(conn quic.Connection, handler func(util.ToxConn)) { + defer conn.CloseWithError(0, "") + + for { + stream, err := conn.AcceptStream(context.Background()) + if err != nil { + logger.Infof("AcceptStream fail, err: %v", err) + break + } + + go handleStream(stream, handler) + } +} + +func handleStream(stream quic.Stream, handler func(util.ToxConn)) { + handler(util.NewToxConnection(stream)) +} diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index 354b5ec..c84d43e 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -8,6 +8,7 @@ import ( "github.com/isayme/go-logger" "github.com/isayme/tox/tunnel/grpc" "github.com/isayme/tox/tunnel/h2" + "github.com/isayme/tox/tunnel/quic" "github.com/isayme/tox/tunnel/websocket" "github.com/isayme/tox/util" ) @@ -35,6 +36,8 @@ func NewClient(opts util.ToxOptions) (Client, error) { return h2.NewClient(opts) case "ws", "wss": return websocket.NewClient(opts) + case "quic", "http3": + return quic.NewClient(opts) } return nil, fmt.Errorf("not supported schema: %s", URL.Scheme) @@ -53,6 +56,8 @@ func NewServer(opts util.ToxOptions) (Server, error) { return h2.NewServer(opts) case "ws", "wss": return websocket.NewServer(opts) + case "quic", "http3": + return quic.NewServer(opts) } return nil, fmt.Errorf("not supported schema: %s", URL.Scheme) } diff --git a/util/conn.go b/util/conn.go index 8ec896e..57290c2 100644 --- a/util/conn.go +++ b/util/conn.go @@ -154,7 +154,7 @@ func (conn *ToxConnection) Write(p []byte) (int, error) { func (conn *ToxConnection) CloseWrite() error { conn.closeWrite = true - err := conn.writeFrame(COMMAND_DATA, nil) + err := conn.writeFrame(COMMAND_CLOSE_WRITE, nil) if err != nil { return err }