diff --git a/options.go b/options.go index 1b8236b..f3ba187 100644 --- a/options.go +++ b/options.go @@ -4,6 +4,7 @@ import ( "context" "git.nspix.com/golang/kos/util/env" "git.nspix.com/golang/kos/util/ip" + "git.nspix.com/golang/kos/util/sys" "os" "strings" "syscall" @@ -68,7 +69,7 @@ func WithDebug() Option { func NewOptions() *Options { opts := &Options{ - Name: env.Get(EnvAppName, ""), + Name: env.Get(EnvAppName, sys.Hostname()), Version: env.Get(EnvAppVersion, "0.0.1"), Context: context.Background(), Metadata: make(map[string]string), diff --git a/util/fetch/fetch.go b/util/fetch/fetch.go index 0fb3e31..a4d6233 100644 --- a/util/fetch/fetch.go +++ b/util/fetch/fetch.go @@ -11,6 +11,7 @@ import ( "net" "net/http" "net/url" + "path" "strings" "time" ) @@ -63,7 +64,7 @@ func Get(ctx context.Context, urlString string, cbs ...Option) (res *http.Respon req.Header.Set(k, v) } } - return Do(ctx, req) + return do(ctx, req, opts) } func Post(ctx context.Context, urlString string, cbs ...Option) (res *http.Response, err error) { @@ -113,12 +114,10 @@ func Post(ctx context.Context, urlString string, cbs ...Option) (res *http.Respo req.Header.Set(k, v) } } - req.Header.Set("Content-Type", contentType) - return Do(ctx, req) -} - -func Do(ctx context.Context, req *http.Request) (res *http.Response, err error) { - return httpClient.Do(req.WithContext(ctx)) + if contentType != "" { + req.Header.Set("Content-Type", contentType) + } + return do(ctx, req, opts) } func Request(ctx context.Context, urlString string, response any, cbs ...Option) (err error) { @@ -151,7 +150,7 @@ func Request(ctx context.Context, urlString string, response any, cbs ...Option) req.Header.Set(k, v) } } - if res, err = Do(ctx, req); err != nil { + if res, err = do(ctx, req, opts); err != nil { return } defer func() { @@ -166,12 +165,28 @@ func Request(ctx context.Context, urlString string, response any, cbs ...Option) return } contentType = strings.ToLower(res.Header.Get("Content-Type")) - if strings.Contains(contentType, JSON) { + extName := path.Ext(req.URL.String()) + if strings.Contains(contentType, JSON) || extName == ".json" { err = json.NewDecoder(res.Body).Decode(response) - } else if strings.Contains(contentType, XML) { + } else if strings.Contains(contentType, XML) || extName == ".xml" { err = xml.NewDecoder(res.Body).Decode(response) } else { err = fmt.Errorf("unsupported content type: %s", contentType) } return } + +func do(ctx context.Context, req *http.Request, opts *Options) (res *http.Response, err error) { + if opts.Human { + if req.Header.Get("User-Agent") == "" { + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.54") + } + if req.Header.Get("Referer") == "" { + req.Header.Set("Referer", req.URL.String()) + } + if req.Header.Get("Accept") == "" { + req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7") + } + } + return httpClient.Do(req.WithContext(ctx)) +} diff --git a/util/fetch/options.go b/util/fetch/options.go index 5ccfc0b..31bc0db 100644 --- a/util/fetch/options.go +++ b/util/fetch/options.go @@ -9,6 +9,7 @@ type ( Header map[string]string Params map[string]string Data any + Human bool } Option func(o *Options) ) @@ -27,7 +28,18 @@ func WithMethod(s string) Option { func WithHeader(h map[string]string) Option { return func(o *Options) { - o.Header = h + if o.Header == nil { + o.Header = h + } + for k, v := range o.Header { + o.Header[k] = v + } + } +} + +func WithHuman() Option { + return func(o *Options) { + o.Human = true } } diff --git a/util/sys/name.go b/util/sys/name.go new file mode 100644 index 0000000..65becd2 --- /dev/null +++ b/util/sys/name.go @@ -0,0 +1,8 @@ +package sys + +import "os" + +func Hostname() string { + s, _ := os.Hostname() + return s +}