/* * Copyright 2017 Baidu, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions * and limitations under the License. */ // request.go - the custom HTTP request for BCE package http import ( "context" "fmt" "io" "net/http" "strconv" "strings" "github.com/baidubce/bce-sdk-go/util" ) // Reauest stands for the general http request structure to make request to the BCE services. type Request struct { protocol string host string port int method string uri string proxyUrl string timeout int headers map[string]string params map[string]string // Optional body and length fields to set the body stream and content length body io.ReadCloser length int64 ctx context.Context httpClient *http.Client } func (r *Request) HTTPClient() *http.Client { return r.httpClient } func (r *Request) SetHTTPClient(client *http.Client) { if client != nil { r.httpClient = client } } func (r *Request) Context() context.Context { return r.ctx } func (r *Request) SetContext(ctx context.Context) { if ctx != nil { r.ctx = ctx } } func (r *Request) Protocol() string { return r.protocol } func (r *Request) SetProtocol(protocol string) { r.protocol = protocol } func (r *Request) Endpoint() string { if r.host == "" { return "" } return r.protocol + "://" + r.host } func (r *Request) SetEndpoint(endpoint string) { pos := strings.Index(endpoint, "://") rest := endpoint if pos != -1 { r.protocol = endpoint[0:pos] rest = endpoint[pos+3:] } else { r.protocol = "http" } r.SetHost(rest) } func (r *Request) Host() string { return r.host } func (r *Request) SetHost(host string) { r.host = host pos := strings.Index(host, ":") if pos != -1 { p, e := strconv.Atoi(host[pos+1:]) if e == nil { r.port = p } } if r.port == 0 { if r.protocol == "http" { r.port = 80 } else if r.protocol == "https" { r.port = 443 } } } func (r *Request) Port() int { return r.port } func (r *Request) SetPort(port int) { // Port can be set by the endpoint or host, this method is rarely used. r.port = port } func (r *Request) Headers() map[string]string { return r.headers } func (r *Request) SetHeaders(headers map[string]string) { r.headers = headers } func (r *Request) Header(key string) string { if v, ok := r.headers[key]; ok { return v } return "" } func (r *Request) SetHeader(key, value string) { if r.headers == nil { r.headers = make(map[string]string) } r.headers[key] = value } func (r *Request) Params() map[string]string { return r.params } func (r *Request) SetParams(params map[string]string) { r.params = params } func (r *Request) Param(key string) string { if v, ok := r.params[key]; ok { return v } return "" } func (r *Request) SetParam(key, value string) { if r.params == nil { r.params = make(map[string]string) } r.params[key] = value } func (r *Request) QueryString() string { buf := make([]string, 0, len(r.params)) for k, v := range r.params { if len(v) == 0 { buf = append(buf, util.UriEncode(k, true)) } else { buf = append(buf, util.UriEncode(k, true)+"="+util.UriEncode(v, true)) } } return strings.Join(buf, "&") } func (r *Request) Method() string { return r.method } func (r *Request) SetMethod(method string) { r.method = method } func (r *Request) Uri() string { return r.uri } func (r *Request) SetUri(uri string) { r.uri = uri } func (r *Request) ProxyUrl() string { return r.proxyUrl } func (r *Request) SetProxyUrl(url string) { r.proxyUrl = url } func (r *Request) Timeout() int { return r.timeout } func (r *Request) SetTimeout(timeout int) { r.timeout = timeout } func (r *Request) Body() io.ReadCloser { return r.body } func (r *Request) SetBody(stream io.ReadCloser) { r.body = stream } func (r *Request) Length() int64 { return r.length } func (r *Request) SetLength(l int64) { r.length = l } func (r *Request) GenerateUrl(addPort bool) string { if addPort { return fmt.Sprintf("%s://%s:%d%s?%s", r.protocol, r.host, r.port, r.uri, r.QueryString()) } else { return fmt.Sprintf("%s://%s%s?%s", r.protocol, r.host, r.uri, r.QueryString()) } } func (r *Request) String() string { header := make([]string, 0, len(r.headers)) for k, v := range r.headers { header = append(header, "\t"+k+"="+v) } return fmt.Sprintf("\t%s %s\n%v", r.method, r.GenerateUrl(false), strings.Join(header, "\n")) }