mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 20:52:33 +02:00
Feat/http3 (#84)
* chore(deps): update go-playground/validator to v10.26.0 * chore(deps): update Go version to 1.24.2 and dependencies, reorganize dependencies into categorized sections * chore(deps): update Go version to 1.24.2 in Dockerfile * refactor(agent): replace deprecated context import with standard context package * feat(http3): add HTTP/3 support and refactor server handling code into utility functions --------- Co-authored-by: yusing <yusing@6uo.me>
This commit is contained in:
parent
51813e6030
commit
8e37627371
6 changed files with 212 additions and 63 deletions
|
@ -1,5 +1,5 @@
|
||||||
# Stage 1: deps
|
# Stage 1: deps
|
||||||
FROM golang:1.24.1-alpine AS deps
|
FROM golang:1.24.2-alpine AS deps
|
||||||
HEALTHCHECK NONE
|
HEALTHCHECK NONE
|
||||||
|
|
||||||
# package version does not matter
|
# package version does not matter
|
||||||
|
|
72
go.mod
72
go.mod
|
@ -1,36 +1,66 @@
|
||||||
module github.com/yusing/go-proxy
|
module github.com/yusing/go-proxy
|
||||||
|
|
||||||
go 1.24.1
|
go 1.24.2
|
||||||
|
|
||||||
|
// misc
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/PuerkitoBio/goquery v1.10.2 // parsing HTML for extract fav icon
|
|
||||||
github.com/coder/websocket v1.8.13 // websocket for API and agent
|
|
||||||
github.com/coreos/go-oidc/v3 v3.13.0 // oidc authentication
|
|
||||||
github.com/docker/docker v28.0.4+incompatible // docker daemon
|
|
||||||
github.com/fsnotify/fsnotify v1.8.0 // file watcher
|
github.com/fsnotify/fsnotify v1.8.0 // file watcher
|
||||||
github.com/go-acme/lego/v4 v4.22.2 // acme client
|
github.com/go-acme/lego/v4 v4.22.2 // acme client
|
||||||
github.com/go-playground/validator/v10 v10.25.0 // validator
|
github.com/go-playground/validator/v10 v10.26.0 // validator
|
||||||
github.com/gobwas/glob v0.2.3 // glob matcher for route rules
|
github.com/gobwas/glob v0.2.3 // glob matcher for route rules
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2 // jwt for default auth
|
|
||||||
github.com/gotify/server/v2 v2.6.1 // reference the Message struct for json response
|
github.com/gotify/server/v2 v2.6.1 // reference the Message struct for json response
|
||||||
github.com/lithammer/fuzzysearch v1.1.8 // fuzzy search for searching icons and filtering metrics
|
github.com/lithammer/fuzzysearch v1.1.8 // fuzzy search for searching icons and filtering metrics
|
||||||
github.com/prometheus/client_golang v1.21.1 // metrics
|
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 // lock free map for concurrent operations
|
github.com/puzpuzpuz/xsync/v3 v3.5.1 // lock free map for concurrent operations
|
||||||
github.com/rs/zerolog v1.34.0 // logging
|
|
||||||
github.com/shirou/gopsutil/v4 v4.25.2 // system info metrics
|
|
||||||
github.com/vincent-petithory/dataurl v1.0.0 // data url for fav icon
|
|
||||||
golang.org/x/crypto v0.36.0 // encrypting password with bcrypt
|
|
||||||
golang.org/x/net v0.38.0 // HTTP header utilities
|
|
||||||
golang.org/x/oauth2 v0.28.0 // oauth2 authentication
|
|
||||||
golang.org/x/text v0.23.0 // string utilities
|
golang.org/x/text v0.23.0 // string utilities
|
||||||
golang.org/x/time v0.11.0 // time utilities
|
golang.org/x/time v0.11.0 // time utilities
|
||||||
gopkg.in/yaml.v3 v3.0.1 // yaml parsing for different config files
|
gopkg.in/yaml.v3 v3.0.1 // yaml parsing for different config files
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// http
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/docker/cli v28.0.4+incompatible
|
github.com/coder/websocket v1.8.13 // websocket for API and agent
|
||||||
github.com/docker/go-connections v0.5.0
|
github.com/quic-go/quic-go v0.50.1 // http3 server
|
||||||
github.com/stretchr/testify v1.10.0
|
golang.org/x/net v0.38.0 // HTTP header utilities
|
||||||
|
)
|
||||||
|
|
||||||
|
// authentication
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/coreos/go-oidc/v3 v3.13.0 // oidc authentication
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.2.2 // jwt for default auth
|
||||||
|
golang.org/x/crypto v0.36.0 // encrypting password with bcrypt
|
||||||
|
golang.org/x/oauth2 v0.28.0 // oauth2 authentication
|
||||||
|
)
|
||||||
|
|
||||||
|
// favicon extraction
|
||||||
|
require (
|
||||||
|
github.com/PuerkitoBio/goquery v1.10.2 // parsing HTML for extract fav icon
|
||||||
|
github.com/vincent-petithory/dataurl v1.0.0 // data url for fav icon
|
||||||
|
)
|
||||||
|
|
||||||
|
// docker
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/docker/cli v28.0.4+incompatible // docker cli
|
||||||
|
github.com/docker/docker v28.0.4+incompatible // docker daemon
|
||||||
|
github.com/docker/go-connections v0.5.0 // docker connection utilities
|
||||||
|
)
|
||||||
|
|
||||||
|
// logging
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/rs/zerolog v1.34.0 // logging
|
||||||
|
github.com/samber/slog-zerolog/v2 v2.7.3 // zerlog to slog adapter for quic-go
|
||||||
|
)
|
||||||
|
|
||||||
|
// metrics
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/prometheus/client_golang v1.21.1 // metrics
|
||||||
|
github.com/shirou/gopsutil/v4 v4.25.3 // system info metrics
|
||||||
|
github.com/stretchr/testify v1.10.0 // testing utilities
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
@ -53,9 +83,11 @@ require (
|
||||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.5 // indirect
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect
|
||||||
github.com/klauspost/compress v1.18.0 // indirect
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
|
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
|
||||||
|
@ -67,6 +99,7 @@ require (
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/nrdcg/porkbun v0.4.0 // indirect
|
github.com/nrdcg/porkbun v0.4.0 // indirect
|
||||||
|
github.com/onsi/ginkgo/v2 v2.23.3 // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||||
github.com/ovh/go-ovh v1.7.0 // indirect
|
github.com/ovh/go-ovh v1.7.0 // indirect
|
||||||
|
@ -76,6 +109,9 @@ require (
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.63.0 // indirect
|
github.com/prometheus/common v0.63.0 // indirect
|
||||||
github.com/prometheus/procfs v0.16.0 // indirect
|
github.com/prometheus/procfs v0.16.0 // indirect
|
||||||
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
|
github.com/samber/lo v1.49.1 // indirect
|
||||||
|
github.com/samber/slog-common v0.18.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
||||||
github.com/tklauser/numcpus v0.10.0 // indirect
|
github.com/tklauser/numcpus v0.10.0 // indirect
|
||||||
|
@ -86,6 +122,8 @@ require (
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||||
|
go.uber.org/mock v0.5.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||||
golang.org/x/mod v0.24.0 // indirect
|
golang.org/x/mod v0.24.0 // indirect
|
||||||
golang.org/x/sync v0.12.0 // indirect
|
golang.org/x/sync v0.12.0 // indirect
|
||||||
golang.org/x/sys v0.31.0 // indirect
|
golang.org/x/sys v0.31.0 // indirect
|
||||||
|
|
30
go.sum
30
go.sum
|
@ -61,8 +61,10 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8=
|
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
|
||||||
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
|
@ -78,6 +80,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||||
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gotify/server/v2 v2.6.1 h1:Kf7v5fzBxzELzZa/jonWfwJMkqYqh1LBzBpCmt5QIAI=
|
github.com/gotify/server/v2 v2.6.1 h1:Kf7v5fzBxzELzZa/jonWfwJMkqYqh1LBzBpCmt5QIAI=
|
||||||
|
@ -123,6 +127,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/nrdcg/porkbun v0.4.0 h1:rWweKlwo1PToQ3H+tEO9gPRW0wzzgmI/Ob3n2Guticw=
|
github.com/nrdcg/porkbun v0.4.0 h1:rWweKlwo1PToQ3H+tEO9gPRW0wzzgmI/Ob3n2Guticw=
|
||||||
github.com/nrdcg/porkbun v0.4.0/go.mod h1:/QMskrHEIM0IhC/wY7iTCUgINsxdT2WcOphktJ9+Q54=
|
github.com/nrdcg/porkbun v0.4.0/go.mod h1:/QMskrHEIM0IhC/wY7iTCUgINsxdT2WcOphktJ9+Q54=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
|
||||||
|
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||||
|
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||||
|
@ -146,13 +154,23 @@ github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2b
|
||||||
github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg=
|
github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg=
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
|
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
||||||
|
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||||
|
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||||
|
github.com/quic-go/quic-go v0.50.1 h1:unsgjFIUqW8a2oopkY7YNONpV1gYND6Nt9hnt1PN94Q=
|
||||||
|
github.com/quic-go/quic-go v0.50.1/go.mod h1:Vim6OmUvlYdwBhXP9ZVrtGmCMWa3wEqhq3NgYrI8b4E=
|
||||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||||
github.com/shirou/gopsutil/v4 v4.25.2 h1:NMscG3l2CqtWFS86kj3vP7soOczqrQYIEhO/pMvvQkk=
|
github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
|
||||||
github.com/shirou/gopsutil/v4 v4.25.2/go.mod h1:34gBYJzyqCDT11b6bMHP0XCvWeU3J61XRT7a2EmCRTA=
|
github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
|
||||||
|
github.com/samber/slog-common v0.18.1 h1:c0EipD/nVY9HG5shgm/XAs67mgpWDMF+MmtptdJNCkQ=
|
||||||
|
github.com/samber/slog-common v0.18.1/go.mod h1:QNZiNGKakvrfbJ2YglQXLCZauzkI9xZBjOhWFKS3IKk=
|
||||||
|
github.com/samber/slog-zerolog/v2 v2.7.3 h1:/MkPDl/tJhijN2GvB1MWwBn2FU8RiL3rQ8gpXkQm2EY=
|
||||||
|
github.com/samber/slog-zerolog/v2 v2.7.3/go.mod h1:oWU7WHof4Xp8VguiNO02r1a4VzkgoOyOZhY5CuRke60=
|
||||||
|
github.com/shirou/gopsutil/v4 v4.25.3 h1:SeA68lsu8gLggyMbmCn8cmp97V1TI9ld9sVzAUcKcKE=
|
||||||
|
github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
@ -190,6 +208,8 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt
|
||||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||||
|
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||||
|
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
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.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
@ -200,6 +220,8 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||||
|
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||||
|
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
|
|
@ -19,6 +19,8 @@ var (
|
||||||
IsDebug = GetEnvBool("DEBUG", IsTest)
|
IsDebug = GetEnvBool("DEBUG", IsTest)
|
||||||
IsTrace = GetEnvBool("TRACE", false) && IsDebug
|
IsTrace = GetEnvBool("TRACE", false) && IsDebug
|
||||||
|
|
||||||
|
HTTP3Enabled = GetEnvBool("HTTP3_ENABLED", true)
|
||||||
|
|
||||||
ProxyHTTPAddr,
|
ProxyHTTPAddr,
|
||||||
ProxyHTTPHost,
|
ProxyHTTPHost,
|
||||||
ProxyHTTPPort,
|
ProxyHTTPPort,
|
||||||
|
|
|
@ -3,11 +3,11 @@ package server
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/quic-go/quic-go/http3"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/yusing/go-proxy/internal/autocert"
|
"github.com/yusing/go-proxy/internal/autocert"
|
||||||
"github.com/yusing/go-proxy/internal/common"
|
"github.com/yusing/go-proxy/internal/common"
|
||||||
|
@ -33,6 +33,11 @@ type Options struct {
|
||||||
Handler http.Handler
|
Handler http.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type httpServer interface {
|
||||||
|
*http.Server | *http3.Server
|
||||||
|
Shutdown(ctx context.Context) error
|
||||||
|
}
|
||||||
|
|
||||||
func StartServer(parent task.Parent, opt Options) (s *Server) {
|
func StartServer(parent task.Parent, opt Options) (s *Server) {
|
||||||
s = NewServer(opt)
|
s = NewServer(opt)
|
||||||
s.Start(parent)
|
s.Start(parent)
|
||||||
|
@ -82,67 +87,74 @@ func NewServer(opt Options) (s *Server) {
|
||||||
func (s *Server) Start(parent task.Parent) {
|
func (s *Server) Start(parent task.Parent) {
|
||||||
s.startTime = time.Now()
|
s.startTime = time.Now()
|
||||||
subtask := parent.Subtask("server."+s.Name, false)
|
subtask := parent.Subtask("server."+s.Name, false)
|
||||||
|
|
||||||
|
if s.https != nil && common.HTTP3Enabled {
|
||||||
|
s.https.TLSConfig.NextProtos = []string{http3.NextProtoH3, "h2", "http/1.1"}
|
||||||
|
h3 := &http3.Server{
|
||||||
|
Addr: s.https.Addr,
|
||||||
|
Handler: s.https.Handler,
|
||||||
|
TLSConfig: http3.ConfigureTLSConfig(s.https.TLSConfig),
|
||||||
|
}
|
||||||
|
Start(subtask, h3, &s.l)
|
||||||
|
s.http.Handler = advertiseHTTP3(s.http.Handler, h3)
|
||||||
|
s.https.Handler = advertiseHTTP3(s.https.Handler, h3)
|
||||||
|
}
|
||||||
|
|
||||||
Start(subtask, s.http, &s.l)
|
Start(subtask, s.http, &s.l)
|
||||||
Start(subtask, s.https, &s.l)
|
Start(subtask, s.https, &s.l)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(parent task.Parent, srv *http.Server, logger *zerolog.Logger) {
|
func Start[Server httpServer](parent task.Parent, srv Server, logger *zerolog.Logger) {
|
||||||
if srv == nil {
|
if srv == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
srv.BaseContext = func(l net.Listener) context.Context {
|
|
||||||
return parent.Context()
|
|
||||||
}
|
|
||||||
|
|
||||||
if common.IsDebug {
|
setDebugLogger(srv, logger)
|
||||||
srv.ErrorLog = log.New(logger, "", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
var proto string
|
|
||||||
if srv.TLSConfig == nil {
|
|
||||||
proto = "http"
|
|
||||||
} else {
|
|
||||||
proto = "https"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
proto := proto(srv)
|
||||||
task := parent.Subtask(proto, false)
|
task := parent.Subtask(proto, false)
|
||||||
|
|
||||||
var lc net.ListenConfig
|
var lc net.ListenConfig
|
||||||
|
var serveFunc func() error
|
||||||
|
|
||||||
// Serve already closes the listener on return
|
switch srv := any(srv).(type) {
|
||||||
|
case *http.Server:
|
||||||
|
srv.BaseContext = func(l net.Listener) context.Context {
|
||||||
|
return parent.Context()
|
||||||
|
}
|
||||||
l, err := lc.Listen(task.Context(), "tcp", srv.Addr)
|
l, err := lc.Listen(task.Context(), "tcp", srv.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(logger, err, "failed to listen on port")
|
HandleError(logger, err, "failed to listen on port")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if srv.TLSConfig != nil {
|
||||||
task.OnCancel("stop", func() {
|
l = tls.NewListener(l, srv.TLSConfig)
|
||||||
Stop(srv, logger)
|
|
||||||
})
|
|
||||||
|
|
||||||
logger.Info().Str("addr", srv.Addr).Msg("server started")
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
if srv.TLSConfig == nil {
|
|
||||||
err = srv.Serve(l)
|
|
||||||
} else {
|
|
||||||
err = srv.Serve(tls.NewListener(l, srv.TLSConfig))
|
|
||||||
}
|
}
|
||||||
|
serveFunc = getServeFunc(l, srv.Serve)
|
||||||
|
case *http3.Server:
|
||||||
|
l, err := lc.ListenPacket(task.Context(), "udp", srv.Addr)
|
||||||
|
if err != nil {
|
||||||
|
HandleError(logger, err, "failed to listen on port")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
serveFunc = getServeFunc(l, srv.Serve)
|
||||||
|
}
|
||||||
|
task.OnCancel("stop", func() {
|
||||||
|
stop(srv, logger)
|
||||||
|
})
|
||||||
|
logStarted(srv, logger)
|
||||||
|
go func() {
|
||||||
|
err := serveFunc()
|
||||||
HandleError(logger, err, "failed to serve "+proto+" server")
|
HandleError(logger, err, "failed to serve "+proto+" server")
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Stop(srv *http.Server, logger *zerolog.Logger) {
|
func stop[Server httpServer](srv Server, logger *zerolog.Logger) {
|
||||||
if srv == nil {
|
if srv == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var proto string
|
proto := proto(srv)
|
||||||
if srv.TLSConfig == nil {
|
|
||||||
proto = "http"
|
|
||||||
} else {
|
|
||||||
proto = "https"
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(task.RootContext(), 3*time.Second)
|
ctx, cancel := context.WithTimeout(task.RootContext(), 3*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -150,7 +162,7 @@ func Stop(srv *http.Server, logger *zerolog.Logger) {
|
||||||
if err := srv.Shutdown(ctx); err != nil {
|
if err := srv.Shutdown(ctx); err != nil {
|
||||||
HandleError(logger, err, "failed to shutdown "+proto+" server")
|
HandleError(logger, err, "failed to shutdown "+proto+" server")
|
||||||
} else {
|
} else {
|
||||||
logger.Info().Str("addr", srv.Addr).Msgf("server stopped")
|
logger.Info().Str("proto", proto).Str("addr", addr(srv)).Msg("server stopped")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
75
internal/net/gphttp/server/utils.go
Normal file
75
internal/net/gphttp/server/utils.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/quic-go/quic-go/http3"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
slogzerolog "github.com/samber/slog-zerolog/v2"
|
||||||
|
"github.com/yusing/go-proxy/internal/common"
|
||||||
|
"github.com/yusing/go-proxy/internal/net/gphttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func advertiseHTTP3(handler http.Handler, h3 *http3.Server) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.ProtoMajor < 3 {
|
||||||
|
err := h3.SetQUICHeaders(w.Header())
|
||||||
|
if err != nil {
|
||||||
|
gphttp.ServerError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func proto[Server httpServer](srv Server) string {
|
||||||
|
var proto string
|
||||||
|
switch src := any(srv).(type) {
|
||||||
|
case *http.Server:
|
||||||
|
if src.TLSConfig == nil {
|
||||||
|
proto = "http"
|
||||||
|
} else {
|
||||||
|
proto = "https"
|
||||||
|
}
|
||||||
|
case *http3.Server:
|
||||||
|
proto = "h3"
|
||||||
|
}
|
||||||
|
return proto
|
||||||
|
}
|
||||||
|
|
||||||
|
func addr[Server httpServer](srv Server) string {
|
||||||
|
var addr string
|
||||||
|
switch src := any(srv).(type) {
|
||||||
|
case *http.Server:
|
||||||
|
addr = src.Addr
|
||||||
|
case *http3.Server:
|
||||||
|
addr = src.Addr
|
||||||
|
}
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func getServeFunc[listener any](l listener, serve func(listener) error) func() error {
|
||||||
|
return func() error {
|
||||||
|
return serve(l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setDebugLogger[Server httpServer](srv Server, logger *zerolog.Logger) {
|
||||||
|
if !common.IsDebug {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch srv := any(srv).(type) {
|
||||||
|
case *http.Server:
|
||||||
|
srv.ErrorLog = log.New(logger, "", 0)
|
||||||
|
case *http3.Server:
|
||||||
|
logOpts := slogzerolog.Option{Level: slog.LevelDebug, Logger: logger}
|
||||||
|
srv.Logger = slog.New(logOpts.NewZerologHandler())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func logStarted[Server httpServer](srv Server, logger *zerolog.Logger) {
|
||||||
|
logger.Info().Str("proto", proto(srv)).Str("addr", addr(srv)).Msg("server started")
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue