mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
Avoid per request URL parsing (#17593)
Every request does a `url.Parse(c.url.String())` to clone a URL. The host will also be static, so we rewrite that on creation.
This commit is contained in:
parent
cb1ec0a0d9
commit
45a717a142
@ -126,16 +126,14 @@ func removeEmptyPort(host string) string {
|
||||
}
|
||||
|
||||
// Copied from http.NewRequest but implemented to ensure we re-use `url.URL` instance.
|
||||
func (c *Client) newRequest(ctx context.Context, u *url.URL, body io.Reader) (*http.Request, error) {
|
||||
func (c *Client) newRequest(ctx context.Context, u url.URL, body io.Reader) (*http.Request, error) {
|
||||
rc, ok := body.(io.ReadCloser)
|
||||
if !ok && body != nil {
|
||||
rc = io.NopCloser(body)
|
||||
}
|
||||
u.Host = removeEmptyPort(u.Host)
|
||||
// The host's colon:port should be normalized. See Issue 14836.
|
||||
req := &http.Request{
|
||||
Method: http.MethodPost,
|
||||
URL: u,
|
||||
URL: &u,
|
||||
Proto: "HTTP/1.1",
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 1,
|
||||
@ -288,22 +286,19 @@ func (c *Client) dumpHTTP(req *http.Request, resp *http.Response) {
|
||||
|
||||
// Call - make a REST call with context.
|
||||
func (c *Client) Call(ctx context.Context, method string, values url.Values, body io.Reader, length int64) (reply io.ReadCloser, err error) {
|
||||
urlStr := c.url.String()
|
||||
if !c.IsOnline() {
|
||||
return nil, &NetworkError{c.LastError()}
|
||||
}
|
||||
|
||||
u, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, &NetworkError{Err: &url.Error{Op: method, URL: urlStr, Err: err}}
|
||||
return nil, &NetworkError{Err: c.LastError()}
|
||||
}
|
||||
|
||||
// Shallow copy. We don't modify the *UserInfo, if set.
|
||||
// All other fields are copied.
|
||||
u := *c.url
|
||||
u.Path = path.Join(u.Path, method)
|
||||
u.RawQuery = values.Encode()
|
||||
|
||||
req, err := c.newRequest(ctx, u, body)
|
||||
if err != nil {
|
||||
return nil, &NetworkError{err}
|
||||
return nil, &NetworkError{Err: err}
|
||||
}
|
||||
if length > 0 {
|
||||
req.ContentLength = length
|
||||
@ -379,14 +374,27 @@ func (c *Client) Close() {
|
||||
}
|
||||
|
||||
// NewClient - returns new REST client.
|
||||
func NewClient(url *url.URL, tr http.RoundTripper, newAuthToken func(aud string) string) *Client {
|
||||
func NewClient(uu *url.URL, tr http.RoundTripper, newAuthToken func(aud string) string) *Client {
|
||||
connected := int32(online)
|
||||
urlStr := uu.String()
|
||||
u, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
// Mark offline, with no reconnection attempts.
|
||||
connected = int32(offline)
|
||||
err = &url.Error{URL: urlStr, Err: err}
|
||||
}
|
||||
// The host's colon:port should be normalized. See Issue 14836.
|
||||
u.Host = removeEmptyPort(u.Host)
|
||||
|
||||
// Transport is exactly same as Go default in https://golang.org/pkg/net/http/#RoundTripper
|
||||
// except custom DialContext and TLSClientConfig.
|
||||
return &Client{
|
||||
httpClient: &http.Client{Transport: tr},
|
||||
url: url,
|
||||
url: u,
|
||||
lastErr: err,
|
||||
lastErrTime: time.Now(),
|
||||
newAuthToken: newAuthToken,
|
||||
connected: online,
|
||||
connected: connected,
|
||||
lastConn: time.Now().UnixNano(),
|
||||
MaxErrResponseSize: 4096,
|
||||
HealthCheckReconnectUnit: 200 * time.Millisecond,
|
||||
|
Loading…
Reference in New Issue
Block a user