github.com/waldiirawan/apm-agent-go/v2@v2.2.2/internal/apmhttputil/url_test.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package apmhttputil_test
    19  
    20  import (
    21  	"crypto/tls"
    22  	"encoding/json"
    23  	"net/http"
    24  	"testing"
    25  
    26  	"github.com/stretchr/testify/assert"
    27  
    28  	"github.com/waldiirawan/apm-agent-go/v2/internal/apmhttputil"
    29  	"github.com/waldiirawan/apm-agent-go/v2/model"
    30  	"go.elastic.co/fastjson"
    31  )
    32  
    33  func TestRequestURLClient(t *testing.T) {
    34  	req := mustNewRequest("https://user:pass@host.invalid:9443/path?query&querier=foo#fragment")
    35  	assert.Equal(t, model.URL{
    36  		Protocol: "https",
    37  		Hostname: "host.invalid",
    38  		Port:     "9443",
    39  		Path:     "/path",
    40  		Search:   "query&querier=foo",
    41  		Hash:     "fragment",
    42  	}, apmhttputil.RequestURL(req))
    43  }
    44  
    45  func TestRequestURLServer(t *testing.T) {
    46  	req := mustNewRequest("/path?query&querier=foo")
    47  	req.Host = "host.invalid:8080"
    48  
    49  	assert.Equal(t, model.URL{
    50  		Protocol: "http",
    51  		Hostname: "host.invalid",
    52  		Port:     "8080",
    53  		Path:     "/path",
    54  		Search:   "query&querier=foo",
    55  	}, apmhttputil.RequestURL(req))
    56  }
    57  
    58  func TestRequestURLServerTLS(t *testing.T) {
    59  	req := mustNewRequest("/path?query&querier=foo")
    60  	req.Host = "host.invalid:8080"
    61  	req.TLS = &tls.ConnectionState{}
    62  	assert.Equal(t, "https", apmhttputil.RequestURL(req).Protocol)
    63  }
    64  
    65  func TestRequestURLHeaders(t *testing.T) {
    66  	type test struct {
    67  		name   string
    68  		full   string
    69  		header http.Header
    70  	}
    71  
    72  	tests := []test{{
    73  		name:   "Forwarded",
    74  		full:   "https://forwarded.invalid:443/",
    75  		header: http.Header{"Forwarded": []string{"Host=\"forwarded.invalid:443\"; proto=HTTPS"}},
    76  	}, {
    77  		name:   "Forwarded-Empty-Host",
    78  		full:   "http://host.invalid/", // falls back to the next option
    79  		header: http.Header{"Forwarded": []string{""}},
    80  	}, {
    81  		name:   "X-Forwarded-Host",
    82  		full:   "http://x-forwarded-host.invalid/",
    83  		header: http.Header{"X-Forwarded-Host": []string{"x-forwarded-host.invalid"}},
    84  	}, {
    85  		name:   "X-Forwarded-Proto",
    86  		full:   "https://host.invalid/",
    87  		header: http.Header{"X-Forwarded-Proto": []string{"https"}},
    88  	}, {
    89  		name:   "X-Forwarded-Protocol",
    90  		full:   "https://host.invalid/",
    91  		header: http.Header{"X-Forwarded-Protocol": []string{"https"}},
    92  	}, {
    93  		name:   "X-Url-Scheme",
    94  		full:   "https://host.invalid/",
    95  		header: http.Header{"X-Url-Scheme": []string{"https"}},
    96  	}, {
    97  		name:   "Front-End-Https",
    98  		full:   "https://host.invalid/",
    99  		header: http.Header{"Front-End-Https": []string{"on"}},
   100  	}, {
   101  		name:   "X-Forwarded-Ssl",
   102  		full:   "https://host.invalid/",
   103  		header: http.Header{"X-Forwarded-Ssl": []string{"on"}},
   104  	}}
   105  
   106  	for _, test := range tests {
   107  		t.Run(test.name, func(t *testing.T) {
   108  			req := mustNewRequest("/")
   109  			req.Host = "host.invalid"
   110  			req.Header = test.header
   111  
   112  			out := apmhttputil.RequestURL(req)
   113  
   114  			// Marshal the URL to gets its "full" representation.
   115  			var w fastjson.Writer
   116  			err := out.MarshalFastJSON(&w)
   117  			assert.NoError(t, err)
   118  
   119  			var decoded struct {
   120  				Full string
   121  			}
   122  			err = json.Unmarshal(w.Bytes(), &decoded)
   123  			assert.NoError(t, err)
   124  			assert.Equal(t, test.full, decoded.Full)
   125  		})
   126  	}
   127  }
   128  
   129  func mustNewRequest(url string) *http.Request {
   130  	req, err := http.NewRequest("GET", url, nil)
   131  	if err != nil {
   132  		panic(err)
   133  	}
   134  	return req
   135  }