github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/servicebus/util/httpclient.go (about)

     1  package util
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/tls"
     6  	"errors"
     7  	"net/http"
     8  	"strings"
     9  	"time"
    10  )
    11  
    12  // SignRequest sign a http request so that it can talk to API Server
    13  var SignRequest func(*http.Request) error
    14  
    15  // URLClientOption is a struct which provides options for client
    16  type URLClientOption struct {
    17  	SSLEnabled            bool
    18  	TLSConfig             *tls.Config
    19  	Compressed            bool
    20  	HandshakeTimeout      time.Duration
    21  	ResponseHeaderTimeout time.Duration
    22  	Verbose               bool
    23  }
    24  
    25  // URLClient is a struct used for storing details of a client
    26  type URLClient struct {
    27  	*http.Client
    28  	TLS     *tls.Config
    29  	Request *http.Request
    30  	options URLClientOption
    31  }
    32  
    33  // HTTPDo is a method used for http connection
    34  func (client *URLClient) HTTPDo(method, rawURL string, headers http.Header, body []byte) (resp *http.Response, err error) {
    35  	client.clientHasPrefix(rawURL, "https")
    36  
    37  	if headers == nil {
    38  		headers = make(http.Header)
    39  	}
    40  
    41  	if _, ok := headers["Accept"]; !ok {
    42  		headers["Accept"] = []string{"*/*"}
    43  	}
    44  	if _, ok := headers["Accept-Encoding"]; !ok && client.options.Compressed {
    45  		headers["Accept-Encoding"] = []string{"deflate, gzip"}
    46  	}
    47  
    48  	req, err := http.NewRequest(method, rawURL, bytes.NewBuffer(body))
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	client.Request = req
    53  
    54  	req.Header = headers
    55  	//sign a request
    56  	if SignRequest != nil {
    57  		if err = SignRequest(req); err != nil {
    58  			return nil, errors.New("Add auth info failed, err: " + err.Error())
    59  		}
    60  	}
    61  	resp, err = client.Client.Do(req)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	return resp, nil
    67  }
    68  
    69  func (client *URLClient) clientHasPrefix(url, pro string) {
    70  	if strings.HasPrefix(url, pro) {
    71  		if transport, ok := client.Client.Transport.(*http.Transport); ok {
    72  			transport.TLSClientConfig = client.TLS
    73  		}
    74  	}
    75  }
    76  
    77  // DefaultURLClientOption is a struct object which has default client option
    78  var DefaultURLClientOption = &URLClientOption{
    79  	Compressed:            true,
    80  	HandshakeTimeout:      30 * time.Second,
    81  	ResponseHeaderTimeout: 60 * time.Second,
    82  }
    83  
    84  // GetURLClient is a function which sets client options
    85  func GetURLClient(option *URLClientOption) (client *URLClient, err error) {
    86  	if option == nil {
    87  		option = DefaultURLClientOption
    88  	} else {
    89  		switch {
    90  		case option.HandshakeTimeout == 0:
    91  			option.HandshakeTimeout = DefaultURLClientOption.HandshakeTimeout
    92  			fallthrough
    93  		case option.ResponseHeaderTimeout == 0:
    94  			option.ResponseHeaderTimeout = DefaultURLClientOption.HandshakeTimeout
    95  		}
    96  	}
    97  
    98  	if !option.SSLEnabled {
    99  		client = &URLClient{
   100  			Client: &http.Client{
   101  				Transport: &http.Transport{
   102  					TLSHandshakeTimeout:   option.HandshakeTimeout,
   103  					ResponseHeaderTimeout: option.ResponseHeaderTimeout,
   104  					DisableCompression:    !option.Compressed,
   105  				},
   106  			},
   107  			options: *option,
   108  		}
   109  
   110  		return
   111  	}
   112  
   113  	client = &URLClient{
   114  		Client: &http.Client{
   115  			Transport: &http.Transport{
   116  				TLSHandshakeTimeout:   option.HandshakeTimeout,
   117  				ResponseHeaderTimeout: option.ResponseHeaderTimeout,
   118  				DisableCompression:    !option.Compressed,
   119  			},
   120  		},
   121  		TLS:     option.TLSConfig,
   122  		options: *option,
   123  	}
   124  	return
   125  }