-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
刘洪宝
committed
Oct 22, 2018
1 parent
efa00ee
commit 0f55f1e
Showing
11 changed files
with
2,560 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
size_coverage.out | ||
vendor/ | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,13 @@ | ||
# bingo-router | ||
基于httprouter的路由模块 | ||
|
||
// 重写httprouter种的router结构体,添加中间件支持 | ||
|
||
httprouter 原来是添加一个handle | ||
|
||
改为添加一个 Route结构体 | ||
|
||
使用NewRoute创建 | ||
|
||
// 使用fasthttp | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// +build go1.7 | ||
|
||
package bingo_router | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
) | ||
|
||
type paramsKey struct{} | ||
|
||
// ParamsKey is the request context key under which URL params are stored. | ||
// | ||
// This is only present from go 1.7. | ||
var ParamsKey = paramsKey{} | ||
|
||
// Handler is an adapter which allows the usage of an http.Handler as a | ||
// request handle. With go 1.7+, the Params will be available in the | ||
// request context under ParamsKey. | ||
func (r *Router) Handler(method, path string, handler http.Handler) { | ||
r.Handle(method, path, | ||
func(w http.ResponseWriter, req *http.Request, p Params) { | ||
ctx := req.Context() | ||
ctx = context.WithValue(ctx, ParamsKey, p) | ||
req = req.WithContext(ctx) | ||
handler.ServeHTTP(w, req) | ||
}, | ||
) | ||
} | ||
|
||
// ParamsFromContext pulls the URL parameters from a request context, | ||
// or returns nil if none are present. | ||
// | ||
// This is only present from go 1.7. | ||
func ParamsFromContext(ctx context.Context) Params { | ||
p, _ := ctx.Value(ParamsKey).(Params) | ||
return p | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// +build !go1.7 | ||
|
||
package bingo_router | ||
|
||
import "net/http" | ||
|
||
// Handler is an adapter which allows the usage of an http.Handler as a | ||
// request handle. With go 1.7+, the Params will be available in the | ||
// request context under ParamsKey. | ||
func (r *Router) Handler(method, path string, handler http.Handler) { | ||
r.Handle(method, path, | ||
func(w http.ResponseWriter, req *http.Request, _ Params) { | ||
handler.ServeHTTP(w, req) | ||
}, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// Copyright 2013 Julien Schmidt. All rights reserved. | ||
// Based on the path package, Copyright 2009 The Go Authors. | ||
// Use of this source code is governed by a BSD-style license that can be found | ||
// in the LICENSE file. | ||
|
||
package bingo_router | ||
|
||
// CleanPath is the URL version of path.Clean, it returns a canonical URL path | ||
// for p, eliminating . and .. elements. | ||
// | ||
// The following rules are applied iteratively until no further processing can | ||
// be done: | ||
// 1. Replace multiple slashes with a single slash. | ||
// 2. Eliminate each . path name element (the current directory). | ||
// 3. Eliminate each inner .. path name element (the parent directory) | ||
// along with the non-.. element that precedes it. | ||
// 4. Eliminate .. elements that begin a rooted path: | ||
// that is, replace "/.." by "/" at the beginning of a path. | ||
// | ||
// If the result of this process is an empty string, "/" is returned | ||
func CleanPath(p string) string { | ||
// Turn empty string into "/" | ||
if p == "" { | ||
return "/" | ||
} | ||
|
||
n := len(p) | ||
var buf []byte | ||
|
||
// Invariants: | ||
// reading from path; r is index of next byte to process. | ||
// writing to buf; w is index of next byte to write. | ||
|
||
// path must start with '/' | ||
r := 1 | ||
w := 1 | ||
|
||
if p[0] != '/' { | ||
r = 0 | ||
buf = make([]byte, n+1) | ||
buf[0] = '/' | ||
} | ||
|
||
trailing := n > 1 && p[n-1] == '/' | ||
|
||
// A bit more clunky without a 'lazybuf' like the path package, but the loop | ||
// gets completely inlined (bufApp). So in contrast to the path package this | ||
// loop has no expensive function calls (except 1x make) | ||
|
||
for r < n { | ||
switch { | ||
case p[r] == '/': | ||
// empty path element, trailing slash is added after the end | ||
r++ | ||
|
||
case p[r] == '.' && r+1 == n: | ||
trailing = true | ||
r++ | ||
|
||
case p[r] == '.' && p[r+1] == '/': | ||
// . element | ||
r += 2 | ||
|
||
case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'): | ||
// .. element: remove to last / | ||
r += 3 | ||
|
||
if w > 1 { | ||
// can backtrack | ||
w-- | ||
|
||
if buf == nil { | ||
for w > 1 && p[w] != '/' { | ||
w-- | ||
} | ||
} else { | ||
for w > 1 && buf[w] != '/' { | ||
w-- | ||
} | ||
} | ||
} | ||
|
||
default: | ||
// real path element. | ||
// add slash if needed | ||
if w > 1 { | ||
bufApp(&buf, p, w, '/') | ||
w++ | ||
} | ||
|
||
// copy element | ||
for r < n && p[r] != '/' { | ||
bufApp(&buf, p, w, p[r]) | ||
w++ | ||
r++ | ||
} | ||
} | ||
} | ||
|
||
// re-append trailing slash | ||
if trailing && w > 1 { | ||
bufApp(&buf, p, w, '/') | ||
w++ | ||
} | ||
|
||
if buf == nil { | ||
return p[:w] | ||
} | ||
return string(buf[:w]) | ||
} | ||
|
||
// internal helper to lazily create a buffer if necessary | ||
func bufApp(buf *[]byte, s string, w int, c byte) { | ||
if *buf == nil { | ||
if s[w] == c { | ||
return | ||
} | ||
|
||
*buf = make([]byte, len(s)) | ||
copy(*buf, s[:w]) | ||
} | ||
(*buf)[w] = c | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Copyright 2013 Julien Schmidt. All rights reserved. | ||
// Based on the path package, Copyright 2009 The Go Authors. | ||
// Use of this source code is governed by a BSD-style license that can be found | ||
// in the LICENSE file. | ||
|
||
package bingo_router | ||
|
||
import ( | ||
"runtime" | ||
"testing" | ||
) | ||
|
||
var cleanTests = []struct { | ||
path, result string | ||
}{ | ||
// Already clean | ||
{"/", "/"}, | ||
{"/abc", "/abc"}, | ||
{"/a/b/c", "/a/b/c"}, | ||
{"/abc/", "/abc/"}, | ||
{"/a/b/c/", "/a/b/c/"}, | ||
|
||
// missing root | ||
{"", "/"}, | ||
{"a/", "/a/"}, | ||
{"abc", "/abc"}, | ||
{"abc/def", "/abc/def"}, | ||
{"a/b/c", "/a/b/c"}, | ||
|
||
// Remove doubled slash | ||
{"//", "/"}, | ||
{"/abc//", "/abc/"}, | ||
{"/abc/def//", "/abc/def/"}, | ||
{"/a/b/c//", "/a/b/c/"}, | ||
{"/abc//def//ghi", "/abc/def/ghi"}, | ||
{"//abc", "/abc"}, | ||
{"///abc", "/abc"}, | ||
{"//abc//", "/abc/"}, | ||
|
||
// Remove . elements | ||
{".", "/"}, | ||
{"./", "/"}, | ||
{"/abc/./def", "/abc/def"}, | ||
{"/./abc/def", "/abc/def"}, | ||
{"/abc/.", "/abc/"}, | ||
|
||
// Remove .. elements | ||
{"..", "/"}, | ||
{"../", "/"}, | ||
{"../../", "/"}, | ||
{"../..", "/"}, | ||
{"../../abc", "/abc"}, | ||
{"/abc/def/ghi/../jkl", "/abc/def/jkl"}, | ||
{"/abc/def/../ghi/../jkl", "/abc/jkl"}, | ||
{"/abc/def/..", "/abc"}, | ||
{"/abc/def/../..", "/"}, | ||
{"/abc/def/../../..", "/"}, | ||
{"/abc/def/../../..", "/"}, | ||
{"/abc/def/../../../ghi/jkl/../../../mno", "/mno"}, | ||
|
||
// Combinations | ||
{"abc/./../def", "/def"}, | ||
{"abc//./../def", "/def"}, | ||
{"abc/../../././../def", "/def"}, | ||
} | ||
|
||
func TestPathClean(t *testing.T) { | ||
for _, test := range cleanTests { | ||
if s := CleanPath(test.path); s != test.result { | ||
t.Errorf("CleanPath(%q) = %q, want %q", test.path, s, test.result) | ||
} | ||
if s := CleanPath(test.result); s != test.result { | ||
t.Errorf("CleanPath(%q) = %q, want %q", test.result, s, test.result) | ||
} | ||
} | ||
} | ||
|
||
func TestPathCleanMallocs(t *testing.T) { | ||
if testing.Short() { | ||
t.Skip("skipping malloc count in short mode") | ||
} | ||
if runtime.GOMAXPROCS(0) > 1 { | ||
t.Log("skipping AllocsPerRun checks; GOMAXPROCS>1") | ||
return | ||
} | ||
|
||
for _, test := range cleanTests { | ||
allocs := testing.AllocsPerRun(100, func() { CleanPath(test.result) }) | ||
if allocs > 0 { | ||
t.Errorf("CleanPath(%q): %v allocs, want zero", test.result, allocs) | ||
} | ||
} | ||
} |
Oops, something went wrong.