package proxy import ( "context" "fmt" "io" "log" "net/http" "strings" "time" _ "embed" "github.com/imroc/req/v3" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "gopkg.in/elazarl/goproxy.v1" ) func ServeE(cmd *cobra.Command, args []string) error { duration, err := cmd.Flags().GetInt("duration") if err != nil { duration = 10 } host, err := cmd.Flags().GetString("host") if err != nil { return err } host = strings.TrimSpace(host) if host == "" { logrus.Fatal("host is empty") } logrus.SetLevel(logrus.WarnLevel) debug, err := cmd.Flags().GetBool("debug") if err != nil { return err } return NewProxy(host, debug, duration).Serve(29999) } func NewProxy(host string, debug bool, duration int) *Proxy { return New( WithHost(host), WithLogger(log.New(io.Discard, "", log.LstdFlags)), WithHttps(), WithDebug(debug), WithVerbose(), WithFollower(), WithUserInfo(duration), ) } type Option func(*Proxy) func WithLogger(logger *log.Logger) Option { return func(p *Proxy) { p.proxy.Logger = logger // p.proxy.Logger = log.New(io.Discard, "", log.LstdFlags) } } func WithVerbose() Option { return func(p *Proxy) { p.proxy.Verbose = true } } func WithHttps() Option { return func(p *Proxy) { p.proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm) } } func WithDebug(debug bool) Option { return func(p *Proxy) { if debug { p.client = p.client.DevMode() logrus.SetLevel(logrus.DebugLevel) } } } func WithHost(h string) Option { return func(p *Proxy) { logrus.Infof("post data to host: %s", h) p.client = req.C(). SetBaseURL(h). EnableInsecureSkipVerify(). SetTimeout(10*time.Second). SetCommonBasicAuth("rogeecn", "xixi@0202") } } type Proxy struct { proxy *goproxy.ProxyHttpServer client *req.Client server *http.Server } func New(opts ...Option) *Proxy { proxy := &Proxy{ proxy: goproxy.NewProxyHttpServer(), } for _, opt := range opts { opt(proxy) } return proxy } // run func (p *Proxy) Serve(port uint) error { logrus.Infof("douyin proxy start serve at: :%d", port) p.server = &http.Server{ Addr: fmt.Sprintf(":%d", port), Handler: p.proxy, } return p.server.ListenAndServe() } func (p *Proxy) Shutdown() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() return p.server.Shutdown(ctx) }