github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/api/http.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package api
     5  
     6  import (
     7  	"crypto/tls"
     8  	"io"
     9  	"net/http"
    10  	"net/url"
    11  
    12  	"github.com/juju/errors"
    13  	"github.com/juju/utils"
    14  
    15  	apihttp "github.com/juju/juju/api/http"
    16  	apiserverhttp "github.com/juju/juju/apiserver/http"
    17  )
    18  
    19  var newHTTPClient = func(s Connection) apihttp.HTTPClient {
    20  	return s.NewHTTPClient()
    21  }
    22  
    23  // NewHTTPClient returns an HTTP client initialized based on State.
    24  func (s *State) NewHTTPClient() *http.Client {
    25  	httpclient := utils.GetValidatingHTTPClient()
    26  	tlsconfig := tls.Config{
    27  		RootCAs: s.certPool,
    28  		// We want to be specific here (rather than just using "anything".
    29  		// See commit 7fc118f015d8480dfad7831788e4b8c0432205e8 (PR 899).
    30  		ServerName: "juju-apiserver",
    31  	}
    32  	httpclient.Transport = utils.NewHttpTLSTransport(&tlsconfig)
    33  	return httpclient
    34  }
    35  
    36  // NewHTTPRequest returns a new API-supporting HTTP request based on State.
    37  func (s *State) NewHTTPRequest(method, path string) (*http.Request, error) {
    38  	baseURL, err := url.Parse(s.serverRoot())
    39  	if err != nil {
    40  		return nil, errors.Annotatef(err, "while parsing base URL (%s)", s.serverRoot())
    41  	}
    42  
    43  	tag, err := s.EnvironTag()
    44  	if err != nil {
    45  		return nil, errors.Annotate(err, "while extracting environment UUID")
    46  	}
    47  	uuid := tag.Id()
    48  
    49  	req, err := apiserverhttp.NewRequest(method, baseURL, path, uuid, s.tag, s.password)
    50  	return req, errors.Trace(err)
    51  }
    52  
    53  // SendHTTPRequest sends a GET request using the HTTP client derived from State.
    54  func (s *State) SendHTTPRequest(path string, args interface{}) (*http.Request, *http.Response, error) {
    55  	req, err := s.NewHTTPRequest("GET", path)
    56  	if err != nil {
    57  		return nil, nil, errors.Trace(err)
    58  	}
    59  
    60  	err = apiserverhttp.SetRequestArgs(req, args)
    61  	if err != nil {
    62  		return nil, nil, errors.Annotate(err, "while setting request body")
    63  	}
    64  
    65  	httpclient := newHTTPClient(s)
    66  	resp, err := httpclient.Do(req)
    67  	if err != nil {
    68  		return nil, nil, errors.Annotate(err, "while sending HTTP request")
    69  	}
    70  	return req, resp, nil
    71  }
    72  
    73  // SendHTTPRequestReader sends a PUT request using the HTTP client derived
    74  // from State. The provided io.Reader and associated JSON metadata are
    75  // attached to the request body as multi-part data. The name parameter
    76  // identifies the attached data's part in the multi-part data. That name
    77  // doesn't have any semantic significance in juju, so the provided value
    78  // is strictly informational.
    79  func (s *State) SendHTTPRequestReader(path string, attached io.Reader, meta interface{}, name string) (*http.Request, *http.Response, error) {
    80  	req, err := s.NewHTTPRequest("PUT", path)
    81  	if err != nil {
    82  		return nil, nil, errors.Trace(err)
    83  	}
    84  
    85  	if err := apiserverhttp.AttachToRequest(req, attached, meta, name); err != nil {
    86  		return nil, nil, errors.Trace(err)
    87  	}
    88  
    89  	httpclient := newHTTPClient(s)
    90  	resp, err := httpclient.Do(req)
    91  	if err != nil {
    92  		return nil, nil, errors.Annotate(err, "while sending HTTP request")
    93  	}
    94  	return req, resp, nil
    95  }