github.com/GuanceCloud/cliutils@v1.1.21/dialtesting/http_test.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package dialtesting
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"io"
    12  	"net/http"
    13  	"net/http/httptest"
    14  	"net/http/httputil"
    15  	"net/url"
    16  	"strings"
    17  	"testing"
    18  	"time"
    19  
    20  	"github.com/GuanceCloud/cliutils"
    21  	"github.com/gin-gonic/gin"
    22  )
    23  
    24  func getHttpCases(httpServer, httpsServer, proxyServer *httptest.Server) []struct {
    25  	t         *HTTPTask
    26  	fail      bool
    27  	reasonCnt int
    28  } {
    29  	return []struct {
    30  		t         *HTTPTask
    31  		fail      bool
    32  		reasonCnt int
    33  	}{
    34  		{
    35  			fail:      false,
    36  			reasonCnt: 0,
    37  			t: &HTTPTask{
    38  				ExternalID: cliutils.XID("dtst_"),
    39  				Method:     "GET",
    40  				URL:        fmt.Sprintf("%s/_test_no_resp", httpsServer.URL),
    41  				Name:       "_test_no_resp",
    42  				Region:     "hangzhou",
    43  				Frequency:  "1s",
    44  				AdvanceOptions: &HTTPAdvanceOption{
    45  					Certificate: &HTTPOptCertificate{
    46  						IgnoreServerCertificateError: true,
    47  						PrivateKey:                   string(tlsData["key"]),
    48  						Certificate:                  string(tlsData["crt"]),
    49  					},
    50  					Secret: &HTTPSecret{
    51  						NoSaveResponseBody: true,
    52  					},
    53  				},
    54  
    55  				SuccessWhen: []*HTTPSuccess{
    56  					{
    57  						StatusCode: []*SuccessOption{
    58  							{Is: "200"},
    59  						},
    60  					},
    61  				},
    62  			},
    63  		},
    64  
    65  		// test dial with certificate
    66  		{
    67  			fail:      false,
    68  			reasonCnt: 0,
    69  			t: &HTTPTask{
    70  				ExternalID: cliutils.XID("dtst_"),
    71  				Method:     "GET",
    72  				URL:        fmt.Sprintf("%s/_test_with_cert", httpsServer.URL),
    73  				Name:       "_test_with_cert",
    74  				Region:     "hangzhou",
    75  				Frequency:  "1s",
    76  				AdvanceOptions: &HTTPAdvanceOption{
    77  					Certificate: &HTTPOptCertificate{
    78  						IgnoreServerCertificateError: true,
    79  						PrivateKey:                   string(tlsData["key"]),
    80  						Certificate:                  string(tlsData["crt"]),
    81  					},
    82  				},
    83  
    84  				SuccessWhen: []*HTTPSuccess{
    85  					{
    86  						StatusCode: []*SuccessOption{
    87  							{Is: "200"},
    88  						},
    89  					},
    90  				},
    91  			},
    92  		},
    93  		{
    94  			fail:      true,
    95  			reasonCnt: 0,
    96  			t: &HTTPTask{
    97  				ExternalID: cliutils.XID("dtst_"),
    98  				Method:     "GET",
    99  				URL:        fmt.Sprintf("%s/_test_with_cert", httpsServer.URL),
   100  				Name:       "_test_with_cert",
   101  				Region:     "hangzhou",
   102  				Frequency:  "1s",
   103  				AdvanceOptions: &HTTPAdvanceOption{
   104  					Certificate: &HTTPOptCertificate{
   105  						IgnoreServerCertificateError: false, // bad certificate, expect fail
   106  						PrivateKey:                   string(tlsData["key"]),
   107  						Certificate:                  string(tlsData["crt"]),
   108  					},
   109  				},
   110  
   111  				SuccessWhen: []*HTTPSuccess{
   112  					{
   113  						StatusCode: []*SuccessOption{
   114  							{Is: "200"},
   115  						},
   116  					},
   117  				},
   118  			},
   119  		},
   120  
   121  		// test dial with proxy
   122  		{
   123  			fail:      false,
   124  			reasonCnt: 0,
   125  			t: &HTTPTask{
   126  				ExternalID: cliutils.XID("dtst_"),
   127  				Method:     "POST",
   128  				URL:        fmt.Sprintf("%s/_test_with_proxy", httpServer.URL),
   129  				Name:       "_test_with_proxy",
   130  				Region:     "hangzhou",
   131  				Frequency:  "1s",
   132  				AdvanceOptions: &HTTPAdvanceOption{
   133  					Proxy: &HTTPOptProxy{
   134  						URL:     proxyServer.URL,
   135  						Headers: map[string]string{"X-proxy-header": "proxy-foo"},
   136  					},
   137  				},
   138  
   139  				SuccessWhen: []*HTTPSuccess{
   140  					{
   141  						StatusCode: []*SuccessOption{
   142  							{Is: "200"},
   143  						},
   144  					},
   145  				},
   146  			},
   147  		},
   148  
   149  		// test dial with body
   150  		{
   151  			fail:      true,
   152  			reasonCnt: 0,
   153  			t: &HTTPTask{
   154  				ExternalID: cliutils.XID("dtst_"),
   155  				Method:     "POST",
   156  				URL:        fmt.Sprintf("%s/_test_with_body", httpServer.URL),
   157  				Name:       "_test_with_body",
   158  				Region:     "hangzhou",
   159  				Frequency:  "1s",
   160  				AdvanceOptions: &HTTPAdvanceOption{
   161  					RequestBody: &HTTPOptBody{
   162  						BodyType: "application/unknown", // XXX: invalid body type
   163  						Body:     `{"key": "value"}`,
   164  					},
   165  				},
   166  
   167  				SuccessWhen: []*HTTPSuccess{
   168  					{
   169  						StatusCode: []*SuccessOption{
   170  							{Is: "200"},
   171  						},
   172  					},
   173  				},
   174  			},
   175  		},
   176  
   177  		{
   178  			reasonCnt: 0,
   179  			t: &HTTPTask{
   180  				ExternalID: cliutils.XID("dtst_"),
   181  				Method:     "POST",
   182  				URL:        fmt.Sprintf("%s/_test_with_body", httpServer.URL),
   183  				Name:       "_test_with_body",
   184  				Region:     "hangzhou",
   185  				Frequency:  "1s",
   186  				AdvanceOptions: &HTTPAdvanceOption{
   187  					RequestBody: &HTTPOptBody{
   188  						BodyType: "None", // "application/json",
   189  						Body:     `{"key": "value"}`,
   190  					},
   191  				},
   192  
   193  				SuccessWhen: []*HTTPSuccess{
   194  					{
   195  						StatusCode: []*SuccessOption{
   196  							{Is: "200"},
   197  						},
   198  					},
   199  				},
   200  			},
   201  		},
   202  
   203  		// test dial with headers
   204  		{
   205  			reasonCnt: 0,
   206  			t: &HTTPTask{
   207  				ExternalID: cliutils.XID("dtst_"),
   208  				Method:     "GET",
   209  				URL:        fmt.Sprintf("%s/_test_with_headers", httpServer.URL),
   210  				Name:       "_test_with_headers",
   211  				Region:     "hangzhou",
   212  				Frequency:  "1s",
   213  				AdvanceOptions: &HTTPAdvanceOption{
   214  					RequestOptions: &HTTPOptRequest{
   215  						Headers: map[string]string{
   216  							"X-Header-1": "foo",
   217  							"X-Header-2": "bar",
   218  						},
   219  					},
   220  				},
   221  
   222  				SuccessWhen: []*HTTPSuccess{
   223  					{
   224  						StatusCode: []*SuccessOption{
   225  							{Is: "200"},
   226  						},
   227  					},
   228  				},
   229  			},
   230  		},
   231  
   232  		// test dial with auth
   233  		{
   234  			reasonCnt: 0,
   235  			t: &HTTPTask{
   236  				ExternalID: cliutils.XID("dtst_"),
   237  				Method:     "GET",
   238  				URL:        fmt.Sprintf("%s/_test_with_basic_auth", httpServer.URL),
   239  				Name:       "_test_with_basic_auth",
   240  				Region:     "hangzhou",
   241  				Frequency:  "1s",
   242  				AdvanceOptions: &HTTPAdvanceOption{
   243  					RequestOptions: &HTTPOptRequest{
   244  						Auth: &HTTPOptAuth{
   245  							Username: "foo",
   246  							Password: "bar",
   247  						},
   248  					},
   249  				},
   250  
   251  				SuccessWhen: []*HTTPSuccess{
   252  					{
   253  						StatusCode: []*SuccessOption{
   254  							{Is: "200"},
   255  						},
   256  					},
   257  				},
   258  			},
   259  		},
   260  
   261  		// test dial with cookie
   262  		{
   263  			reasonCnt: 0,
   264  			t: &HTTPTask{
   265  				ExternalID: cliutils.XID("dtst_"),
   266  				Method:     "GET",
   267  				URL:        fmt.Sprintf("%s/_test_with_cookie", httpServer.URL),
   268  				Name:       "_test_with_cookie",
   269  				Region:     "hangzhou",
   270  				Frequency:  "1s",
   271  				AdvanceOptions: &HTTPAdvanceOption{
   272  					RequestOptions: &HTTPOptRequest{
   273  						Cookies: (&http.Cookie{
   274  							Name:   "_test_with_cookie",
   275  							Value:  "foo-bar",
   276  							MaxAge: 0,
   277  							Secure: true,
   278  						}).String(),
   279  					},
   280  				},
   281  
   282  				SuccessWhen: []*HTTPSuccess{
   283  					{
   284  						StatusCode: []*SuccessOption{
   285  							{Is: "200"},
   286  						},
   287  					},
   288  				},
   289  			},
   290  		},
   291  
   292  		// test dial for redirect
   293  		{
   294  			reasonCnt: 0,
   295  			t: &HTTPTask{
   296  				ExternalID: cliutils.XID("dtst_"),
   297  				Method:     "GET",
   298  				URL:        fmt.Sprintf("%s/_test_redirect", httpServer.URL),
   299  				Name:       "_test_redirect",
   300  				Region:     "hangzhou",
   301  				Frequency:  "1s",
   302  				AdvanceOptions: &HTTPAdvanceOption{
   303  					RequestOptions: &HTTPOptRequest{FollowRedirect: true},
   304  				},
   305  
   306  				SuccessWhen: []*HTTPSuccess{
   307  					{
   308  						StatusCode: []*SuccessOption{
   309  							{Is: "200"}, // allow redirect, should be 200
   310  						},
   311  					},
   312  				},
   313  			},
   314  		},
   315  
   316  		{
   317  			reasonCnt: 0,
   318  			t: &HTTPTask{
   319  				ExternalID: cliutils.XID("dtst_"),
   320  				Method:     "GET",
   321  				URL:        fmt.Sprintf("%s/_test_redirect", httpServer.URL),
   322  				Name:       "_test_redirect_disabled",
   323  				Region:     "hangzhou",
   324  				Frequency:  "1s",
   325  				AdvanceOptions: &HTTPAdvanceOption{
   326  					RequestOptions: &HTTPOptRequest{FollowRedirect: false},
   327  				},
   328  
   329  				SuccessWhen: []*HTTPSuccess{
   330  					{
   331  						StatusCode: []*SuccessOption{
   332  							{Is: "302"}, // disabled redirect, should be 302
   333  						},
   334  					},
   335  				},
   336  			},
   337  		},
   338  
   339  		{
   340  			reasonCnt: 1,
   341  			fail:      true,
   342  			t: &HTTPTask{
   343  				ExternalID: cliutils.XID("dtst_"),
   344  				Method:     "GET",
   345  				URL:        fmt.Sprintf("%s/_test_http_timeout", httpServer.URL),
   346  				Name:       "_test_http_timeout_failed",
   347  				Region:     "hangzhou",
   348  				Frequency:  "1s",
   349  				AdvanceOptions: &HTTPAdvanceOption{
   350  					RequestTimeout: "1ms",
   351  				},
   352  				SuccessWhen: []*HTTPSuccess{
   353  					{
   354  						StatusCode: []*SuccessOption{
   355  							{Is: "200"},
   356  						},
   357  					},
   358  				},
   359  			},
   360  		},
   361  
   362  		{
   363  			reasonCnt: 0,
   364  			fail:      true,
   365  			t: &HTTPTask{
   366  				ExternalID: cliutils.XID("dtst_"),
   367  				Method:     "GET",
   368  				URL:        fmt.Sprintf("%s/_test_http_timeout", httpServer.URL),
   369  				Name:       "_test_http_timeout_ok",
   370  				Region:     "hangzhou",
   371  				Frequency:  "1s",
   372  				AdvanceOptions: &HTTPAdvanceOption{
   373  					RequestTimeout: "1s",
   374  				},
   375  				SuccessWhen: []*HTTPSuccess{
   376  					{
   377  						StatusCode: []*SuccessOption{
   378  							{Is: "200"},
   379  						},
   380  					},
   381  				},
   382  			},
   383  		},
   384  
   385  		// test dial with response time checking
   386  		{
   387  			reasonCnt: 1,
   388  			t: &HTTPTask{
   389  				ExternalID: cliutils.XID("dialt_"),
   390  				Method:     "GET",
   391  				URL:        fmt.Sprintf("%s/_test_resp_time_less_10ms", httpServer.URL),
   392  				Name:       "_test_resp_time_less_10ms",
   393  				Frequency:  "1s",
   394  				Region:     "hangzhou",
   395  				SuccessWhen: []*HTTPSuccess{
   396  					{ResponseTime: "10ms"},
   397  				},
   398  			},
   399  		},
   400  
   401  		// test dial with response headers
   402  		{
   403  			reasonCnt: 2,
   404  			t: &HTTPTask{
   405  				ExternalID: cliutils.XID("dtst_"),
   406  				Method:     "GET",
   407  				URL:        fmt.Sprintf("%s/_test_resp_time_less_10ms", httpServer.URL),
   408  				Name:       "_test_header_checking",
   409  				Region:     "hangzhou",
   410  				Frequency:  "1s",
   411  				SuccessWhen: []*HTTPSuccess{
   412  					{
   413  						Header: map[string][]*SuccessOption{
   414  							"Cache-Control": {
   415  								{MatchRegex: `max-ag=\d`}, // expect fail: max-age
   416  							},
   417  							"Server": {
   418  								{Is: `Apache`}, // expect fail
   419  							},
   420  
   421  							"Date": {
   422  								{Contains: "GMT"}, // ok: Date always use GMT
   423  							},
   424  							"NotExistHeader1": {
   425  								{NotMatchRegex: `.+`}, // ok
   426  							},
   427  							"NotExistHeader2": {
   428  								{IsNot: `abc`}, // ok
   429  							},
   430  							"NotExistHeader3": {
   431  								{NotContains: `def`}, // ok
   432  							},
   433  						},
   434  					},
   435  				},
   436  			},
   437  		},
   438  	}
   439  }
   440  
   441  func TestDialHTTP(t *testing.T) {
   442  	createServer := func(proxyServer *httptest.Server, isHttps bool) *httptest.Server {
   443  		gin.SetMode(gin.ReleaseMode)
   444  
   445  		r := gin.New()
   446  		gin.DisableConsoleColor()
   447  		r.Use(gin.Recovery())
   448  
   449  		addTestingRoutes(t, r, proxyServer, isHttps)
   450  
   451  		if isHttps {
   452  			return httptest.NewTLSServer(r)
   453  		} else {
   454  			return httptest.NewServer(r)
   455  		}
   456  	}
   457  
   458  	proxyServer := proxyServer(t)
   459  	httpServer := createServer(proxyServer, false) // http server
   460  	httpsServer := createServer(proxyServer, true) // https server
   461  
   462  	defer httpServer.Close()
   463  	defer httpsServer.Close()
   464  	defer proxyServer.Close()
   465  
   466  	httpCases := getHttpCases(httpServer, httpsServer, proxyServer)
   467  
   468  	for _, c := range httpCases {
   469  		if err := c.t.Init(); err != nil {
   470  			if c.fail == false {
   471  				t.Errorf("case %s failed: %s", c.t.Name, err)
   472  			} else {
   473  				t.Logf("expected: %s", err.Error())
   474  			}
   475  			continue
   476  		}
   477  
   478  		if err := c.t.Run(); err != nil {
   479  			if c.fail == false {
   480  				t.Errorf("case %s failed: %s", c.t.Name, err)
   481  			} else {
   482  				t.Logf("expected: %s", err.Error())
   483  			}
   484  			continue
   485  		}
   486  
   487  		ts, fs := c.t.GetResults()
   488  
   489  		t.Logf("ts: %+#v \n fs: %+#v \n ", ts, fs)
   490  
   491  		reasons, _ := c.t.CheckResult()
   492  		if len(reasons) != c.reasonCnt {
   493  			t.Errorf("case %s expect %d reasons, but got %d reasons:\n\t%s",
   494  				c.t.Name, c.reasonCnt, len(reasons), strings.Join(reasons, "\n\t"))
   495  		} else if len(reasons) > 0 {
   496  			t.Logf("case %s reasons:\n\t%s",
   497  				c.t.Name, strings.Join(reasons, "\n\t"))
   498  		}
   499  	}
   500  }
   501  
   502  func proxyServer(t *testing.T) *httptest.Server {
   503  	t.Helper()
   504  	return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
   505  		t.Logf("proxied request coming")
   506  		for k := range req.Header {
   507  			t.Logf("proxied header: %s: %s", k, req.Header.Get(k))
   508  		}
   509  
   510  		fmt.Fprintf(w, "ok")
   511  	}))
   512  }
   513  
   514  func proxyHandler(t *testing.T, target string) gin.HandlerFunc {
   515  	t.Helper()
   516  	remote, err := url.Parse(target)
   517  	if err != nil {
   518  		t.Error(err)
   519  		return nil
   520  	}
   521  
   522  	return func(c *gin.Context) {
   523  		director := func(_ *http.Request) {
   524  			req := c.Request
   525  
   526  			req.URL.Scheme = remote.Scheme
   527  			req.URL.Host = remote.Host
   528  			req.URL.RawQuery = remote.RawQuery
   529  
   530  			req.Header["X-proxy-header"] = []string{c.Request.Header.Get("X-proxy-header")}
   531  			delete(req.Header, "X-proxy-header")
   532  		}
   533  		proxy := &httputil.ReverseProxy{Director: director}
   534  		proxy.ServeHTTP(c.Writer, c.Request)
   535  	}
   536  }
   537  
   538  var tlsData = map[string][]byte{
   539  	"csr": []byte(`-----BEGIN CERTIFICATE REQUEST-----
   540  MIICtzCCAZ8CAQAwcjELMAkGA1UEBhMCQ04xDDAKBgNVBAgMA2ZvbzEMMAoGA1UE
   541  BwwDYmFyMQ0wCwYDVQQKDARmb28xMQ0wCwYDVQQLDARiYXIxMQ0wCwYDVQQDDARm
   542  b28yMRowGAYJKoZIhvcNAQkBFgtmb29AYmFyLmNvbTCCASIwDQYJKoZIhvcNAQEB
   543  BQADggEPADCCAQoCggEBANEQvuwHLDTsu+QuIEXc4R8aTSFTgFl0CPz3GzAhZnYt
   544  /MgZ66iu6W7FplTiqIPoSgTqccCcWPlOgaad0BfkmbuYaoo9SiF5/ewip6QXfpBQ
   545  Va34Q92E3EfBv5vyuCgMyNbjXb+hHbRvYmgOUeL0J9jRMJ1l981pgYgjGdzNFJTz
   546  S2FDVoaoexOkoOXblAI9tqbBi+9+Sbu7Q/DgeudeF07VmI+cZzZX73Oo2EzwHHXn
   547  FI5OAbRBjKsQyU9O6TgarA/5n0hAH2bcHkoCxq4iVgHuZjK2xV8hJU8b4jGevDVE
   548  TCwE07LJJfP2RnlYe7nBqNlNXApMSllUgX4c8RhUuQ0CAwEAAaAAMA0GCSqGSIb3
   549  DQEBCwUAA4IBAQC4Z2ELAmnrPSoghuEyKuM2GsvRqOIUHKKwM/lCWxOE/o/pQDTY
   550  OcC+2BwSimChoBd1TY3vM03TYxzY5jlHqfwLAFqJv51DFlTasHUhlo8+7IVR+6TE
   551  WH9latBruNVSDZ5/qL1dfbLoBw6yyQi4kYdSg1T5CBtGVCe3iBC42NmXHqp5/XXB
   552  dQAILNu1lzVi4dM6FbHcr6FTSZBIyYrHTYLPIj4aUQ/p5iO1jYvfM8DiXR0OWfzw
   553  VFjOt6N0pYsfLgeOHA8v6NZMQ+N59Ne0Dl7Pg7bK56qP+l0R2hY0smXH/IPrGaFF
   554  Qf01BfPoTUfoyV195ZF8BpeVtT1HBs3of/+6
   555  -----END CERTIFICATE REQUEST-----`),
   556  	"crt": []byte(`-----BEGIN CERTIFICATE-----
   557  MIIDYDCCAkgCCQCgwJeKz0Yl5jANBgkqhkiG9w0BAQUFADByMQswCQYDVQQGEwJD
   558  TjEMMAoGA1UECAwDZm9vMQwwCgYDVQQHDANiYXIxDTALBgNVBAoMBGZvbzExDTAL
   559  BgNVBAsMBGJhcjExDTALBgNVBAMMBGZvbzIxGjAYBgkqhkiG9w0BCQEWC2Zvb0Bi
   560  YXIuY29tMB4XDTIxMDIyMjA0MDAwNloXDTIyMDIyMjA0MDAwNlowcjELMAkGA1UE
   561  BhMCQ04xDDAKBgNVBAgMA2ZvbzEMMAoGA1UEBwwDYmFyMQ0wCwYDVQQKDARmb28x
   562  MQ0wCwYDVQQLDARiYXIxMQ0wCwYDVQQDDARmb28yMRowGAYJKoZIhvcNAQkBFgtm
   563  b29AYmFyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANEQvuwH
   564  LDTsu+QuIEXc4R8aTSFTgFl0CPz3GzAhZnYt/MgZ66iu6W7FplTiqIPoSgTqccCc
   565  WPlOgaad0BfkmbuYaoo9SiF5/ewip6QXfpBQVa34Q92E3EfBv5vyuCgMyNbjXb+h
   566  HbRvYmgOUeL0J9jRMJ1l981pgYgjGdzNFJTzS2FDVoaoexOkoOXblAI9tqbBi+9+
   567  Sbu7Q/DgeudeF07VmI+cZzZX73Oo2EzwHHXnFI5OAbRBjKsQyU9O6TgarA/5n0hA
   568  H2bcHkoCxq4iVgHuZjK2xV8hJU8b4jGevDVETCwE07LJJfP2RnlYe7nBqNlNXApM
   569  SllUgX4c8RhUuQ0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAn8TzH9LvNyhH+cqa
   570  gRc8Gqj0ccPf1LkW9dIlTlk31HBHzfKI7xhul23PimMuz6hg3YCAttXhKXrVoiIJ
   571  1rQUngGr0e2CkesxfeaMxDPPRCRiLPRLzsryjvJI/eS2rmxtmUyC0X5aR+/2F8Ha
   572  p2JXig4KUhYwMmttnd/Qbjmc0C397zKudBxkIoxprIN/gVhRBJJRqxN8bgeL8JsH
   573  2HfsA/SzFDUOYPQhw0EnyLukRuQi0C3soKL4fIUGqonJPQ0TIceJRMGrtIj0h7j+
   574  oNbJXTP7ABRYVmFRYViczu86MWsbHkif4bWqhPJeC0K+cp1UuwykJ+4XzM5WDR/+
   575  InEHyg==
   576  -----END CERTIFICATE-----`),
   577  
   578  	"key": []byte(`-----BEGIN PRIVATE KEY-----
   579  MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDREL7sByw07Lvk
   580  LiBF3OEfGk0hU4BZdAj89xswIWZ2LfzIGeuoruluxaZU4qiD6EoE6nHAnFj5ToGm
   581  ndAX5Jm7mGqKPUohef3sIqekF36QUFWt+EPdhNxHwb+b8rgoDMjW412/oR20b2Jo
   582  DlHi9CfY0TCdZffNaYGIIxnczRSU80thQ1aGqHsTpKDl25QCPbamwYvvfkm7u0Pw
   583  4HrnXhdO1ZiPnGc2V+9zqNhM8Bx15xSOTgG0QYyrEMlPTuk4GqwP+Z9IQB9m3B5K
   584  AsauIlYB7mYytsVfISVPG+Ixnrw1REwsBNOyySXz9kZ5WHu5wajZTVwKTEpZVIF+
   585  HPEYVLkNAgMBAAECggEAJp/9ZgX9ONnz7LhI5h9kyCZH0bxnnh89+d59e2rwTy03
   586  4pBHZabLIdgKXuxxTc2Av1/BHGDGX2kNswa9B20IqgwCwv+Hzp+HNjVA26QrkeYF
   587  rlqLz0VYnTlCeUFinKOgB3OCQoE1x7w8ZhUfM9r/8aLUZIAORDkV4Vz6zjxlbQ8g
   588  JxHrZ5eZexTzSVylVFZda3AgtqMr1N6ZzMejtYqttGGDDmh372QgykvxhmEIeHAf
   589  g1bW86oOedxxfZ0003/F9He6qvdWmAKfbQczCNKBPHgGpdcuTTBsj/ieB/31AZG9
   590  R1CUopzAklrUXzv1SBxw/5mJdOcmTUH4Hpdl4vXh0QKBgQD99FiKIKRxWZiHcbV4
   591  X2wl0AZsMUbUT+BVKRbdfYk0pTstSKaQMpEB2ojvVqW8HVN83+jJxWUxxGWnT0Mn
   592  wfw9lavhNS14klj+rJw6zI4m2lcI8t+P9HxTMDfBU+LiMnlUFK44u7Mx6Vr/dm9p
   593  53o0aGapLOQfwps+UdJ86ZCAKwKBgQDSv9az1zHE1AtJx7UlreduzXrYjzJqrgYX
   594  ufjLu+aTsSWNXIlIxG5gkKbkF6R4VVmpXkF7B8nJ3IrsrRuwMZpMjyhLl2LLCnGL
   595  XgAgz/SNjxS4Clo1PVcP2ZoANVnPs/+DRlI1aTqXHZA5sJ1d2a9e385ndZ+/Qg+q
   596  giRNOsfXpwKBgQC2dwnmtO1yQ93D839frbAWuxDiS8WIZpvYlF1JZxleKhoKv1ht
   597  4uctXcdlr+wE7U0/O+IWly3ORD6Fp/2oY0jJNvD4Ly0spHotAfh+htrcL6S5WUgo
   598  NpHdc5eb4JnzzDBAqVtEiBiIlBI92urSPO8hGKIqi4adC0Zf0IpcFbUtYQKBgF24
   599  Iepn0CIPidWNkejnpPuJNRAI3grCyMLUWOeA79DN/j0W4ZYShGM88HqOaP16Nx0y
   600  ZTwpAntaMA2ADcgUxuE06F51O+G/Cy9G5hexYrdw4W3WbLcwR/8sbWeaUg4jpYTj
   601  SLunx/5bjz+YYuLRY0N1k3w+uoN7BSx2I16UvToRAoGAEFhhsGTxXLeNOMDU1jhJ
   602  cbbypRkGjSoxUbn7apEMwdpeDPQwWwkwi634rjVcTIQuO/8HMbjZi2AZcM5TWNY0
   603  HHrpiTXtbrUfbKX2TEk3DSevJ9EZEuewxALtsaRQgX4WyHlxpYDXNSjag04Nn+/x
   604  9WKHZvRf3lbLY7GAR/emacU=
   605  -----END PRIVATE KEY-----`),
   606  }
   607  
   608  func addTestingRoutes(t *testing.T, r *gin.Engine, proxyServer *httptest.Server, isHttps bool) {
   609  	t.Helper()
   610  	r.GET("/_test_resp_time_less_10ms", func(c *gin.Context) {
   611  		time.Sleep(time.Millisecond * 11)
   612  		c.Data(http.StatusOK, ``, nil)
   613  	})
   614  
   615  	r.GET("/_test_header_checking", func(c *gin.Context) {
   616  		c.DataFromReader(http.StatusOK, 0, "", bytes.NewBuffer([]byte("")),
   617  			map[string]string{
   618  				"Cache-Control": "max-age=1024",
   619  				"Server":        "dialtesting-server",
   620  			})
   621  	})
   622  
   623  	r.GET("/_test_redirect", func(c *gin.Context) {
   624  		c.Redirect(http.StatusFound, "/_redirect_to_me")
   625  	})
   626  	r.GET("/_redirect_to_me", func(c *gin.Context) {
   627  		t.Log("redirect ok")
   628  		c.Data(http.StatusOK, ``, nil)
   629  	})
   630  
   631  	r.GET("/_test_with_cookie", func(c *gin.Context) {
   632  		cookies := c.Request.Cookies()
   633  		for _, c := range cookies {
   634  			t.Logf("%s", c.String())
   635  		}
   636  
   637  		c.Data(http.StatusOK, ``, nil)
   638  	})
   639  
   640  	r.GET("/_test_with_basic_auth", func(c *gin.Context) {
   641  		user, pwd, ok := c.Request.BasicAuth()
   642  		if !ok {
   643  			t.Errorf("basic auth failed")
   644  		} else {
   645  			t.Logf("user: %s, password: %s", user, pwd)
   646  		}
   647  
   648  		c.Data(http.StatusOK, ``, nil)
   649  	})
   650  
   651  	r.GET("/_test_no_resp", func(c *gin.Context) {
   652  		c.Data(http.StatusOK, string(tlsData["key"]), nil)
   653  	})
   654  
   655  	r.GET("/_test_with_headers", func(c *gin.Context) {
   656  		for k := range c.Request.Header {
   657  			t.Logf("%s: %s", k, c.Request.Header.Get(k))
   658  		}
   659  
   660  		c.Data(http.StatusOK, ``, nil)
   661  	})
   662  
   663  	r.GET("/_test_http_timeout", func(c *gin.Context) {
   664  		time.Sleep(10 * time.Millisecond)
   665  		c.Data(http.StatusOK, "", nil)
   666  	})
   667  
   668  	r.POST("/_test_with_body", func(c *gin.Context) {
   669  		defer c.Request.Body.Close() //nolint:errcheck
   670  		body, err := io.ReadAll(c.Request.Body)
   671  		if err != nil {
   672  			t.Error(err)
   673  		}
   674  
   675  		t.Logf("body: %s", string(body))
   676  
   677  		c.Data(http.StatusOK, ``, nil)
   678  	})
   679  
   680  	r.GET("/_test_with_proxy",
   681  		proxyHandler(t, fmt.Sprintf("%s/_test_with_proxy", proxyServer.URL)))
   682  
   683  	if isHttps {
   684  		r.GET("/_test_with_cert", func(c *gin.Context) {
   685  			t.Logf("request tls: %+#v", c.Request.TLS)
   686  			c.Data(http.StatusOK, ``, nil)
   687  		})
   688  	}
   689  }