github.com/netdata/go.d.plugin@v0.58.1/pkg/web/request_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package web 4 5 import ( 6 "encoding/base64" 7 "net/http" 8 "strings" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestRequest_Copy(t *testing.T) { 16 tests := map[string]struct { 17 orig Request 18 change func(req *Request) 19 }{ 20 "change headers": { 21 orig: Request{ 22 URL: "http://127.0.0.1:19999/api/v1/info", 23 Method: "POST", 24 Headers: map[string]string{ 25 "X-Api-Key": "secret", 26 }, 27 Username: "username", 28 Password: "password", 29 ProxyUsername: "proxy_username", 30 ProxyPassword: "proxy_password", 31 }, 32 change: func(req *Request) { 33 req.Headers["header_key"] = "header_value" 34 }, 35 }, 36 } 37 38 for name, test := range tests { 39 t.Run(name, func(t *testing.T) { 40 reqCopy := test.orig.Copy() 41 42 assert.Equal(t, test.orig, reqCopy) 43 test.change(&reqCopy) 44 assert.NotEqual(t, test.orig, reqCopy) 45 }) 46 } 47 } 48 49 func TestNewHTTPRequest(t *testing.T) { 50 tests := map[string]struct { 51 req Request 52 wantErr bool 53 }{ 54 "test url": { 55 req: Request{ 56 URL: "http://127.0.0.1:19999/api/v1/info", 57 }, 58 wantErr: false, 59 }, 60 "test body": { 61 req: Request{ 62 Body: "content", 63 }, 64 wantErr: false, 65 }, 66 "test method": { 67 req: Request{ 68 Method: "POST", 69 }, 70 wantErr: false, 71 }, 72 "test headers": { 73 req: Request{ 74 Headers: map[string]string{ 75 "X-Api-Key": "secret", 76 }, 77 }, 78 wantErr: false, 79 }, 80 "test special headers (host)": { 81 req: Request{ 82 Headers: map[string]string{ 83 "host": "Host", 84 }, 85 }, 86 wantErr: false, 87 }, 88 "test special headers (Host)": { 89 req: Request{ 90 Headers: map[string]string{ 91 "Host": "Host", 92 }, 93 }, 94 wantErr: false, 95 }, 96 "test username and password": { 97 req: Request{ 98 Username: "username", 99 Password: "password", 100 }, 101 wantErr: false, 102 }, 103 "test proxy username and proxy password": { 104 req: Request{ 105 ProxyUsername: "proxy_username", 106 ProxyPassword: "proxy_password", 107 }, 108 wantErr: false, 109 }, 110 } 111 112 for name, test := range tests { 113 t.Run(name, func(t *testing.T) { 114 httpReq, err := NewHTTPRequest(test.req) 115 116 if test.wantErr { 117 assert.Error(t, err) 118 assert.Nil(t, httpReq) 119 return 120 } 121 122 require.NoError(t, err) 123 require.NotNil(t, httpReq) 124 require.IsType(t, (*http.Request)(nil), httpReq) 125 126 assert.Equal(t, test.req.URL, httpReq.URL.String()) 127 128 if test.req.Body != "" { 129 assert.NotNil(t, httpReq.Body) 130 } 131 132 if test.req.Username != "" || test.req.Password != "" { 133 user, pass, ok := httpReq.BasicAuth() 134 assert.True(t, ok) 135 assert.Equal(t, test.req.Username, user) 136 assert.Equal(t, test.req.Password, pass) 137 } 138 139 if test.req.Method != "" { 140 assert.Equal(t, test.req.Method, httpReq.Method) 141 } 142 143 if test.req.ProxyUsername != "" || test.req.ProxyPassword != "" { 144 user, pass, ok := parseBasicAuth(httpReq.Header.Get("Proxy-Authorization")) 145 assert.True(t, ok) 146 assert.Equal(t, test.req.ProxyUsername, user) 147 assert.Equal(t, test.req.ProxyPassword, pass) 148 } 149 150 for k, v := range test.req.Headers { 151 switch k { 152 case "host", "Host": 153 assert.Equal(t, httpReq.Host, v) 154 default: 155 assert.Equal(t, v, httpReq.Header.Get(k)) 156 } 157 } 158 }) 159 } 160 } 161 162 func parseBasicAuth(auth string) (username, password string, ok bool) { 163 const prefix = "Basic " 164 if len(auth) < len(prefix) || !strings.EqualFold(auth[:len(prefix)], prefix) { 165 return "", "", false 166 } 167 168 decoded, err := base64.StdEncoding.DecodeString(auth[len(prefix):]) 169 if err != nil { 170 return "", "", false 171 } 172 173 decodedStr := string(decoded) 174 idx := strings.IndexByte(decodedStr, ':') 175 if idx < 0 { 176 return "", "", false 177 } 178 179 return decodedStr[:idx], decodedStr[idx+1:], true 180 }