packer-cn/vendor/github.com/ucloud/ucloud-sdk-go/private/protocol/http/client.go

81 lines
1.7 KiB
Go

/*
Package http is an implementation of http protocol
*/
package http
import (
"io/ioutil"
"net/http"
"time"
)
// Client is the interface of http client
type Client interface {
Send(*HttpRequest) (*HttpResponse, error)
}
// HttpClient used to send a real request via http to server
type HttpClient struct {
}
// NewHttpClient will create a new HttpClient instance
func NewHttpClient() HttpClient {
return HttpClient{}
}
// Send will send a real http request to remote server
func (c *HttpClient) Send(req *HttpRequest) (*HttpResponse, error) {
// build http.Client with timeout settings
httpClient, err := c.buildHTTPClient(req.GetTimeout())
if err != nil {
return nil, err
}
// convert sdk http request to origin http.Request
httpReq, err := req.buildHTTPRequest()
if err != nil {
return nil, err
}
// TODO: enable tracer via `httptrace` package
resp, err := c.doHTTPRequest(httpClient, httpReq)
if err != nil {
return nil, err
}
return resp, nil
}
func (c *HttpClient) buildHTTPClient(timeout time.Duration) (*http.Client, error) {
httpClient := http.Client{}
if timeout != 0 {
httpClient = http.Client{Timeout: timeout}
}
return &httpClient, nil
}
func (c *HttpClient) doHTTPRequest(client *http.Client, req *http.Request) (*HttpResponse, error) {
// send request
httpResp, err := client.Do(req)
if err != nil {
return nil, err
}
defer httpResp.Body.Close()
// raise status error
if httpResp.StatusCode >= 400 {
return nil, NewStatusError(httpResp.StatusCode, httpResp.Status)
}
// read content
body, err := ioutil.ReadAll(httpResp.Body)
if err != nil {
return nil, err
}
// build response wrapper
resp := NewHttpResponse()
resp.setHttpResponse(httpResp)
resp.SetBody(body)
return resp, nil
}