From 9bacadd3eab2e7271c456eedf2b02e4e09357d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B0=E6=AC=A7?= Date: Fri, 1 Mar 2019 07:11:02 +0800 Subject: [PATCH 1/2] remove docs dir (#1786) the post doc move https://gin-gonic.com/blog/ --- docs/how-to-build-an-effective-middleware.md | 137 ------------------- 1 file changed, 137 deletions(-) delete mode 100644 docs/how-to-build-an-effective-middleware.md diff --git a/docs/how-to-build-an-effective-middleware.md b/docs/how-to-build-an-effective-middleware.md deleted file mode 100644 index 568d5720..00000000 --- a/docs/how-to-build-an-effective-middleware.md +++ /dev/null @@ -1,137 +0,0 @@ -# How to build one effective middleware? - -## Consitituent part - -The middleware has two parts: - - - part one is what is executed once, when you initialize your middleware. That's where you set up all the global objects, logicals etc. Everything that happens one per application lifetime. - - - part two is what executes on every request. For example, a database middleware you simply inject your "global" database object into the context. Once it's inside the context, you can retrieve it from within other middlewares and your handler function. - -```go -func funcName(params string) gin.HandlerFunc { - // <--- - // This is part one - // ---> - // The follow code is an example - if err := check(params); err != nil { - panic(err) - } - - return func(c *gin.Context) { - // <--- - // This is part two - // ---> - // The follow code is an example - c.Set("TestVar", params) - c.Next() - } -} -``` - -## Execution process - -Firstly, we have the follow example code: - -```go -func main() { - router := gin.Default() - - router.Use(globalMiddleware()) - - router.GET("/rest/n/api/*some", mid1(), mid2(), handler) - - router.Run() -} - -func globalMiddleware() gin.HandlerFunc { - fmt.Println("globalMiddleware...1") - - return func(c *gin.Context) { - fmt.Println("globalMiddleware...2") - c.Next() - fmt.Println("globalMiddleware...3") - } -} - -func handler(c *gin.Context) { - fmt.Println("exec handler.") -} - -func mid1() gin.HandlerFunc { - fmt.Println("mid1...1") - - return func(c *gin.Context) { - - fmt.Println("mid1...2") - c.Next() - fmt.Println("mid1...3") - } -} - -func mid2() gin.HandlerFunc { - fmt.Println("mid2...1") - - return func(c *gin.Context) { - fmt.Println("mid2...2") - c.Next() - fmt.Println("mid2...3") - } -} -``` - -According to [Consitituent part](#consitituent-part) said, when we run the gin process, **part one** will execute firstly and will print the follow information: - -```go -globalMiddleware...1 -mid1...1 -mid2...1 -``` - -And init order are: - -```go -globalMiddleware...1 - | - v -mid1...1 - | - v -mid2...1 -``` - -When we curl one request `curl -v localhost:8080/rest/n/api/some`, **part two** will execute their middleware and output the following information: - -```go -globalMiddleware...2 -mid1...2 -mid2...2 -exec handler. -mid2...3 -mid1...3 -globalMiddleware...3 -``` - -In other words, run order are: - -```go -globalMiddleware...2 - | - v -mid1...2 - | - v -mid2...2 - | - v -exec handler. - | - v -mid2...3 - | - v -mid1...3 - | - v -globalMiddleware...3 -``` From 2dd31930060c978a84507571f7a3106afbf9673b Mon Sep 17 00:00:00 2001 From: Equim Date: Fri, 1 Mar 2019 10:03:14 +0800 Subject: [PATCH 2/2] Support negotiation wildcards, fix #391 (#1112) * support negotiation wildcards, fix #391 * fix typo --- context.go | 13 ++++++++++++- context_test.go | 28 ++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/context.go b/context.go index 7618cef5..08c420b1 100644 --- a/context.go +++ b/context.go @@ -952,7 +952,18 @@ func (c *Context) NegotiateFormat(offered ...string) string { } for _, accepted := range c.Accepted { for _, offert := range offered { - if accepted == offert { + // According to RFC 2616 and RFC 2396, non-ASCII characters are not allowed in headers, + // therefore we can just iterate over the string without casting it into []rune + i := 0 + for ; i < len(accepted); i++ { + if accepted[i] == '*' || offert[i] == '*' { + return offert + } + if accepted[i] != offert[i] { + break + } + } + if i == len(accepted) { return offert } } diff --git a/context_test.go b/context_test.go index 060a8e8d..483e1680 100644 --- a/context_test.go +++ b/context_test.go @@ -1158,17 +1158,41 @@ func TestContextNegotiationFormat(t *testing.T) { func TestContextNegotiationFormatWithAccept(t *testing.T) { c, _ := CreateTestContext(httptest.NewRecorder()) c.Request, _ = http.NewRequest("POST", "/", nil) - c.Request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") + c.Request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8") assert.Equal(t, MIMEXML, c.NegotiateFormat(MIMEJSON, MIMEXML)) assert.Equal(t, MIMEHTML, c.NegotiateFormat(MIMEXML, MIMEHTML)) assert.Empty(t, c.NegotiateFormat(MIMEJSON)) } +func TestContextNegotiationFormatWithWildcardAccept(t *testing.T) { + c, _ := CreateTestContext(httptest.NewRecorder()) + c.Request, _ = http.NewRequest("POST", "/", nil) + c.Request.Header.Add("Accept", "*/*") + + assert.Equal(t, c.NegotiateFormat("*/*"), "*/*") + assert.Equal(t, c.NegotiateFormat("text/*"), "text/*") + assert.Equal(t, c.NegotiateFormat("application/*"), "application/*") + assert.Equal(t, c.NegotiateFormat(MIMEJSON), MIMEJSON) + assert.Equal(t, c.NegotiateFormat(MIMEXML), MIMEXML) + assert.Equal(t, c.NegotiateFormat(MIMEHTML), MIMEHTML) + + c, _ = CreateTestContext(httptest.NewRecorder()) + c.Request, _ = http.NewRequest("POST", "/", nil) + c.Request.Header.Add("Accept", "text/*") + + assert.Equal(t, c.NegotiateFormat("*/*"), "*/*") + assert.Equal(t, c.NegotiateFormat("text/*"), "text/*") + assert.Equal(t, c.NegotiateFormat("application/*"), "") + assert.Equal(t, c.NegotiateFormat(MIMEJSON), "") + assert.Equal(t, c.NegotiateFormat(MIMEXML), "") + assert.Equal(t, c.NegotiateFormat(MIMEHTML), MIMEHTML) +} + func TestContextNegotiationFormatCustom(t *testing.T) { c, _ := CreateTestContext(httptest.NewRecorder()) c.Request, _ = http.NewRequest("POST", "/", nil) - c.Request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") + c.Request.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8") c.Accepted = nil c.SetAccepted(MIMEJSON, MIMEXML)