github.com/gramework/gramework@v1.8.1-0.20231027140105-82555c9057f5/router_test.go (about)

     1  // Copyright 2017-present Kirill Danshin and Gramework contributors
     2  // Copyright 2019-present Highload LTD (UK CN: 11893420)
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  
    11  package gramework
    12  
    13  import (
    14  	"errors"
    15  	"fmt"
    16  	"net/http"
    17  	"reflect"
    18  	"runtime"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/gramework/gramework/x/testutils"
    23  
    24  	"github.com/valyala/fasthttp"
    25  )
    26  
    27  func TestGrameRouter(t *testing.T) {
    28  	app := New()
    29  	if h, _ := app.defaultRouter.Lookup("GET", "/", nil); h != nil {
    30  		t.Log("GET / should not return handler before registration")
    31  		t.FailNow()
    32  	}
    33  	app.GET("/", 1)
    34  	if h, _ := app.defaultRouter.Lookup("GET", "/", nil); h == nil {
    35  		t.Log("GET / should return handler after registration")
    36  		t.FailNow()
    37  	}
    38  	if h, _ := app.defaultRouter.Lookup("GET", "/abc", nil); h != nil {
    39  		t.Log("GET /abc should not return handler before registration")
    40  		t.FailNow()
    41  	}
    42  
    43  	app.GET("/abc", "abc")
    44  
    45  	if h, _ := app.defaultRouter.Lookup("GET", "/abc", nil); h == nil {
    46  		t.Log("GET /abc should return handler after registration")
    47  		t.FailNow()
    48  	}
    49  
    50  	app.GET("/redir", app.ToTLSHandler())
    51  
    52  	// POST
    53  
    54  	if h, _ := app.defaultRouter.Lookup("POST", "/", nil); h != nil {
    55  		fpc := runtime.FuncForPC(reflect.ValueOf(h).Pointer())
    56  		file, line := fpc.FileLine(fpc.Entry())
    57  		t.Logf("POST / should not return handler before registration, got %q (%v:%v)", fpc.Name(), file, line)
    58  		t.FailNow()
    59  	}
    60  	app.POST("/", 1)
    61  	if h, _ := app.defaultRouter.Lookup("POST", "/", nil); h == nil {
    62  		fpc := runtime.FuncForPC(reflect.ValueOf(h).Pointer())
    63  		file, line := fpc.FileLine(fpc.Entry())
    64  		t.Logf("POST / should return handler after registration, got %q (%v:%v)", fpc.Name(), file, line)
    65  		t.FailNow()
    66  	}
    67  	if h, _ := app.defaultRouter.Lookup("POST", "/abc", nil); h != nil {
    68  		fpc := runtime.FuncForPC(reflect.ValueOf(h).Pointer())
    69  		file, line := fpc.FileLine(fpc.Entry())
    70  		t.Logf("POST /abc should not return handler before registration, got %q (%v:%v)", fpc.Name(), file, line)
    71  		t.FailNow()
    72  	}
    73  
    74  	app.POST("/abc", "abc")
    75  
    76  	if h, _ := app.defaultRouter.Lookup("POST", "/abc", nil); h == nil {
    77  		t.Log("POST /abc should return handler after registration")
    78  		t.FailNow()
    79  	}
    80  
    81  	// PUT
    82  	if h, _ := app.defaultRouter.Lookup("PUT", "/", nil); h != nil {
    83  		t.Log("PUT / should not return handler before registration")
    84  		t.FailNow()
    85  	}
    86  	app.PUT("/", 1)
    87  	if h, _ := app.defaultRouter.Lookup("PUT", "/", nil); h == nil {
    88  		t.Log("PUT / should return handler after registration")
    89  		t.FailNow()
    90  	}
    91  	if h, _ := app.defaultRouter.Lookup("PUT", "/abc", nil); h != nil {
    92  		t.Log("PUT /abc should not return handler before registration")
    93  		t.FailNow()
    94  	}
    95  
    96  	app.PUT("/abc", "abc")
    97  
    98  	if h, _ := app.defaultRouter.Lookup("PUT", "/abc", nil); h == nil {
    99  		t.Log("PUT /abc should return handler after registration")
   100  		t.FailNow()
   101  	}
   102  
   103  	// DELETE
   104  	if h, _ := app.defaultRouter.Lookup("DELETE", "/", nil); h != nil {
   105  		t.Log("DELETE / should not return handler before registration")
   106  		t.FailNow()
   107  	}
   108  	app.DELETE("/", 1)
   109  	if h, _ := app.defaultRouter.Lookup("DELETE", "/", nil); h == nil {
   110  		t.Log("DELETE / should return handler after registration")
   111  		t.FailNow()
   112  	}
   113  	if h, _ := app.defaultRouter.Lookup("DELETE", "/abc", nil); h != nil {
   114  		t.Log("DELETE /abc should not return handler before registration")
   115  		t.FailNow()
   116  	}
   117  
   118  	app.DELETE("/abc", "abc")
   119  
   120  	if h, _ := app.defaultRouter.Lookup("DELETE", "/abc", nil); h == nil {
   121  		t.Log("DELETE /abc should return handler after registration")
   122  		t.FailNow()
   123  	}
   124  
   125  	// HEAD
   126  	if h, _ := app.defaultRouter.Lookup("HEAD", "/", nil); h != nil {
   127  		t.Log("HEAD / should not return handler before registration")
   128  		t.FailNow()
   129  	}
   130  	app.HEAD("/", 1)
   131  	if h, _ := app.defaultRouter.Lookup("HEAD", "/", nil); h == nil {
   132  		t.Log("HEAD / should return handler after registration")
   133  		t.FailNow()
   134  	}
   135  	if h, _ := app.defaultRouter.Lookup("HEAD", "/abc", nil); h != nil {
   136  		t.Log("HEAD /abc should not return handler before registration")
   137  		t.FailNow()
   138  	}
   139  
   140  	app.HEAD("/abc", "abc")
   141  
   142  	if h, _ := app.defaultRouter.Lookup("HEAD", "/abc", nil); h == nil {
   143  		t.Log("HEAD /abc should return handler after registration")
   144  		t.FailNow()
   145  	}
   146  
   147  	// OPTIONS
   148  	if h, _ := app.defaultRouter.Lookup("OPTIONS", "/", nil); h != nil {
   149  		t.Log("OPTIONS / should not return handler before registration")
   150  		t.FailNow()
   151  	}
   152  	app.OPTIONS("/", 1)
   153  	if h, _ := app.defaultRouter.Lookup("OPTIONS", "/", nil); h == nil {
   154  		t.Log("OPTIONS / should return handler after registration")
   155  		t.FailNow()
   156  	}
   157  	if h, _ := app.defaultRouter.Lookup("OPTIONS", "/abc", nil); h != nil {
   158  		t.Log("OPTIONS /abc should not return handler before registration")
   159  		t.FailNow()
   160  	}
   161  
   162  	app.OPTIONS("/abc", "abc")
   163  
   164  	if h, _ := app.defaultRouter.Lookup("OPTIONS", "/abc", nil); h == nil {
   165  		t.Log("OPTIONS /abc should return handler after registration")
   166  		t.FailNow()
   167  	}
   168  
   169  	// PATCH
   170  	if h, _ := app.defaultRouter.Lookup("PATCH", "/", nil); h != nil {
   171  		t.Log("PATCH / should not return handler before registration")
   172  		t.FailNow()
   173  	}
   174  	app.PATCH("/", 1)
   175  	if h, _ := app.defaultRouter.Lookup("PATCH", "/", nil); h == nil {
   176  		t.Log("PATCH / should return handler after registration")
   177  		t.FailNow()
   178  	}
   179  	if h, _ := app.defaultRouter.Lookup("PATCH", "/abc", nil); h != nil {
   180  		t.Log("PATCH /abc should not return handler before registration")
   181  		t.FailNow()
   182  	}
   183  
   184  	app.PATCH("/abc", "abc")
   185  
   186  	if h, _ := app.defaultRouter.Lookup("PATCH", "/abc", nil); h == nil {
   187  		t.Log("PATCH /abc should return handler after registration")
   188  		t.FailNow()
   189  	}
   190  
   191  	app.Sub("/abc").Handle("GET", "/def", "abcdef")
   192  
   193  	if h, _ := app.defaultRouter.Lookup("GET", "/abc/def", nil); h == nil {
   194  		t.Log("GET /abc/def should return handler after registration")
   195  		t.FailNow()
   196  	}
   197  
   198  	app.Handle("CONNECT", "/ws", "")
   199  	app.PanicHandler(nil)
   200  	app.NotFound(nil)
   201  	app.HandleMethodNotAllowed(true)
   202  	app.HandleOPTIONS(true)
   203  
   204  	ln, port := testutils.Port().NonRoot().Unused().AcquireListener()
   205  	bindAddr := fmt.Sprintf(":%d", port)
   206  	go func() {
   207  		err := app.Serve(ln)
   208  		if err != nil {
   209  			panic(err)
   210  		}
   211  	}()
   212  	time.Sleep(250 * time.Millisecond)
   213  	_, err := http.Get("http://127.0.0.1" + bindAddr) // just should not panic
   214  	if err != nil {
   215  		t.Error(err)
   216  	}
   217  }
   218  
   219  func TestSubRouter(t *testing.T) {
   220  	app := New()
   221  
   222  	app.Sub("/abc").Handle("GET", "/def", "abcdef")
   223  	if h, _ := app.defaultRouter.Lookup("GET", "/abc/def", nil); h == nil {
   224  		t.Log("GET /abc/def should return handler after registration")
   225  		t.FailNow()
   226  	}
   227  
   228  	app.Sub("/abc").Handle("GET", "/def2/", "abcdef")
   229  	if h, _ := app.defaultRouter.Lookup("GET", "/abc/def2", nil); h == nil {
   230  		t.Log("GET /abc/def should return handler after registration")
   231  		t.FailNow()
   232  	}
   233  
   234  	app.Sub("/cba").Handle("GET", "/def/:user", "abcdef")
   235  	if h, _ := app.defaultRouter.Lookup("GET", "/cba/def/usr", nil); h == nil {
   236  		t.Log("GET /cba/def/usr should return handler after registration")
   237  		t.FailNow()
   238  	}
   239  
   240  	app.Sub("/hello").Sub("/world").Handle("POST", "/def", "defdef")
   241  	if h, _ := app.defaultRouter.Lookup("POST", "/hello/world/def", nil); h == nil {
   242  		t.Log("GET /hello/world/def/usr should return handler after registration")
   243  		t.FailNow()
   244  	}
   245  
   246  	app.Sub("/hello").Sub("/world").Handle("POST", "/def/:user", "user")
   247  	if h, _ := app.defaultRouter.Lookup("POST", "/hello/world/def/usr", nil); h == nil {
   248  		t.Log("GET /hello/world/def/usr should return handler after registration")
   249  		t.FailNow()
   250  	}
   251  }
   252  
   253  func TestDomainRouter(t *testing.T) {
   254  	app := New()
   255  	r := app.Domain("example.com")
   256  	if h, _ := r.Lookup("GET", "/", nil); h != nil {
   257  		t.Log("GET / should not return handler before registration")
   258  		t.FailNow()
   259  	}
   260  	r.GET("/", 1)
   261  	if h, _ := r.Lookup("GET", "/", nil); h == nil {
   262  		t.Log("GET / should return handler after registration")
   263  		t.FailNow()
   264  	}
   265  	if h, _ := r.Lookup("GET", "/abc", nil); h != nil {
   266  		t.Log("GET /abc should not return handler before registration")
   267  		t.FailNow()
   268  	}
   269  
   270  	r.GET("/abc", "abc")
   271  
   272  	if h, _ := r.Lookup("GET", "/abc", nil); h == nil {
   273  		t.Log("GET /abc should return handler after registration")
   274  		t.FailNow()
   275  	}
   276  
   277  	r.GET("/redir", app.ToTLSHandler())
   278  
   279  	// POST
   280  
   281  	if h, _ := r.Lookup("POST", "/", nil); h != nil {
   282  		t.Log("POST / should not return handler before registration")
   283  		t.FailNow()
   284  	}
   285  	r.POST("/", 1)
   286  	if h, _ := r.Lookup("POST", "/", nil); h == nil {
   287  		t.Log("POST / should return handler after registration")
   288  		t.FailNow()
   289  	}
   290  	if h, _ := r.Lookup("POST", "/abc", nil); h != nil {
   291  		t.Log("POST /abc should not return handler before registration")
   292  		t.FailNow()
   293  	}
   294  
   295  	r.POST("/abc", "abc")
   296  
   297  	if h, _ := r.Lookup("POST", "/abc", nil); h == nil {
   298  		t.Log("POST /abc should return handler after registration")
   299  		t.FailNow()
   300  	}
   301  
   302  	// PUT
   303  	if h, _ := r.Lookup("PUT", "/", nil); h != nil {
   304  		t.Log("PUT / should not return handler before registration")
   305  		t.FailNow()
   306  	}
   307  	r.PUT("/", 1)
   308  	if h, _ := r.Lookup("PUT", "/", nil); h == nil {
   309  		t.Log("PUT / should return handler after registration")
   310  		t.FailNow()
   311  	}
   312  	if h, _ := r.Lookup("PUT", "/abc", nil); h != nil {
   313  		t.Log("PUT /abc should not return handler before registration")
   314  		t.FailNow()
   315  	}
   316  
   317  	r.PUT("/abc", "abc")
   318  
   319  	if h, _ := r.Lookup("PUT", "/abc", nil); h == nil {
   320  		t.Log("PUT /abc should return handler after registration")
   321  		t.FailNow()
   322  	}
   323  
   324  	// DELETE
   325  	if h, _ := r.Lookup("DELETE", "/", nil); h != nil {
   326  		t.Log("DELETE / should not return handler before registration")
   327  		t.FailNow()
   328  	}
   329  	r.DELETE("/", 1)
   330  	if h, _ := r.Lookup("DELETE", "/", nil); h == nil {
   331  		t.Log("DELETE / should return handler after registration")
   332  		t.FailNow()
   333  	}
   334  	if h, _ := r.Lookup("DELETE", "/abc", nil); h != nil {
   335  		t.Log("DELETE /abc should not return handler before registration")
   336  		t.FailNow()
   337  	}
   338  
   339  	r.DELETE("/abc", "abc")
   340  
   341  	if h, _ := r.Lookup("DELETE", "/abc", nil); h == nil {
   342  		t.Log("DELETE /abc should return handler after registration")
   343  		t.FailNow()
   344  	}
   345  
   346  	// HEAD
   347  	if h, _ := r.Lookup("HEAD", "/", nil); h != nil {
   348  		t.Log("HEAD / should not return handler before registration")
   349  		t.FailNow()
   350  	}
   351  	r.HEAD("/", 1)
   352  	if h, _ := r.Lookup("HEAD", "/", nil); h == nil {
   353  		t.Log("HEAD / should return handler after registration")
   354  		t.FailNow()
   355  	}
   356  	if h, _ := r.Lookup("HEAD", "/abc", nil); h != nil {
   357  		t.Log("HEAD /abc should not return handler before registration")
   358  		t.FailNow()
   359  	}
   360  
   361  	r.HEAD("/abc", "abc")
   362  
   363  	if h, _ := r.Lookup("HEAD", "/abc", nil); h == nil {
   364  		t.Log("HEAD /abc should return handler after registration")
   365  		t.FailNow()
   366  	}
   367  
   368  	// OPTIONS
   369  	if h, _ := r.Lookup("OPTIONS", "/", nil); h != nil {
   370  		t.Log("OPTIONS / should not return handler before registration")
   371  		t.FailNow()
   372  	}
   373  	r.OPTIONS("/", 1)
   374  	if h, _ := r.Lookup("OPTIONS", "/", nil); h == nil {
   375  		t.Log("OPTIONS / should return handler after registration")
   376  		t.FailNow()
   377  	}
   378  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h != nil {
   379  		t.Log("OPTIONS /abc should not return handler before registration")
   380  		t.FailNow()
   381  	}
   382  
   383  	r.OPTIONS("/abc", "abc")
   384  
   385  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h == nil {
   386  		t.Log("OPTIONS /abc should return handler after registration")
   387  		t.FailNow()
   388  	}
   389  
   390  	// PATCH
   391  	if h, _ := r.Lookup("PATCH", "/", nil); h != nil {
   392  		t.Log("PATCH / should not return handler before registration")
   393  		t.FailNow()
   394  	}
   395  	r.PATCH("/", 1)
   396  	if h, _ := r.Lookup("PATCH", "/", nil); h == nil {
   397  		t.Log("PATCH / should return handler after registration")
   398  		t.FailNow()
   399  	}
   400  	if h, _ := r.Lookup("PATCH", "/abc", nil); h != nil {
   401  		t.Log("PATCH /abc should not return handler before registration")
   402  		t.FailNow()
   403  	}
   404  
   405  	r.PATCH("/abc", "abc")
   406  
   407  	if h, _ := r.Lookup("PATCH", "/abc", nil); h == nil {
   408  		t.Log("PATCH /abc should return handler after registration")
   409  		t.FailNow()
   410  	}
   411  
   412  	ln, port := testutils.Port().NonRoot().Unused().AcquireListener()
   413  	bindAddr := fmt.Sprintf(":%d", port)
   414  	go func() {
   415  		err := app.Serve(ln)
   416  		if err != nil {
   417  			panic(err)
   418  		}
   419  	}()
   420  	_, err := http.Get("http://127.0.0.1" + bindAddr) // just should not panic
   421  	_ = err
   422  }
   423  
   424  func TestDomainHTTPRouter(t *testing.T) {
   425  	app := New()
   426  	r := app.Domain("example.com").HTTP()
   427  	if h, _ := r.Lookup("GET", "/", nil); h != nil {
   428  		t.Log("GET / should not return handler before registration")
   429  		t.FailNow()
   430  	}
   431  	r.GET("/", 1)
   432  	if h, _ := r.Lookup("GET", "/", nil); h == nil {
   433  		t.Log("GET / should return handler after registration")
   434  		t.FailNow()
   435  	}
   436  	if h, _ := r.Lookup("GET", "/abc", nil); h != nil {
   437  		t.Log("GET /abc should not return handler before registration")
   438  		t.FailNow()
   439  	}
   440  
   441  	r.GET("/abc", "abc")
   442  
   443  	if h, _ := r.Lookup("GET", "/abc", nil); h == nil {
   444  		t.Log("GET /abc should return handler after registration")
   445  		t.FailNow()
   446  	}
   447  
   448  	r.GET("/redir", app.ToTLSHandler())
   449  
   450  	// POST
   451  
   452  	if h, _ := r.Lookup("POST", "/", nil); h != nil {
   453  		t.Log("POST / should not return handler before registration")
   454  		t.FailNow()
   455  	}
   456  	r.POST("/", 1)
   457  	if h, _ := r.Lookup("POST", "/", nil); h == nil {
   458  		t.Log("POST / should return handler after registration")
   459  		t.FailNow()
   460  	}
   461  	if h, _ := r.Lookup("POST", "/abc", nil); h != nil {
   462  		t.Log("POST /abc should not return handler before registration")
   463  		t.FailNow()
   464  	}
   465  
   466  	r.POST("/abc", "abc")
   467  
   468  	if h, _ := r.Lookup("POST", "/abc", nil); h == nil {
   469  		t.Log("POST /abc should return handler after registration")
   470  		t.FailNow()
   471  	}
   472  
   473  	// PUT
   474  	if h, _ := r.Lookup("PUT", "/", nil); h != nil {
   475  		t.Log("PUT / should not return handler before registration")
   476  		t.FailNow()
   477  	}
   478  	r.PUT("/", 1)
   479  	if h, _ := r.Lookup("PUT", "/", nil); h == nil {
   480  		t.Log("PUT / should return handler after registration")
   481  		t.FailNow()
   482  	}
   483  	if h, _ := r.Lookup("PUT", "/abc", nil); h != nil {
   484  		t.Log("PUT /abc should not return handler before registration")
   485  		t.FailNow()
   486  	}
   487  
   488  	r.PUT("/abc", "abc")
   489  
   490  	if h, _ := r.Lookup("PUT", "/abc", nil); h == nil {
   491  		t.Log("PUT /abc should return handler after registration")
   492  		t.FailNow()
   493  	}
   494  
   495  	// DELETE
   496  	if h, _ := r.Lookup("DELETE", "/", nil); h != nil {
   497  		t.Log("DELETE / should not return handler before registration")
   498  		t.FailNow()
   499  	}
   500  	r.DELETE("/", 1)
   501  	if h, _ := r.Lookup("DELETE", "/", nil); h == nil {
   502  		t.Log("DELETE / should return handler after registration")
   503  		t.FailNow()
   504  	}
   505  	if h, _ := r.Lookup("DELETE", "/abc", nil); h != nil {
   506  		t.Log("DELETE /abc should not return handler before registration")
   507  		t.FailNow()
   508  	}
   509  
   510  	r.DELETE("/abc", "abc")
   511  
   512  	if h, _ := r.Lookup("DELETE", "/abc", nil); h == nil {
   513  		t.Log("DELETE /abc should return handler after registration")
   514  		t.FailNow()
   515  	}
   516  
   517  	// HEAD
   518  	if h, _ := r.Lookup("HEAD", "/", nil); h != nil {
   519  		t.Log("HEAD / should not return handler before registration")
   520  		t.FailNow()
   521  	}
   522  	r.HEAD("/", 1)
   523  	if h, _ := r.Lookup("HEAD", "/", nil); h == nil {
   524  		t.Log("HEAD / should return handler after registration")
   525  		t.FailNow()
   526  	}
   527  	if h, _ := r.Lookup("HEAD", "/abc", nil); h != nil {
   528  		t.Log("HEAD /abc should not return handler before registration")
   529  		t.FailNow()
   530  	}
   531  
   532  	r.HEAD("/abc", "abc")
   533  
   534  	if h, _ := r.Lookup("HEAD", "/abc", nil); h == nil {
   535  		t.Log("HEAD /abc should return handler after registration")
   536  		t.FailNow()
   537  	}
   538  
   539  	// OPTIONS
   540  	if h, _ := r.Lookup("OPTIONS", "/", nil); h != nil {
   541  		t.Log("OPTIONS / should not return handler before registration")
   542  		t.FailNow()
   543  	}
   544  	r.OPTIONS("/", 1)
   545  	if h, _ := r.Lookup("OPTIONS", "/", nil); h == nil {
   546  		t.Log("OPTIONS / should return handler after registration")
   547  		t.FailNow()
   548  	}
   549  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h != nil {
   550  		t.Log("OPTIONS /abc should not return handler before registration")
   551  		t.FailNow()
   552  	}
   553  
   554  	r.OPTIONS("/abc", "abc")
   555  
   556  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h == nil {
   557  		t.Log("OPTIONS /abc should return handler after registration")
   558  		t.FailNow()
   559  	}
   560  
   561  	// PATCH
   562  	if h, _ := r.Lookup("PATCH", "/", nil); h != nil {
   563  		t.Log("PATCH / should not return handler before registration")
   564  		t.FailNow()
   565  	}
   566  	r.PATCH("/", 1)
   567  	if h, _ := r.Lookup("PATCH", "/", nil); h == nil {
   568  		t.Log("PATCH / should return handler after registration")
   569  		t.FailNow()
   570  	}
   571  	if h, _ := r.Lookup("PATCH", "/abc", nil); h != nil {
   572  		t.Log("PATCH /abc should not return handler before registration")
   573  		t.FailNow()
   574  	}
   575  
   576  	r.PATCH("/abc", "abc")
   577  
   578  	if h, _ := r.Lookup("PATCH", "/abc", nil); h == nil {
   579  		t.Log("PATCH /abc should return handler after registration")
   580  		t.FailNow()
   581  	}
   582  }
   583  
   584  func TestDomainHTTPSRouter(t *testing.T) {
   585  	app := New()
   586  	r := app.Domain("example.com").HTTPS()
   587  	if h, _ := r.Lookup("GET", "/", nil); h != nil {
   588  		t.Log("GET / should not return handler before registration")
   589  		t.FailNow()
   590  	}
   591  	r.GET("/", 1)
   592  	if h, _ := r.Lookup("GET", "/", nil); h == nil {
   593  		t.Log("GET / should return handler after registration")
   594  		t.FailNow()
   595  	}
   596  	if h, _ := r.Lookup("GET", "/abc", nil); h != nil {
   597  		t.Log("GET /abc should not return handler before registration")
   598  		t.FailNow()
   599  	}
   600  
   601  	r.GET("/abc", "abc")
   602  
   603  	if h, _ := r.Lookup("GET", "/abc", nil); h == nil {
   604  		t.Log("GET /abc should return handler after registration")
   605  		t.FailNow()
   606  	}
   607  
   608  	r.GET("/redir", app.ToTLSHandler())
   609  
   610  	if h, _ := r.Lookup("GET", "/redir", nil); h == nil {
   611  		t.Log("GET /abc should return handler after registration")
   612  		t.FailNow()
   613  	} else {
   614  		defer func() {
   615  			e := recover()
   616  			if e != nil {
   617  				t.Log("panic handled when testing /redir")
   618  			}
   619  		}()
   620  		h(&Context{
   621  			RequestCtx: &fasthttp.RequestCtx{},
   622  		})
   623  	}
   624  
   625  	// POST
   626  
   627  	if h, _ := r.Lookup("POST", "/", nil); h != nil {
   628  		t.Log("POST / should not return handler before registration")
   629  		t.FailNow()
   630  	}
   631  	r.POST("/", 1)
   632  	if h, _ := r.Lookup("POST", "/", nil); h == nil {
   633  		t.Log("POST / should return handler after registration")
   634  		t.FailNow()
   635  	}
   636  	if h, _ := r.Lookup("POST", "/abc", nil); h != nil {
   637  		t.Log("POST /abc should not return handler before registration")
   638  		t.FailNow()
   639  	}
   640  
   641  	r.POST("/abc", "abc")
   642  
   643  	if h, _ := r.Lookup("POST", "/abc", nil); h == nil {
   644  		t.Log("POST /abc should return handler after registration")
   645  		t.FailNow()
   646  	}
   647  
   648  	// PUT
   649  	if h, _ := r.Lookup("PUT", "/", nil); h != nil {
   650  		t.Log("PUT / should not return handler before registration")
   651  		t.FailNow()
   652  	}
   653  	r.PUT("/", 1)
   654  	if h, _ := r.Lookup("PUT", "/", nil); h == nil {
   655  		t.Log("PUT / should return handler after registration")
   656  		t.FailNow()
   657  	}
   658  	if h, _ := r.Lookup("PUT", "/abc", nil); h != nil {
   659  		t.Log("PUT /abc should not return handler before registration")
   660  		t.FailNow()
   661  	}
   662  
   663  	r.PUT("/abc", "abc")
   664  
   665  	if h, _ := r.Lookup("PUT", "/abc", nil); h == nil {
   666  		t.Log("PUT /abc should return handler after registration")
   667  		t.FailNow()
   668  	}
   669  
   670  	// DELETE
   671  	if h, _ := r.Lookup("DELETE", "/", nil); h != nil {
   672  		t.Log("DELETE / should not return handler before registration")
   673  		t.FailNow()
   674  	}
   675  	r.DELETE("/", 1)
   676  	if h, _ := r.Lookup("DELETE", "/", nil); h == nil {
   677  		t.Log("DELETE / should return handler after registration")
   678  		t.FailNow()
   679  	}
   680  	if h, _ := r.Lookup("DELETE", "/abc", nil); h != nil {
   681  		t.Log("DELETE /abc should not return handler before registration")
   682  		t.FailNow()
   683  	}
   684  
   685  	r.DELETE("/abc", "abc")
   686  
   687  	if h, _ := r.Lookup("DELETE", "/abc", nil); h == nil {
   688  		t.Log("DELETE /abc should return handler after registration")
   689  		t.FailNow()
   690  	}
   691  
   692  	// HEAD
   693  	if h, _ := r.Lookup("HEAD", "/", nil); h != nil {
   694  		t.Log("HEAD / should not return handler before registration")
   695  		t.FailNow()
   696  	}
   697  	r.HEAD("/", 1)
   698  	if h, _ := r.Lookup("HEAD", "/", nil); h == nil {
   699  		t.Log("HEAD / should return handler after registration")
   700  		t.FailNow()
   701  	}
   702  	if h, _ := r.Lookup("HEAD", "/abc", nil); h != nil {
   703  		t.Log("HEAD /abc should not return handler before registration")
   704  		t.FailNow()
   705  	}
   706  
   707  	r.HEAD("/abc", "abc")
   708  
   709  	if h, _ := r.Lookup("HEAD", "/abc", nil); h == nil {
   710  		t.Log("HEAD /abc should return handler after registration")
   711  		t.FailNow()
   712  	}
   713  
   714  	// OPTIONS
   715  	if h, _ := r.Lookup("OPTIONS", "/", nil); h != nil {
   716  		t.Log("OPTIONS / should not return handler before registration")
   717  		t.FailNow()
   718  	}
   719  	r.OPTIONS("/", 1)
   720  	if h, _ := r.Lookup("OPTIONS", "/", nil); h == nil {
   721  		t.Log("OPTIONS / should return handler after registration")
   722  		t.FailNow()
   723  	}
   724  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h != nil {
   725  		t.Log("OPTIONS /abc should not return handler before registration")
   726  		t.FailNow()
   727  	}
   728  
   729  	r.OPTIONS("/abc", "abc")
   730  
   731  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h == nil {
   732  		t.Log("OPTIONS /abc should return handler after registration")
   733  		t.FailNow()
   734  	}
   735  
   736  	// PATCH
   737  	if h, _ := r.Lookup("PATCH", "/", nil); h != nil {
   738  		t.Log("PATCH / should not return handler before registration")
   739  		t.FailNow()
   740  	}
   741  	r.PATCH("/", 1)
   742  	if h, _ := r.Lookup("PATCH", "/", nil); h == nil {
   743  		t.Log("PATCH / should return handler after registration")
   744  		t.FailNow()
   745  	}
   746  	if h, _ := r.Lookup("PATCH", "/abc", nil); h != nil {
   747  		t.Log("PATCH /abc should not return handler before registration")
   748  		t.FailNow()
   749  	}
   750  
   751  	r.PATCH("/abc", "abc")
   752  
   753  	if h, _ := r.Lookup("PATCH", "/abc", nil); h == nil {
   754  		t.Log("PATCH /abc should return handler after registration")
   755  		t.FailNow()
   756  	}
   757  
   758  	r.GET("/err", func(ctx *Context) error {
   759  		return errors.New("test")
   760  	})
   761  
   762  	r.GET("/fasterr", func(ctx *fasthttp.RequestCtx) error {
   763  		return errors.New("test")
   764  	})
   765  
   766  	if h, _ := r.Lookup("PATCH", "/abc", nil); h == nil {
   767  		t.Log("PATCH /abc should return handler after registration")
   768  		t.FailNow()
   769  	}
   770  
   771  	ln, port := testutils.Port().NonRoot().Unused().AcquireListener()
   772  	bindAddr := fmt.Sprintf(":%d", port)
   773  	go func() {
   774  		err := app.Serve(ln)
   775  		if err != nil {
   776  			panic(err)
   777  		}
   778  	}()
   779  	_, e := http.Get("http://127.0.0.1" + bindAddr) // just should not panic
   780  	_ = e
   781  	_, e = http.Get("http://127.0.0.1" + bindAddr) // just should not panic, twice
   782  	_ = e
   783  }
   784  
   785  func TestHTTPRouter(t *testing.T) {
   786  	app := New()
   787  	r := app.HTTP()
   788  	if h, _ := r.Lookup("GET", "/", nil); h != nil {
   789  		t.Log("GET / should not return handler before registration")
   790  		t.FailNow()
   791  	}
   792  	r.GET("/", 1)
   793  	if h, _ := r.Lookup("GET", "/", nil); h == nil {
   794  		t.Log("GET / should return handler after registration")
   795  		t.FailNow()
   796  	}
   797  	if h, _ := r.Lookup("GET", "/abc", nil); h != nil {
   798  		t.Log("GET /abc should not return handler before registration")
   799  		t.FailNow()
   800  	}
   801  
   802  	r.GET("/abc", "abc")
   803  
   804  	if h, _ := r.Lookup("GET", "/abc", nil); h == nil {
   805  		t.Log("GET /abc should return handler after registration")
   806  		t.FailNow()
   807  	}
   808  
   809  	r.GET("/redir", app.ToTLSHandler())
   810  
   811  	// POST
   812  
   813  	if h, _ := r.Lookup("POST", "/", nil); h != nil {
   814  		t.Log("POST / should not return handler before registration")
   815  		t.FailNow()
   816  	}
   817  	r.POST("/", 1)
   818  	if h, _ := r.Lookup("POST", "/", nil); h == nil {
   819  		t.Log("POST / should return handler after registration")
   820  		t.FailNow()
   821  	}
   822  	if h, _ := r.Lookup("POST", "/abc", nil); h != nil {
   823  		t.Log("POST /abc should not return handler before registration")
   824  		t.FailNow()
   825  	}
   826  
   827  	r.POST("/abc", "abc")
   828  
   829  	if h, _ := r.Lookup("POST", "/abc", nil); h == nil {
   830  		t.Log("POST /abc should return handler after registration")
   831  		t.FailNow()
   832  	}
   833  
   834  	// PUT
   835  	if h, _ := r.Lookup("PUT", "/", nil); h != nil {
   836  		t.Log("PUT / should not return handler before registration")
   837  		t.FailNow()
   838  	}
   839  	r.PUT("/", 1)
   840  	if h, _ := r.Lookup("PUT", "/", nil); h == nil {
   841  		t.Log("PUT / should return handler after registration")
   842  		t.FailNow()
   843  	}
   844  	if h, _ := r.Lookup("PUT", "/abc", nil); h != nil {
   845  		t.Log("PUT /abc should not return handler before registration")
   846  		t.FailNow()
   847  	}
   848  
   849  	r.PUT("/abc", "abc")
   850  
   851  	if h, _ := r.Lookup("PUT", "/abc", nil); h == nil {
   852  		t.Log("PUT /abc should return handler after registration")
   853  		t.FailNow()
   854  	}
   855  
   856  	// DELETE
   857  	if h, _ := r.Lookup("DELETE", "/", nil); h != nil {
   858  		t.Log("DELETE / should not return handler before registration")
   859  		t.FailNow()
   860  	}
   861  	r.DELETE("/", 1)
   862  	if h, _ := r.Lookup("DELETE", "/", nil); h == nil {
   863  		t.Log("DELETE / should return handler after registration")
   864  		t.FailNow()
   865  	}
   866  	if h, _ := r.Lookup("DELETE", "/abc", nil); h != nil {
   867  		t.Log("DELETE /abc should not return handler before registration")
   868  		t.FailNow()
   869  	}
   870  
   871  	r.DELETE("/abc", "abc")
   872  
   873  	if h, _ := r.Lookup("DELETE", "/abc", nil); h == nil {
   874  		t.Log("DELETE /abc should return handler after registration")
   875  		t.FailNow()
   876  	}
   877  
   878  	// HEAD
   879  	if h, _ := r.Lookup("HEAD", "/", nil); h != nil {
   880  		t.Log("HEAD / should not return handler before registration")
   881  		t.FailNow()
   882  	}
   883  	r.HEAD("/", 1)
   884  	if h, _ := r.Lookup("HEAD", "/", nil); h == nil {
   885  		t.Log("HEAD / should return handler after registration")
   886  		t.FailNow()
   887  	}
   888  	if h, _ := r.Lookup("HEAD", "/abc", nil); h != nil {
   889  		t.Log("HEAD /abc should not return handler before registration")
   890  		t.FailNow()
   891  	}
   892  
   893  	r.HEAD("/abc", "abc")
   894  
   895  	if h, _ := r.Lookup("HEAD", "/abc", nil); h == nil {
   896  		t.Log("HEAD /abc should return handler after registration")
   897  		t.FailNow()
   898  	}
   899  
   900  	// OPTIONS
   901  	if h, _ := r.Lookup("OPTIONS", "/", nil); h != nil {
   902  		t.Log("OPTIONS / should not return handler before registration")
   903  		t.FailNow()
   904  	}
   905  	r.OPTIONS("/", 1)
   906  	if h, _ := r.Lookup("OPTIONS", "/", nil); h == nil {
   907  		t.Log("OPTIONS / should return handler after registration")
   908  		t.FailNow()
   909  	}
   910  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h != nil {
   911  		t.Log("OPTIONS /abc should not return handler before registration")
   912  		t.FailNow()
   913  	}
   914  
   915  	r.OPTIONS("/abc", "abc")
   916  
   917  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h == nil {
   918  		t.Log("OPTIONS /abc should return handler after registration")
   919  		t.FailNow()
   920  	}
   921  
   922  	// PATCH
   923  	if h, _ := r.Lookup("PATCH", "/", nil); h != nil {
   924  		t.Log("PATCH / should not return handler before registration")
   925  		t.FailNow()
   926  	}
   927  	r.PATCH("/", 1)
   928  	if h, _ := r.Lookup("PATCH", "/", nil); h == nil {
   929  		t.Log("PATCH / should return handler after registration")
   930  		t.FailNow()
   931  	}
   932  	if h, _ := r.Lookup("PATCH", "/abc", nil); h != nil {
   933  		t.Log("PATCH /abc should not return handler before registration")
   934  		t.FailNow()
   935  	}
   936  
   937  	r.PATCH("/abc", "abc")
   938  
   939  	if h, _ := r.Lookup("PATCH", "/abc", nil); h == nil {
   940  		t.Log("PATCH /abc should return handler after registration")
   941  		t.FailNow()
   942  	}
   943  }
   944  
   945  func TestHTTPSRouter(t *testing.T) {
   946  	app := New()
   947  	r := app.HTTPS()
   948  	if h, _ := r.Lookup("GET", "/", nil); h != nil {
   949  		t.Log("GET / should not return handler before registration")
   950  		t.FailNow()
   951  	}
   952  	r.GET("/", 1)
   953  	if h, _ := r.Lookup("GET", "/", nil); h == nil {
   954  		t.Log("GET / should return handler after registration")
   955  		t.FailNow()
   956  	}
   957  	if h, _ := r.Lookup("GET", "/abc", nil); h != nil {
   958  		t.Log("GET /abc should not return handler before registration")
   959  		t.FailNow()
   960  	}
   961  
   962  	r.GET("/abc", "abc")
   963  
   964  	if h, _ := r.Lookup("GET", "/abc", nil); h == nil {
   965  		t.Log("GET /abc should return handler after registration")
   966  		t.FailNow()
   967  	}
   968  
   969  	r.GET("/redir", app.ToTLSHandler())
   970  
   971  	if h, _ := r.Lookup("GET", "/redir", nil); h == nil {
   972  		t.Log("GET /abc should return handler after registration")
   973  		t.FailNow()
   974  	} else {
   975  		defer func() {
   976  			e := recover()
   977  			if e != nil {
   978  				t.Log("panic handled when testing /redir")
   979  			}
   980  		}()
   981  		h(&Context{
   982  			RequestCtx: &fasthttp.RequestCtx{},
   983  		})
   984  	}
   985  
   986  	// POST
   987  
   988  	if h, _ := r.Lookup("POST", "/", nil); h != nil {
   989  		t.Log("POST / should not return handler before registration")
   990  		t.FailNow()
   991  	}
   992  	r.POST("/", 1)
   993  	if h, _ := r.Lookup("POST", "/", nil); h == nil {
   994  		t.Log("POST / should return handler after registration")
   995  		t.FailNow()
   996  	}
   997  	if h, _ := r.Lookup("POST", "/abc", nil); h != nil {
   998  		t.Log("POST /abc should not return handler before registration")
   999  		t.FailNow()
  1000  	}
  1001  
  1002  	r.POST("/abc", "abc")
  1003  
  1004  	if h, _ := r.Lookup("POST", "/abc", nil); h == nil {
  1005  		t.Log("POST /abc should return handler after registration")
  1006  		t.FailNow()
  1007  	}
  1008  
  1009  	// PUT
  1010  	if h, _ := r.Lookup("PUT", "/", nil); h != nil {
  1011  		t.Log("PUT / should not return handler before registration")
  1012  		t.FailNow()
  1013  	}
  1014  	r.PUT("/", 1)
  1015  	if h, _ := r.Lookup("PUT", "/", nil); h == nil {
  1016  		t.Log("PUT / should return handler after registration")
  1017  		t.FailNow()
  1018  	}
  1019  	if h, _ := r.Lookup("PUT", "/abc", nil); h != nil {
  1020  		t.Log("PUT /abc should not return handler before registration")
  1021  		t.FailNow()
  1022  	}
  1023  
  1024  	r.PUT("/abc", "abc")
  1025  
  1026  	if h, _ := r.Lookup("PUT", "/abc", nil); h == nil {
  1027  		t.Log("PUT /abc should return handler after registration")
  1028  		t.FailNow()
  1029  	}
  1030  
  1031  	// DELETE
  1032  	if h, _ := r.Lookup("DELETE", "/", nil); h != nil {
  1033  		t.Log("DELETE / should not return handler before registration")
  1034  		t.FailNow()
  1035  	}
  1036  	r.DELETE("/", 1)
  1037  	if h, _ := r.Lookup("DELETE", "/", nil); h == nil {
  1038  		t.Log("DELETE / should return handler after registration")
  1039  		t.FailNow()
  1040  	}
  1041  	if h, _ := r.Lookup("DELETE", "/abc", nil); h != nil {
  1042  		t.Log("DELETE /abc should not return handler before registration")
  1043  		t.FailNow()
  1044  	}
  1045  
  1046  	r.DELETE("/abc", "abc")
  1047  
  1048  	if h, _ := r.Lookup("DELETE", "/abc", nil); h == nil {
  1049  		t.Log("DELETE /abc should return handler after registration")
  1050  		t.FailNow()
  1051  	}
  1052  
  1053  	// HEAD
  1054  	if h, _ := r.Lookup("HEAD", "/", nil); h != nil {
  1055  		t.Log("HEAD / should not return handler before registration")
  1056  		t.FailNow()
  1057  	}
  1058  	r.HEAD("/", 1)
  1059  	if h, _ := r.Lookup("HEAD", "/", nil); h == nil {
  1060  		t.Log("HEAD / should return handler after registration")
  1061  		t.FailNow()
  1062  	}
  1063  	if h, _ := r.Lookup("HEAD", "/abc", nil); h != nil {
  1064  		t.Log("HEAD /abc should not return handler before registration")
  1065  		t.FailNow()
  1066  	}
  1067  
  1068  	r.HEAD("/abc", "abc")
  1069  
  1070  	if h, _ := r.Lookup("HEAD", "/abc", nil); h == nil {
  1071  		t.Log("HEAD /abc should return handler after registration")
  1072  		t.FailNow()
  1073  	}
  1074  
  1075  	// OPTIONS
  1076  	if h, _ := r.Lookup("OPTIONS", "/", nil); h != nil {
  1077  		t.Log("OPTIONS / should not return handler before registration")
  1078  		t.FailNow()
  1079  	}
  1080  	r.OPTIONS("/", 1)
  1081  	if h, _ := r.Lookup("OPTIONS", "/", nil); h == nil {
  1082  		t.Log("OPTIONS / should return handler after registration")
  1083  		t.FailNow()
  1084  	}
  1085  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h != nil {
  1086  		t.Log("OPTIONS /abc should not return handler before registration")
  1087  		t.FailNow()
  1088  	}
  1089  
  1090  	r.OPTIONS("/abc", "abc")
  1091  
  1092  	if h, _ := r.Lookup("OPTIONS", "/abc", nil); h == nil {
  1093  		t.Log("OPTIONS /abc should return handler after registration")
  1094  		t.FailNow()
  1095  	}
  1096  
  1097  	// PATCH
  1098  	if h, _ := r.Lookup("PATCH", "/", nil); h != nil {
  1099  		t.Log("PATCH / should not return handler before registration")
  1100  		t.FailNow()
  1101  	}
  1102  	r.PATCH("/", 1)
  1103  	if h, _ := r.Lookup("PATCH", "/", nil); h == nil {
  1104  		t.Log("PATCH / should return handler after registration")
  1105  		t.FailNow()
  1106  	}
  1107  	if h, _ := r.Lookup("PATCH", "/abc", nil); h != nil {
  1108  		t.Log("PATCH /abc should not return handler before registration")
  1109  		t.FailNow()
  1110  	}
  1111  
  1112  	r.PATCH("/abc", "abc")
  1113  
  1114  	if h, _ := r.Lookup("PATCH", "/abc", nil); h == nil {
  1115  		t.Log("PATCH /abc should return handler after registration")
  1116  		t.FailNow()
  1117  	}
  1118  
  1119  	r.GET("/err", func(ctx *Context) error {
  1120  		return errors.New("test")
  1121  	})
  1122  
  1123  	r.GET("/fasterr", func(ctx *fasthttp.RequestCtx) error {
  1124  		return errors.New("test")
  1125  	})
  1126  
  1127  	if h, _ := r.Lookup("PATCH", "/abc", nil); h == nil {
  1128  		t.Log("PATCH /abc should return handler after registration")
  1129  		t.FailNow()
  1130  	}
  1131  
  1132  	ln, port := testutils.Port().NonRoot().Unused().AcquireListener()
  1133  	bindAddr := fmt.Sprintf(":%d", port)
  1134  	go func() {
  1135  		err := app.Serve(ln)
  1136  		if err != nil {
  1137  			panic(err)
  1138  		}
  1139  	}()
  1140  	_, err := http.Get("http://127.0.0.1" + bindAddr) // just should not panic
  1141  	_ = err
  1142  	_, err = http.Get("http://127.0.0.1" + bindAddr) // just should not panic, twice
  1143  	_ = err
  1144  }