github.com/jghiloni/cli@v6.28.1-0.20170628223758-0ce05fe032a2+incompatible/api/uaa/uaa_connection.go (about)

     1  package uaa
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/tls"
     6  	"crypto/x509"
     7  	"encoding/json"
     8  	"io/ioutil"
     9  	"net"
    10  	"net/http"
    11  	"net/url"
    12  	"time"
    13  )
    14  
    15  // UAAConnection represents the connection to UAA
    16  type UAAConnection struct {
    17  	HTTPClient *http.Client
    18  }
    19  
    20  // NewConnection returns a pointer to a new UAA Connection
    21  func NewConnection(skipSSLValidation bool, dialTimeout time.Duration) *UAAConnection {
    22  	tr := &http.Transport{
    23  		TLSClientConfig: &tls.Config{
    24  			InsecureSkipVerify: skipSSLValidation,
    25  		},
    26  		Proxy: http.ProxyFromEnvironment,
    27  		DialContext: (&net.Dialer{
    28  			KeepAlive: 30 * time.Second,
    29  			Timeout:   dialTimeout,
    30  		}).DialContext,
    31  	}
    32  
    33  	return &UAAConnection{
    34  		HTTPClient: &http.Client{Transport: tr},
    35  	}
    36  }
    37  
    38  // Make takes a passedRequest, converts it into an HTTP request and then
    39  // executes it. The response is then injected into passedResponse.
    40  func (connection *UAAConnection) Make(request *http.Request, passedResponse *Response) error {
    41  	// In case this function is called from a retry, passedResponse may already
    42  	// be populated with a previous response. We reset in case there's an HTTP
    43  	// error and we don't repopulate it in populateResponse.
    44  	passedResponse.reset()
    45  
    46  	response, err := connection.HTTPClient.Do(request)
    47  	if err != nil {
    48  		return connection.processRequestErrors(request, err)
    49  	}
    50  
    51  	return connection.populateResponse(response, passedResponse)
    52  }
    53  
    54  func (connection *UAAConnection) processRequestErrors(request *http.Request, err error) error {
    55  	switch e := err.(type) {
    56  	case *url.Error:
    57  		if _, ok := e.Err.(x509.UnknownAuthorityError); ok {
    58  			return UnverifiedServerError{
    59  				URL: request.URL.String(),
    60  			}
    61  		}
    62  		return RequestError{Err: e}
    63  	default:
    64  		return err
    65  	}
    66  }
    67  
    68  func (connection *UAAConnection) populateResponse(response *http.Response, passedResponse *Response) error {
    69  	passedResponse.HTTPResponse = response
    70  
    71  	rawBytes, err := ioutil.ReadAll(response.Body)
    72  	defer response.Body.Close()
    73  	if err != nil {
    74  		return err
    75  	}
    76  	passedResponse.RawResponse = rawBytes
    77  
    78  	err = connection.handleStatusCodes(response, passedResponse)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	if passedResponse.Result != nil {
    84  		decoder := json.NewDecoder(bytes.NewBuffer(passedResponse.RawResponse))
    85  		decoder.UseNumber()
    86  		err = decoder.Decode(passedResponse.Result)
    87  		if err != nil {
    88  			return err
    89  		}
    90  	}
    91  
    92  	return nil
    93  }
    94  
    95  func (*UAAConnection) handleStatusCodes(response *http.Response, passedResponse *Response) error {
    96  	if response.StatusCode >= 400 {
    97  		return RawHTTPStatusError{
    98  			StatusCode:  response.StatusCode,
    99  			RawResponse: passedResponse.RawResponse,
   100  		}
   101  	}
   102  
   103  	return nil
   104  }