@@ -2,6 +2,7 @@ package main
22
33import (
44 "context"
5+ "encoding/base64"
56 "flag"
67 "fmt"
78 "io"
2122 version string
2223)
2324
24- const connTimeoutInSecs = 10
25+ const (
26+ connTimeoutInSecs = 10
27+ maxHeaders = 100
28+ )
2529
2630func main () {
2731 flag .Parse ()
@@ -63,7 +67,7 @@ func main() {
6367 os .Exit (10 )
6468 }
6569
66- httpClient := & http. Client { Timeout : connTimeoutInSecs * time . Second }
70+ httpClient := NewHTTPClient ( commonConfig )
6771 nginxClient , err := nginx .NewNginxClient (commonConfig .APIEndpoint , nginx .WithHTTPClient (httpClient ))
6872 if err != nil {
6973 log .Printf ("Couldn't create NGINX client: %v" , err )
@@ -189,3 +193,57 @@ func getStreamUpstreamServerAddresses(server []nginx.StreamUpstreamServer) []str
189193 }
190194 return streamUpstreamServerAddr
191195}
196+
197+ // headerTransport wraps an http.RoundTripper and adds custom headers to all requests.
198+ type headerTransport struct {
199+ headers http.Header
200+ transport http.RoundTripper
201+ }
202+
203+ func (t * headerTransport ) RoundTrip (req * http.Request ) (* http.Response , error ) {
204+ clonedReq := req .Clone (req .Context ())
205+
206+ for key , values := range t .headers {
207+ for _ , value := range values {
208+ clonedReq .Header .Add (key , value )
209+ }
210+ }
211+
212+ if len (clonedReq .Header ) > maxHeaders {
213+ return nil , fmt .Errorf ("number of headers in request exceeds the maximum allowed (%d)" , maxHeaders )
214+ }
215+
216+ resp , err := t .transport .RoundTrip (clonedReq )
217+ if err != nil {
218+ return nil , fmt .Errorf ("headerTransport RoundTrip failed: %w" , err )
219+ }
220+
221+ return resp , nil
222+ }
223+
224+ func NewHTTPClient (cfg * commonConfig ) * http.Client {
225+ headers := NewHeaders (cfg )
226+ baseTransport := & http.Transport {}
227+
228+ return & http.Client {
229+ Transport : & headerTransport {
230+ headers : headers ,
231+ transport : baseTransport ,
232+ },
233+ Timeout : connTimeoutInSecs * time .Second ,
234+ }
235+ }
236+
237+ func NewHeaders (cfg * commonConfig ) http.Header {
238+ headers := http.Header {}
239+ headers .Set ("Content-Type" , "application/json" )
240+
241+ if cfg .DataplaneAPIKey != "" {
242+ authValue := "ApiKey " + base64 .StdEncoding .EncodeToString ([]byte (cfg .DataplaneAPIKey ))
243+ headers .Set ("Authorization" , authValue )
244+ } else {
245+ log .Printf ("[optional] DataplaneAPIKey not configured" )
246+ }
247+
248+ return headers
249+ }
0 commit comments