We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
接收请求涉及的内容较多,在我公众号的文章中已经有详细概况总结过,具体查看文章:「深入学习解析HTTP请求」
func httpRequest(method string, url string, options ...*Option) (code int, content string, err error) { start := time.Now() reqOpts := defaultRequestOptions() // 默认的请求选项 for _, opt := range options { // 在reqOpts上应用通过options设置的选项 opt.apply(reqOpts) } // 创建请求对象 req, err := http.NewRequest(method, url, strings.NewReader(reqOpts.data)) // 记录请求日志 defer func() { dur := int64(time.Since(start) / time.Second) if dur >= 500 { log.Println("Http"+method, url, "in", reqOpts.data, "out", content, "err", err, "dur/ms", dur) } else { log.Println("Http"+method, url, "in", reqOpts.data, "out", content, "err", err, "dur/ms", dur) } }() defer req.Body.Close() if len(reqOpts.headers) != 0 { // 设置请求头 for key, value := range reqOpts.headers { req.Header.Add(key, value) } } if err != nil { return } // 发起请求 client := &http.Client{Timeout: reqOpts.timeout} resp, error := client.Do(req) if error != nil { return 0, "", error } // 解析响应 defer resp.Body.Close() code = resp.StatusCode result, _ := ioutil.ReadAll(resp.Body) content = string(result) return } // 发起GET请求 func HttpGet(url string, options ...*Option) (code int, content string, err error) { return httpRequest("GET", url, options...) } // 发起POST请求,请求头指定Content-Type: application/json func HttpJsonPost(url string, data string, timeout time.Duration) (code int, content string, err error) { headers := map[string]string{ "Content-Type": "application/json", } code, content, err = httpRequest( "POST", url, WithTimeout(timeout), WithHeaders(headers), WithData(data)) return }
由于HTTP请求时可以设置的选项较多,不固定,所以上面的代码学习gRPC对dialOptions的实现,使用了Options设计模式优雅地解决了不定参数的传递。
// 针对可选的HTTP请求配置项,模仿gRPC使用的Options设计模式实现 type requestOption struct { timeout time.Duration data string headers map[string]string } type Option struct { apply func(option *requestOption) } func defaultRequestOptions() *requestOption { return &requestOption{ // 默认请求选项 timeout: 5 * time.Second, data: "", headers: nil, } } func WithTimeout(timeout time.Duration) *Option { return &Option{ apply: func(option *requestOption) { option.timeout = timeout }, } }
详细代码,请查看仓库里的代码:https://github.com/kevinyan815/gocookbook/blob/master/codes/httptool/http_util.go
The text was updated successfully, but these errors were encountered:
No branches or pull requests
读取请求
接收请求涉及的内容较多,在我公众号的文章中已经有详细概况总结过,具体查看文章:「深入学习解析HTTP请求」
发起请求
由于HTTP请求时可以设置的选项较多,不固定,所以上面的代码学习gRPC对dialOptions的实现,使用了Options设计模式优雅地解决了不定参数的传递。
详细代码,请查看仓库里的代码:https://github.com/kevinyan815/gocookbook/blob/master/codes/httptool/http_util.go
The text was updated successfully, but these errors were encountered: