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 }