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  }