From 371bc17179a46e4b068f755faf25560de9a84233 Mon Sep 17 00:00:00 2001 From: Ehsan Noureddin Moosa Date: Wed, 6 Dec 2023 15:22:52 +0300 Subject: [PATCH] [kit] add socks and http proxy support for stub --- contrib/go.mod | 4 +- contrib/go.sum | 8 +- kit/go.mod | 14 +-- kit/go.sum | 26 ++--- kit/internal/tpl/ts/stub.tstmpl | 186 ++++++++++++++++++++++++++++++++ kit/stub/option.go | 37 +++++++ kit/stub/stub.go | 6 +- 7 files changed, 254 insertions(+), 27 deletions(-) create mode 100644 kit/internal/tpl/ts/stub.tstmpl diff --git a/contrib/go.mod b/contrib/go.mod index 8cb5a0e5..f41467db 100644 --- a/contrib/go.mod +++ b/contrib/go.mod @@ -5,8 +5,8 @@ go 1.20 require ( github.com/clubpay/ronykit/kit v0.11.25 github.com/clubpay/ronykit/std/gateways/fasthttp v0.11.25 - github.com/go-openapi/spec v0.20.9 - github.com/onsi/ginkgo/v2 v2.13.1 + github.com/go-openapi/spec v0.20.11 + github.com/onsi/ginkgo/v2 v2.13.2 github.com/onsi/gomega v1.30.0 github.com/rbretecher/go-postman-collection v0.9.0 go.opentelemetry.io/contrib/propagators/b3 v1.21.1 diff --git a/contrib/go.sum b/contrib/go.sum index a84d10af..f81135e8 100644 --- a/contrib/go.sum +++ b/contrib/go.sum @@ -25,8 +25,8 @@ github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUe github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= -github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.11 h1:J/TzFDLTt4Rcl/l1PmyErvkqlJDncGvPTMnCI39I4gY= +github.com/go-openapi/spec v0.20.11/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= @@ -65,8 +65,8 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU= -github.com/onsi/ginkgo/v2 v2.13.1/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +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.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= diff --git a/kit/go.mod b/kit/go.mod index 3239858b..a5f70cd5 100644 --- a/kit/go.mod +++ b/kit/go.mod @@ -7,17 +7,18 @@ require ( github.com/goccy/go-json v0.10.2 github.com/goccy/go-reflect v1.2.0 github.com/jedib0t/go-pretty/v6 v6.4.9 - github.com/onsi/ginkgo/v2 v2.13.0 - github.com/onsi/gomega v1.28.0 + github.com/onsi/ginkgo/v2 v2.13.2 + github.com/onsi/gomega v1.29.0 github.com/valyala/fasthttp v1.51.0 + golang.org/x/net v0.17.0 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/andybalholm/brotli v1.0.5 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/klauspost/compress v1.17.1 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -27,10 +28,9 @@ require ( github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect github.com/stretchr/testify v1.8.4 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.12.0 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/kit/go.sum b/kit/go.sum index 2d43bb47..ae3769ac 100644 --- a/kit/go.sum +++ b/kit/go.sum @@ -9,8 +9,8 @@ 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= github.com/fasthttp/websocket v1.5.6 h1:4WtWgRJ0Gzj1Ou+xGKy66Ji+a0mUfgAj9ZdPqHiUwQE= github.com/fasthttp/websocket v1.5.6/go.mod h1:yiKhNx2zFOv65YYtCJNhtl5VjdCFew3W+gt8U/9aFkI= -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-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 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/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= @@ -20,8 +20,8 @@ github.com/goccy/go-reflect v1.2.0/go.mod h1:n0oYZn8VcV2CkWTxi8B9QjkCoq6GTtCEdfm github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -39,10 +39,10 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= -github.com/onsi/gomega v1.28.0/go.mod h1:A1H2JE76sI14WIP57LMKj7FVfCHx3g3BcZVjJG8bjX8= +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.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -66,17 +66,17 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= diff --git a/kit/internal/tpl/ts/stub.tstmpl b/kit/internal/tpl/ts/stub.tstmpl new file mode 100644 index 00000000..a435c511 --- /dev/null +++ b/kit/internal/tpl/ts/stub.tstmpl @@ -0,0 +1,186 @@ +{{ define "dto" }} + // {{.Name}} is a data transfer object + {{ range .Comments -}} + // {{.}} + {{ end -}} + type {{.Name}} struct { + {{- range .Fields -}} + {{- if .IsDTO }} + {{- if .Embedded }} + {{.Name}} + {{- else }} + {{.Name}} {{.Type}} {{ if gt (len .Tags) 0 }}`{{ range .Tags -}}{{.Name}}:"{{.Value}}"{{- end }}`{{- end }} + {{- end }} + {{- else }} + {{.Name}} {{.Type}} {{ if gt (len .Tags) 0 }}`{{ range .Tags -}}{{.Name}}:"{{.Value}}"{{- end }}`{{- end }} + {{- end }} + {{- end }} + } + {{ if .IsErr }} + {{- if ne .CodeField ""}} + func (x {{.Name}}) GetCode() int { + return x.{{.CodeField}} + } + {{- end }} + {{ if ne .ItemField ""}} + func (x {{.Name}}) GetItem() string { + return x.{{.ItemField}} + } + {{- end }} + {{- end }} +{{ end }} +// Code generated by RonyKIT Stub Generator (Golang); DO NOT EDIT. + +package {{.Pkg}} + +import ( + "context" + "fmt" + + "github.com/clubpay/ronykit/kit" + "github.com/clubpay/ronykit/kit/stub" + "github.com/clubpay/ronykit/kit/utils/reflector" +) + +var _ fmt.Stringer + +{{$tags := strQuote .Tags}} +func init() { +{{- range $dtoName, $dto := .DTOs }} +reflector.Register(&{{$dtoName}}{}, {{strJoin $tags ","}}) +{{- end }} +} + +{{ range $dtoName, $dto := .DTOs }} +{{ template "dto" $dto }} +{{ end }} + +{{$serviceName := .Name}} +type I{{$serviceName}}Stub interface { + {{ range .RESTs }} + {{$methodName := .Name}} + {{- if ne $methodName "" -}} + {{$methodName}}( + ctx context.Context, req *{{.Request.Name}}, opt ...stub.RESTOption, + ) (*{{.Response.Name}}, *stub.Error) + {{- end -}} + {{- end }} +} + +// {{$serviceName}}Stub represents the client/stub for {{$serviceName}}. +// Implements I{{$serviceName}}Stub +type {{$serviceName}}Stub struct { + hostPort string + secure bool + verifyTLS bool + + s *stub.Stub +} + +func New{{$serviceName}}Stub(hostPort string, opts ...stub.Option) *{{$serviceName}}Stub { + s := &{{$serviceName}}Stub{ + s: stub.New(hostPort, opts...), + } + + return s +} + +var _ I{{$serviceName}}Stub = (*{{$serviceName}}Stub)(nil) + +{{ range .RESTs }} +{{$methodName := .Name}} +{{- if ne $methodName "" }} +func (s {{$serviceName}}Stub) {{$methodName}}( + ctx context.Context, req *{{.Request.Name}}, opt ...stub.RESTOption, +) (*{{.Response.Name}}, *stub.Error){ + res := &{{.Response.Name}}{} + httpCtx := s.s.REST(opt...). + SetMethod("{{.Method}}"). + {{ range $idx, $errDto := .PossibleErrors }} + SetResponseHandler( + {{ $errDto.Code }}, + func(ctx context.Context, r stub.RESTResponse) *stub.Error { + res := &{{$errDto.DTO.Name}}{} + err := stub.WrapError(kit.UnmarshalMessage(r.GetBody(), res)) + if err != nil { + return err + } + + return stub.NewErrorWithMsg(res) + }, + ). + {{- end }} + SetOKHandler( + func(ctx context.Context, r stub.RESTResponse) *stub.Error { + return stub.WrapError(kit.UnmarshalMessage(r.GetBody(), res)) + }, + ). + DefaultResponseHandler( + func(ctx context.Context, r stub.RESTResponse) *stub.Error { + return stub.NewError(r.StatusCode(), string(r.GetBody())) + }, + ). + AutoRun(ctx, "{{.Path}}", {{.Encoding}}, req) + defer httpCtx.Release() + + if err := httpCtx.Err(); err != nil { + return nil, err + } + + return res, nil +} +{{ end }} +{{- end }} + +type MockOption func(*{{$serviceName}}StubMock) + +{{ range .RESTs }} +{{$methodName := .Name}} +{{- if ne $methodName "" }} +func Mock{{$methodName}}( + f func(ctx context.Context, req *{{.Request.Name}}, opt ...stub.RESTOption) (*{{.Response.Name}}, *stub.Error), +) MockOption { + return func(sm *{{$serviceName}}StubMock) { + sm.{{toLower $methodName}} = f + } +} +{{ end }} +{{- end }} + + +// {{$serviceName}}StubMock represents the mocked for client/stub for {{$serviceName}}. +// Implements I{{$serviceName}}Stub +type {{$serviceName}}StubMock struct { +{{ range .RESTs }} + {{$methodName := .Name}} + {{- if ne $methodName "" -}} + {{toLower $methodName}} func(ctx context.Context, req *{{.Request.Name}}, opt ...stub.RESTOption) (*{{.Response.Name}}, *stub.Error) + {{- end -}} +{{- end }} +} + +func New{{$serviceName}}StubMock(opts ...MockOption) *{{$serviceName}}StubMock { + s := &{{$serviceName}}StubMock{} + for _, o := range opts { + o(s) + } + + return s +} + +var _ I{{$serviceName}}Stub = (*{{$serviceName}}StubMock)(nil) + +{{ range .RESTs }} +{{$methodName := .Name}} +{{- if ne $methodName "" }} +func (s {{$serviceName}}StubMock) {{$methodName}}( + ctx context.Context, req *{{.Request.Name}}, opt ...stub.RESTOption, +) (*{{.Response.Name}}, *stub.Error){ + if s.{{toLower $methodName}} == nil { + return nil, stub.WrapError(fmt.Errorf("method not mocked")) + } + + return s.{{toLower $methodName}}(ctx, req, opt...) +} +{{ end }} +{{- end }} diff --git a/kit/stub/option.go b/kit/stub/option.go index 1acb285a..e29508c0 100644 --- a/kit/stub/option.go +++ b/kit/stub/option.go @@ -1,10 +1,15 @@ package stub import ( + "fmt" "io" + "strings" "time" "github.com/clubpay/ronykit/kit" + "github.com/valyala/fasthttp" + "github.com/valyala/fasthttp/fasthttpproxy" + "golang.org/x/net/http/httpproxy" ) type Option func(cfg *config) @@ -20,6 +25,8 @@ type config struct { tp kit.TracePropagator readTimeout, writeTimeout, dialTimeout time.Duration + httpProxyConfig *httpproxy.Config + dialFunc fasthttp.DialFunc } func Secure() Option { @@ -76,3 +83,33 @@ func WithTracePropagator(tp kit.TracePropagator) Option { cfg.tp = tp } } + +// WithHTTPProxy returns an Option that sets the dialer to the provided HTTP proxy. +// example formats: +// +// http://localhost:9050 +// http://username:password@localhost:9050 +// https://localhost:9050 +func WithHTTPProxy(url string, timeout time.Duration) Option { + return func(cfg *config) { + cfg.httpProxyConfig = httpproxy.FromEnvironment() + switch { + default: + panic(fmt.Errorf("unsupported proxy scheme: %s", url)) + case strings.HasPrefix(url, "https://"): + cfg.httpProxyConfig.HTTPSProxy = url + case strings.HasPrefix(url, "http://"): + cfg.httpProxyConfig.HTTPProxy = url + } + + cfg.dialFunc = fasthttpproxy.FasthttpHTTPDialerTimeout(url, timeout) + } +} + +// WithSocksProxy returns an Option that sets the dialer to the provided SOCKS5 proxy. +// example format: socks5://localhost:9050 +func WithSocksProxy(url string) Option { + return func(cfg *config) { + cfg.dialFunc = fasthttpproxy.FasthttpSocksDialer(url) + } +} diff --git a/kit/stub/stub.go b/kit/stub/stub.go index fddc484b..d4795171 100644 --- a/kit/stub/stub.go +++ b/kit/stub/stub.go @@ -44,6 +44,7 @@ func New(hostPort string, opts ...Option) *Stub { Name: cfg.name, ReadTimeout: cfg.readTimeout, WriteTimeout: cfg.writeTimeout, + Dial: cfg.dialFunc, TLSConfig: &tls.Config{ InsecureSkipVerify: cfg.skipVerifyTLS, //nolint:gosec }, @@ -107,6 +108,7 @@ func (s *Stub) REST(opt ...RESTOption) *RESTCtx { } func (s *Stub) Websocket(opts ...WebsocketOption) *WebsocketCtx { + proxyFunc := s.cfg.httpProxyConfig.ProxyFunc() ctx := &WebsocketCtx{ cfg: wsConfig{ autoReconnect: true, @@ -118,7 +120,9 @@ func (s *Stub) Websocket(opts ...WebsocketOption) *WebsocketCtx { rpcOutFactory: common.SimpleOutgoingJSONRPC, dialerBuilder: func() *websocket.Dialer { return &websocket.Dialer{ - Proxy: http.ProxyFromEnvironment, + Proxy: func(req *http.Request) (*url.URL, error) { + return proxyFunc(req.URL) + }, HandshakeTimeout: s.cfg.dialTimeout, } },