github.1485827954.workers.dev/newrelic/newrelic-client-go@v1.1.0/internal/http/request.go (about) 1 package http 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io" 8 9 "github.com/google/go-querystring/query" 10 retryablehttp "github.com/hashicorp/go-retryablehttp" 11 12 "github.com/newrelic/newrelic-client-go/pkg/config" 13 ) 14 15 // Request represents a configurable HTTP request. 16 type Request struct { 17 method string 18 url string 19 params interface{} 20 reqBody interface{} 21 value interface{} 22 config config.Config 23 authStrategy RequestAuthorizer 24 errorValue ErrorResponse 25 request *retryablehttp.Request 26 } 27 28 // NewRequest creates a new Request struct. 29 func (c *Client) NewRequest(method string, url string, params interface{}, reqBody interface{}, value interface{}) (*Request, error) { 30 var ( 31 err error 32 requestBody []byte 33 readBuffer io.Reader 34 ) 35 36 req := &Request{ 37 method: method, 38 url: url, 39 params: params, 40 reqBody: reqBody, 41 value: value, 42 authStrategy: c.authStrategy, 43 errorValue: c.errorValue, 44 } 45 46 // FIXME: We should remove this requirement on the request 47 // Make a copy of the client's config 48 cfg := c.config 49 req.config = cfg 50 51 if reqBody != nil { 52 switch val := reqBody.(type) { 53 case []byte: 54 requestBody = val 55 default: 56 requestBody, err = json.Marshal(val) 57 if err != nil { 58 return nil, err 59 } 60 } 61 } 62 63 req.request, err = retryablehttp.NewRequest(req.method, url, nil) 64 if err != nil { 65 return nil, err 66 } 67 68 readBuffer, err = c.compressor.Compress(req, requestBody) 69 if err != nil { 70 return nil, err 71 } 72 73 if err := req.request.SetBody(readBuffer); err != nil { 74 return nil, err 75 } 76 77 req.SetHeader(defaultNewRelicRequestingServiceHeader, cfg.ServiceName) 78 req.SetHeader("Content-Type", "application/json") 79 80 if cfg.UserAgent != "" { 81 req.SetHeader("User-Agent", cfg.UserAgent) 82 } else { 83 req.SetHeader("User-Agent", defaultUserAgent) 84 } 85 86 return req, nil 87 } 88 89 // WithContext sets the context of the underlying request. 90 func (r *Request) WithContext(ctx context.Context) { 91 r.request.WithContext(ctx) 92 } 93 94 // SetHeader sets a header on the underlying request. 95 func (r *Request) SetHeader(key string, value string) { 96 r.request.Header.Set(key, value) 97 } 98 99 // GetHeader returns the value of the header requested 100 func (r *Request) GetHeader(key string) string { 101 return r.request.Header.Get(key) 102 } 103 104 // DelHeader deletes the specified header if it exists 105 func (r *Request) DelHeader(key string) { 106 if r != nil && r.request != nil && r.request.Header != nil { 107 r.request.Header.Del(key) 108 } 109 } 110 111 // SetAuthStrategy sets the authentication strategy for the request. 112 func (r *Request) SetAuthStrategy(ra RequestAuthorizer) { 113 r.authStrategy = ra 114 } 115 116 // SetErrorValue sets the error object for the request. 117 func (r *Request) SetErrorValue(e ErrorResponse) { 118 r.errorValue = e 119 } 120 121 // SetServiceName sets the service name for the request. 122 func (r *Request) SetServiceName(serviceName string) { 123 serviceName = fmt.Sprintf("%s|%s", serviceName, defaultServiceName) 124 r.SetHeader(defaultNewRelicRequestingServiceHeader, serviceName) 125 } 126 127 func (r *Request) makeRequest() (*retryablehttp.Request, error) { 128 r.authStrategy.AuthorizeRequest(r, &r.config) 129 130 err := r.setQueryParams() 131 if err != nil { 132 return nil, err 133 } 134 135 return r.request, nil 136 } 137 138 func (r *Request) setQueryParams() error { 139 if r.params == nil || len(r.request.URL.Query()) > 0 { 140 return nil 141 } 142 143 q, err := query.Values(r.params) 144 145 if err != nil { 146 return err 147 } 148 149 r.request.URL.RawQuery = q.Encode() 150 151 return nil 152 }