github.com/wangyougui/gf/v2@v2.6.5/net/ghttp/ghttp_z_unit_feature_request_ctx_test.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/wangyougui/gf.
     6  
     7  package ghttp_test
     8  
     9  import (
    10  	"context"
    11  	"fmt"
    12  	"net/http"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/wangyougui/gf/v2/container/garray"
    17  	"github.com/wangyougui/gf/v2/encoding/gbase64"
    18  	"github.com/wangyougui/gf/v2/frame/g"
    19  	"github.com/wangyougui/gf/v2/net/ghttp"
    20  	"github.com/wangyougui/gf/v2/test/gtest"
    21  	"github.com/wangyougui/gf/v2/util/guid"
    22  )
    23  
    24  func Test_Request_IsFileRequest(t *testing.T) {
    25  	gtest.C(t, func(t *gtest.T) {
    26  		s := g.Server(guid.S())
    27  		s.Group("/", func(group *ghttp.RouterGroup) {
    28  			group.ALL("/", func(r *ghttp.Request) {
    29  				r.Response.Write(r.IsFileRequest())
    30  			})
    31  		})
    32  		s.SetDumpRouterMap(false)
    33  		s.Start()
    34  		defer s.Shutdown()
    35  
    36  		time.Sleep(100 * time.Millisecond)
    37  
    38  		c := g.Client()
    39  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
    40  
    41  		t.Assert(c.GetContent(ctx, "/"), false)
    42  	})
    43  }
    44  
    45  func Test_Request_IsAjaxRequest(t *testing.T) {
    46  	gtest.C(t, func(t *gtest.T) {
    47  		s := g.Server(guid.S())
    48  		s.Group("/", func(group *ghttp.RouterGroup) {
    49  			group.ALL("/", func(r *ghttp.Request) {
    50  				r.Response.Write(r.IsAjaxRequest())
    51  			})
    52  		})
    53  		s.SetDumpRouterMap(false)
    54  		s.Start()
    55  		defer s.Shutdown()
    56  
    57  		time.Sleep(100 * time.Millisecond)
    58  
    59  		c := g.Client()
    60  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
    61  
    62  		t.Assert(c.GetContent(ctx, "/"), false)
    63  	})
    64  }
    65  
    66  func Test_Request_GetClientIp(t *testing.T) {
    67  	gtest.C(t, func(t *gtest.T) {
    68  		s := g.Server(guid.S())
    69  		s.Group("/", func(group *ghttp.RouterGroup) {
    70  			group.ALL("/", func(r *ghttp.Request) {
    71  				r.Response.Write(r.GetClientIp())
    72  			})
    73  		})
    74  		s.SetDumpRouterMap(false)
    75  		s.Start()
    76  		defer s.Shutdown()
    77  
    78  		time.Sleep(100 * time.Millisecond)
    79  
    80  		c := g.Client()
    81  		c.SetHeader("X-Forwarded-For", "192.168.0.1")
    82  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
    83  
    84  		t.Assert(c.GetContent(ctx, "/"), "192.168.0.1")
    85  	})
    86  }
    87  
    88  func Test_Request_GetUrl(t *testing.T) {
    89  	gtest.C(t, func(t *gtest.T) {
    90  		s := g.Server(guid.S())
    91  		s.Group("/", func(group *ghttp.RouterGroup) {
    92  			group.ALL("/", func(r *ghttp.Request) {
    93  				r.Response.Write(r.GetUrl())
    94  			})
    95  		})
    96  		s.SetDumpRouterMap(false)
    97  		s.Start()
    98  		defer s.Shutdown()
    99  
   100  		time.Sleep(100 * time.Millisecond)
   101  
   102  		c := g.Client()
   103  		c.SetHeader("X-Forwarded-Proto", "https")
   104  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   105  
   106  		t.Assert(c.GetContent(ctx, "/"), fmt.Sprintf("https://127.0.0.1:%d/", s.GetListenedPort()))
   107  	})
   108  }
   109  
   110  func Test_Request_GetReferer(t *testing.T) {
   111  	gtest.C(t, func(t *gtest.T) {
   112  		s := g.Server(guid.S())
   113  		s.Group("/", func(group *ghttp.RouterGroup) {
   114  			group.ALL("/", func(r *ghttp.Request) {
   115  				r.Response.Write(r.GetReferer())
   116  			})
   117  		})
   118  		s.SetDumpRouterMap(false)
   119  		s.Start()
   120  		defer s.Shutdown()
   121  
   122  		time.Sleep(100 * time.Millisecond)
   123  
   124  		c := g.Client()
   125  		c.SetHeader("Referer", "Referer")
   126  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   127  
   128  		t.Assert(c.GetContent(ctx, "/"), "Referer")
   129  	})
   130  }
   131  
   132  func Test_Request_GetServeHandler(t *testing.T) {
   133  	gtest.C(t, func(t *gtest.T) {
   134  		s := g.Server(guid.S())
   135  		s.Group("/", func(group *ghttp.RouterGroup) {
   136  			group.ALL("/", func(r *ghttp.Request) {
   137  				r.Response.Write(r.GetServeHandler() != nil)
   138  			})
   139  		})
   140  		s.SetDumpRouterMap(false)
   141  		s.Start()
   142  		defer s.Shutdown()
   143  
   144  		time.Sleep(100 * time.Millisecond)
   145  
   146  		c := g.Client()
   147  		c.SetHeader("Referer", "Referer")
   148  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   149  
   150  		t.Assert(c.GetContent(ctx, "/"), true)
   151  	})
   152  }
   153  
   154  func Test_Request_BasicAuth(t *testing.T) {
   155  	const (
   156  		user      = "root"
   157  		pass      = "123456"
   158  		wrongPass = "12345"
   159  	)
   160  
   161  	s := g.Server(guid.S())
   162  	s.Group("/", func(group *ghttp.RouterGroup) {
   163  		group.ALL("/auth1", func(r *ghttp.Request) {
   164  			r.BasicAuth(user, pass, "tips")
   165  		})
   166  		group.ALL("/auth2", func(r *ghttp.Request) {
   167  			r.BasicAuth(user, pass)
   168  		})
   169  	})
   170  	s.SetDumpRouterMap(false)
   171  	s.Start()
   172  	defer s.Shutdown()
   173  
   174  	time.Sleep(100 * time.Millisecond)
   175  
   176  	gtest.C(t, func(t *gtest.T) {
   177  		c := g.Client()
   178  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   179  
   180  		rsp, err := c.Get(ctx, "/auth1")
   181  		t.AssertNil(err)
   182  		t.Assert(rsp.Header.Get("WWW-Authenticate"), "Basic realm=\"tips\"")
   183  		t.Assert(rsp.StatusCode, http.StatusUnauthorized)
   184  
   185  		rsp, err = c.SetHeader("Authorization", user+pass).Get(ctx, "/auth1")
   186  		t.AssertNil(err)
   187  		t.Assert(rsp.StatusCode, http.StatusForbidden)
   188  
   189  		rsp, err = c.SetHeader("Authorization", "Test "+user+pass).Get(ctx, "/auth1")
   190  		t.AssertNil(err)
   191  		t.Assert(rsp.StatusCode, http.StatusForbidden)
   192  
   193  		rsp, err = c.SetHeader("Authorization", "Basic "+user+pass).Get(ctx, "/auth1")
   194  		t.AssertNil(err)
   195  		t.Assert(rsp.StatusCode, http.StatusForbidden)
   196  
   197  		rsp, err = c.SetHeader("Authorization", "Basic "+gbase64.EncodeString(user+pass)).Get(ctx, "/auth1")
   198  		t.AssertNil(err)
   199  		t.Assert(rsp.StatusCode, http.StatusForbidden)
   200  
   201  		rsp, err = c.SetHeader("Authorization", "Basic "+gbase64.EncodeString(user+":"+wrongPass)).Get(ctx, "/auth1")
   202  		t.AssertNil(err)
   203  		t.Assert(rsp.StatusCode, http.StatusUnauthorized)
   204  
   205  		rsp, err = c.BasicAuth(user, pass).Get(ctx, "/auth1")
   206  		t.AssertNil(err)
   207  		t.Assert(rsp.StatusCode, http.StatusOK)
   208  
   209  		rsp, err = c.Get(ctx, "/auth2")
   210  		t.AssertNil(err)
   211  		t.Assert(rsp.Header.Get("WWW-Authenticate"), "Basic realm=\"Need Login\"")
   212  		t.Assert(rsp.StatusCode, http.StatusUnauthorized)
   213  	})
   214  }
   215  
   216  func Test_Request_SetCtx(t *testing.T) {
   217  	type ctxKey string
   218  	const testkey ctxKey = "test"
   219  	s := g.Server(guid.S())
   220  	s.Group("/", func(group *ghttp.RouterGroup) {
   221  		group.Middleware(func(r *ghttp.Request) {
   222  			ctx := context.WithValue(r.Context(), testkey, 1)
   223  			r.SetCtx(ctx)
   224  			r.Middleware.Next()
   225  		})
   226  		group.ALL("/", func(r *ghttp.Request) {
   227  			r.Response.Write(r.Context().Value(testkey))
   228  		})
   229  	})
   230  	s.SetDumpRouterMap(false)
   231  	s.Start()
   232  	defer s.Shutdown()
   233  
   234  	time.Sleep(100 * time.Millisecond)
   235  	gtest.C(t, func(t *gtest.T) {
   236  		c := g.Client()
   237  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   238  
   239  		t.Assert(c.GetContent(ctx, "/"), "1")
   240  	})
   241  }
   242  
   243  func Test_Request_GetCtx(t *testing.T) {
   244  	type ctxKey string
   245  	const testkey ctxKey = "test"
   246  	s := g.Server(guid.S())
   247  	s.Group("/", func(group *ghttp.RouterGroup) {
   248  		group.Middleware(func(r *ghttp.Request) {
   249  			ctx := context.WithValue(r.GetCtx(), testkey, 1)
   250  			r.SetCtx(ctx)
   251  			r.Middleware.Next()
   252  		})
   253  		group.ALL("/", func(r *ghttp.Request) {
   254  			r.Response.Write(r.Context().Value(testkey))
   255  		})
   256  	})
   257  	s.SetDumpRouterMap(false)
   258  	s.Start()
   259  	defer s.Shutdown()
   260  
   261  	time.Sleep(100 * time.Millisecond)
   262  	gtest.C(t, func(t *gtest.T) {
   263  		c := g.Client()
   264  		c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   265  
   266  		t.Assert(c.GetContent(ctx, "/"), "1")
   267  	})
   268  }
   269  
   270  func Test_Request_GetCtxVar(t *testing.T) {
   271  	s := g.Server(guid.S())
   272  	s.Group("/", func(group *ghttp.RouterGroup) {
   273  		group.Middleware(func(r *ghttp.Request) {
   274  			r.Middleware.Next()
   275  		})
   276  		group.GET("/", func(r *ghttp.Request) {
   277  			r.Response.Write(r.GetCtxVar("key", "val"))
   278  		})
   279  	})
   280  	s.SetDumpRouterMap(false)
   281  	s.Start()
   282  	defer s.Shutdown()
   283  
   284  	time.Sleep(100 * time.Millisecond)
   285  	gtest.C(t, func(t *gtest.T) {
   286  		client := g.Client()
   287  		client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   288  
   289  		t.Assert(client.GetContent(ctx, "/"), "val")
   290  	})
   291  }
   292  
   293  func Test_Request_Form(t *testing.T) {
   294  	type User struct {
   295  		Id   int
   296  		Name string
   297  	}
   298  	s := g.Server(guid.S())
   299  	s.Group("/", func(group *ghttp.RouterGroup) {
   300  		group.ALL("/", func(r *ghttp.Request) {
   301  			r.SetForm("key", "val")
   302  			r.Response.Write(r.GetForm("key"))
   303  		})
   304  		group.ALL("/useDef", func(r *ghttp.Request) {
   305  			r.Response.Write(r.GetForm("key", "defVal"))
   306  		})
   307  		group.ALL("/GetFormMap", func(r *ghttp.Request) {
   308  			r.Response.Write(r.GetFormMap(map[string]interface{}{"key": "val"}))
   309  		})
   310  		group.ALL("/GetFormMap1", func(r *ghttp.Request) {
   311  			r.Response.Write(r.GetFormMap(map[string]interface{}{"array": "val"}))
   312  		})
   313  		group.ALL("/GetFormMapStrVar", func(r *ghttp.Request) {
   314  			if r.Get("a") != nil {
   315  				r.Response.Write(r.GetFormMapStrVar()["a"])
   316  			}
   317  		})
   318  		group.ALL("/GetFormStruct", func(r *ghttp.Request) {
   319  			var user User
   320  			if err := r.GetFormStruct(&user); err != nil {
   321  				r.Response.Write(err.Error())
   322  			} else {
   323  				r.Response.Write(user.Name)
   324  			}
   325  		})
   326  	})
   327  	s.SetDumpRouterMap(false)
   328  	s.Start()
   329  	defer s.Shutdown()
   330  
   331  	time.Sleep(100 * time.Millisecond)
   332  	gtest.C(t, func(t *gtest.T) {
   333  		client := g.Client()
   334  		client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   335  
   336  		t.Assert(client.GetContent(ctx, "/"), "val")
   337  		t.Assert(client.GetContent(ctx, "/useDef"), "defVal")
   338  		t.Assert(client.PostContent(ctx, "/GetFormMap"), "{\"key\":\"val\"}")
   339  		t.Assert(client.PostContent(ctx, "/GetFormMap", "array[]=1&array[]=2"), "{\"key\":\"val\"}")
   340  		t.Assert(client.PostContent(ctx, "/GetFormMap1", "array[]=1&array[]=2"), "{\"array\":[\"1\",\"2\"]}")
   341  		t.Assert(client.GetContent(ctx, "/GetFormMapStrVar", "a=1&b=2"), nil)
   342  		t.Assert(client.PostContent(ctx, "/GetFormMapStrVar", "a=1&b=2"), `1`)
   343  		t.Assert(client.PostContent(ctx, "/GetFormStruct", g.Map{
   344  			"id":   1,
   345  			"name": "john",
   346  		}), "john")
   347  	})
   348  }
   349  
   350  func Test_Request_NeverDoneCtx_Done(t *testing.T) {
   351  	var array = garray.New(true)
   352  	s := g.Server(guid.S())
   353  	s.BindHandler("/done", func(r *ghttp.Request) {
   354  		var (
   355  			ctx    = r.Context()
   356  			ticker = time.NewTimer(time.Millisecond * 1500)
   357  		)
   358  		defer ticker.Stop()
   359  		for {
   360  			select {
   361  			case <-ctx.Done():
   362  				array.Append(1)
   363  				return
   364  			case <-ticker.C:
   365  				array.Append(1)
   366  				return
   367  			}
   368  		}
   369  	})
   370  	s.SetDumpRouterMap(false)
   371  	s.Start()
   372  	defer s.Shutdown()
   373  
   374  	time.Sleep(100 * time.Millisecond)
   375  
   376  	c := g.Client()
   377  	c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   378  	gtest.C(t, func(t *gtest.T) {
   379  		ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
   380  		go func() {
   381  			result := c.GetContent(ctx, "/done")
   382  			fmt.Println(result)
   383  		}()
   384  		time.Sleep(time.Millisecond * 100)
   385  
   386  		t.Assert(array.Len(), 0)
   387  		cancel()
   388  
   389  		time.Sleep(time.Millisecond * 500)
   390  		t.Assert(array.Len(), 1)
   391  	})
   392  }
   393  
   394  func Test_Request_NeverDoneCtx_NeverDone(t *testing.T) {
   395  	var array = garray.New(true)
   396  	s := g.Server(guid.S())
   397  	s.Use(ghttp.MiddlewareNeverDoneCtx)
   398  	s.BindHandler("/never-done", func(r *ghttp.Request) {
   399  		var (
   400  			ctx    = r.Context()
   401  			ticker = time.NewTimer(time.Millisecond * 1500)
   402  		)
   403  		defer ticker.Stop()
   404  		for {
   405  			select {
   406  			case <-ctx.Done():
   407  				array.Append(1)
   408  				return
   409  			case <-ticker.C:
   410  				array.Append(1)
   411  				return
   412  			}
   413  		}
   414  	})
   415  	s.SetDumpRouterMap(false)
   416  	s.Start()
   417  	defer s.Shutdown()
   418  
   419  	time.Sleep(100 * time.Millisecond)
   420  
   421  	c := g.Client()
   422  	c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
   423  	gtest.C(t, func(t *gtest.T) {
   424  		ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
   425  		go func() {
   426  			result := c.GetContent(ctx, "/never-done")
   427  			fmt.Println(result)
   428  		}()
   429  		time.Sleep(time.Millisecond * 100)
   430  
   431  		t.Assert(array.Len(), 0)
   432  		cancel()
   433  
   434  		time.Sleep(time.Millisecond * 1500)
   435  		t.Assert(array.Len(), 1)
   436  	})
   437  }