github.com/elopio/cli@v6.21.2-0.20160902224010-ea909d1fdb2f+incompatible/cf/api/curl.go (about)

     1  package api
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"net/http/httputil"
     9  	"net/textproto"
    10  	"strings"
    11  
    12  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
    13  	"code.cloudfoundry.org/cli/cf/errors"
    14  	. "code.cloudfoundry.org/cli/cf/i18n"
    15  	"code.cloudfoundry.org/cli/cf/net"
    16  )
    17  
    18  //go:generate counterfeiter . CurlRepository
    19  
    20  type CurlRepository interface {
    21  	Request(method, path, header, body string) (resHeaders string, resBody string, apiErr error)
    22  }
    23  
    24  type CloudControllerCurlRepository struct {
    25  	config  coreconfig.Reader
    26  	gateway net.Gateway
    27  }
    28  
    29  func NewCloudControllerCurlRepository(config coreconfig.Reader, gateway net.Gateway) (repo CloudControllerCurlRepository) {
    30  	repo.config = config
    31  	repo.gateway = gateway
    32  	return
    33  }
    34  
    35  func (repo CloudControllerCurlRepository) Request(method, path, headerString, body string) (resHeaders, resBody string, err error) {
    36  	url := fmt.Sprintf("%s/%s", repo.config.APIEndpoint(), strings.TrimLeft(path, "/"))
    37  
    38  	if method == "" && body != "" {
    39  		method = "POST"
    40  	}
    41  
    42  	req, err := repo.gateway.NewRequest(method, url, repo.config.AccessToken(), strings.NewReader(body))
    43  	if err != nil {
    44  		return
    45  	}
    46  
    47  	err = mergeHeaders(req.HTTPReq.Header, headerString)
    48  	if err != nil {
    49  		err = fmt.Errorf("%s: %s", T("Error parsing headers"), err.Error())
    50  		return
    51  	}
    52  
    53  	res, err := repo.gateway.PerformRequest(req)
    54  
    55  	if _, ok := err.(errors.HTTPError); ok {
    56  		err = nil
    57  	}
    58  
    59  	if err != nil {
    60  		return
    61  	}
    62  	defer res.Body.Close()
    63  
    64  	headerBytes, _ := httputil.DumpResponse(res, false)
    65  	resHeaders = string(headerBytes)
    66  
    67  	bytes, err := ioutil.ReadAll(res.Body)
    68  	if err != nil {
    69  		err = fmt.Errorf("%s: %s", T("Error reading response"), err.Error())
    70  	}
    71  	resBody = string(bytes)
    72  
    73  	return
    74  }
    75  
    76  func mergeHeaders(destination http.Header, headerString string) (err error) {
    77  	headerString = strings.TrimSpace(headerString)
    78  	headerString += "\n\n"
    79  	headerReader := bufio.NewReader(strings.NewReader(headerString))
    80  	headers, err := textproto.NewReader(headerReader).ReadMIMEHeader()
    81  	if err != nil {
    82  		return
    83  	}
    84  
    85  	for key, values := range headers {
    86  		destination.Del(key)
    87  		for _, value := range values {
    88  			destination.Add(key, value)
    89  		}
    90  	}
    91  
    92  	return
    93  }