Skip to content

Commit 206eda7

Browse files
author
Sergio Andres Virviescas Santana
committed
Small code refactor
1 parent 1d731d8 commit 206eda7

File tree

5 files changed

+142
-143
lines changed

5 files changed

+142
-143
lines changed

path.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package router
77

88
import (
9+
"strings"
910
"sync"
1011

1112
"github.com/savsgio/gotils"
@@ -142,3 +143,33 @@ func cleanPathWithBuffer(cpb *cleanPathBuffer, path string) {
142143

143144
cpb.buf = cpb.buf[:cpb.w]
144145
}
146+
147+
// returns all possible paths when the original path has optional arguments
148+
func getOptionalPaths(path string) []string {
149+
paths := make([]string, 0)
150+
151+
index := 0
152+
newParam := false
153+
for i := 0; i < len(path); i++ {
154+
c := path[i]
155+
156+
if c == ':' {
157+
index = i
158+
newParam = true
159+
} else if i > 0 && newParam && c == '?' {
160+
p := strings.Replace(path[:index], "?", "", -1)
161+
if !gotils.StringSliceInclude(paths, p) {
162+
paths = append(paths, p)
163+
}
164+
165+
p = strings.Replace(path[:i], "?", "", -1) + "/"
166+
if !gotils.StringSliceInclude(paths, p) {
167+
paths = append(paths, p)
168+
}
169+
170+
newParam = false
171+
}
172+
}
173+
174+
return paths
175+
}

path_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ package router
88
import (
99
"runtime"
1010
"testing"
11+
12+
"github.com/valyala/fasthttp"
1113
)
1214

1315
var cleanTests = []struct {
@@ -91,6 +93,33 @@ func TestPathCleanMallocs(t *testing.T) {
9193
}
9294
}
9395

96+
func TestGetOptionalPath(t *testing.T) {
97+
handler := func(ctx *fasthttp.RequestCtx) {
98+
ctx.SetStatusCode(fasthttp.StatusOK)
99+
}
100+
101+
expectedPaths := []string{
102+
"/show/:name/",
103+
"/show/:name/:surname/",
104+
"/show/:name/:surname/at/",
105+
"/show/:name/:surname/at/:address/",
106+
"/show/:name/:surname/at/:address/:id/",
107+
"/show/:name/:surname/at/:address/:id/:phone/",
108+
}
109+
r := New()
110+
r.GET("/show/:name/:surname?/at/:address?/:id/:phone?", handler)
111+
112+
for _, path := range expectedPaths {
113+
ctx := new(fasthttp.RequestCtx)
114+
115+
h, _ := r.Lookup("GET", path, ctx)
116+
117+
if h == nil {
118+
t.Errorf("Expected optional path '%s' is not registered", path)
119+
}
120+
}
121+
}
122+
94123
func BenchmarkCleanPathWithBuffer(b *testing.B) {
95124
path := "/../bench/"
96125
cpb := acquireCleanPathBuffer()

router.go

Lines changed: 48 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,10 @@ func New() *Router {
159159
// Group returns a new grouped Router.
160160
// Path auto-correction, including trailing slashes, is enabled by default.
161161
func (r *Router) Group(path string) *Router {
162-
g := &Router{
163-
parent: r,
164-
beginPath: path,
165-
RedirectTrailingSlash: true,
166-
RedirectFixedPath: true,
167-
HandleMethodNotAllowed: true,
168-
HandleOPTIONS: true,
169-
}
162+
g := New()
163+
g.parent = r
164+
g.beginPath = path
165+
170166
return g
171167
}
172168

@@ -205,36 +201,6 @@ func (r *Router) DELETE(path string, handle fasthttp.RequestHandler) {
205201
r.Handle("DELETE", path, handle)
206202
}
207203

208-
// returns all possible paths when the original path has optional arguments
209-
func getOptionalPaths(path string) []string {
210-
paths := make([]string, 0)
211-
212-
index := 0
213-
newParam := false
214-
for i := 0; i < len(path); i++ {
215-
c := path[i]
216-
217-
if c == ':' {
218-
index = i
219-
newParam = true
220-
} else if i > 0 && newParam && c == '?' {
221-
p := strings.Replace(path[:index], "?", "", -1)
222-
if !gotils.StringSliceInclude(paths, p) {
223-
paths = append(paths, p)
224-
}
225-
226-
p = strings.Replace(path[:i], "?", "", -1) + "/"
227-
if !gotils.StringSliceInclude(paths, p) {
228-
paths = append(paths, p)
229-
}
230-
231-
newParam = false
232-
}
233-
}
234-
235-
return paths
236-
}
237-
238204
// Handle registers a new request handle with the given path and method.
239205
//
240206
// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut
@@ -344,12 +310,6 @@ func (r *Router) ServeFilesCustom(path string, fs *fasthttp.FS) {
344310
})
345311
}
346312

347-
func (r *Router) recv(ctx *fasthttp.RequestCtx) {
348-
if rcv := recover(); rcv != nil {
349-
r.PanicHandler(ctx, rcv)
350-
}
351-
}
352-
353313
// Lookup allows the manual lookup of a method + path combo.
354314
// This is e.g. useful to build a framework around this router.
355315
// If the path was found, it returns the handle function and the path parameter
@@ -362,44 +322,6 @@ func (r *Router) Lookup(method, path string, ctx *fasthttp.RequestCtx) (fasthttp
362322
return nil, false
363323
}
364324

365-
func (r *Router) allowed(path, reqMethod string) (allow string) {
366-
if path == "*" || path == "/*" { // server-wide
367-
for method := range r.trees {
368-
if method == "OPTIONS" {
369-
continue
370-
}
371-
372-
// add request method to list of allowed methods
373-
if len(allow) == 0 {
374-
allow = method
375-
} else {
376-
allow += ", " + method
377-
}
378-
}
379-
} else { // specific path
380-
for method := range r.trees {
381-
// Skip the requested method - we already tried this one
382-
if method == reqMethod || method == "OPTIONS" {
383-
continue
384-
}
385-
386-
handle, _ := r.trees[method].getValue(path, nil)
387-
if handle != nil {
388-
// add request method to list of allowed methods
389-
if len(allow) == 0 {
390-
allow = method
391-
} else {
392-
allow += ", " + method
393-
}
394-
}
395-
}
396-
}
397-
if len(allow) > 0 {
398-
allow += ", OPTIONS"
399-
}
400-
return
401-
}
402-
403325
// Handler makes the router implement the fasthttp.ListenAndServe interface.
404326
func (r *Router) Handler(ctx *fasthttp.RequestCtx) {
405327
if r.PanicHandler != nil {
@@ -495,3 +417,47 @@ func (r *Router) Handler(ctx *fasthttp.RequestCtx) {
495417
ctx.Error(fasthttp.StatusMessage(fasthttp.StatusNotFound), fasthttp.StatusNotFound)
496418
}
497419
}
420+
421+
func (r *Router) allowed(path, reqMethod string) (allow string) {
422+
if path == "*" || path == "/*" { // server-wide
423+
for method := range r.trees {
424+
if method == "OPTIONS" {
425+
continue
426+
}
427+
428+
// add request method to list of allowed methods
429+
if len(allow) == 0 {
430+
allow = method
431+
} else {
432+
allow += ", " + method
433+
}
434+
}
435+
} else { // specific path
436+
for method := range r.trees {
437+
// Skip the requested method - we already tried this one
438+
if method == reqMethod || method == "OPTIONS" {
439+
continue
440+
}
441+
442+
handle, _ := r.trees[method].getValue(path, nil)
443+
if handle != nil {
444+
// add request method to list of allowed methods
445+
if len(allow) == 0 {
446+
allow = method
447+
} else {
448+
allow += ", " + method
449+
}
450+
}
451+
}
452+
}
453+
if len(allow) > 0 {
454+
allow += ", OPTIONS"
455+
}
456+
return
457+
}
458+
459+
func (r *Router) recv(ctx *fasthttp.RequestCtx) {
460+
if rcv := recover(); rcv != nil {
461+
r.PanicHandler(ctx, rcv)
462+
}
463+
}

router_test.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -223,33 +223,6 @@ func TestRouterRoot(t *testing.T) {
223223
}
224224
}
225225

226-
func TestRouterOptionalPathArgs(t *testing.T) {
227-
handler := func(ctx *fasthttp.RequestCtx) {
228-
ctx.SetStatusCode(fasthttp.StatusOK)
229-
}
230-
231-
expectedPaths := []string{
232-
"/show/:name/",
233-
"/show/:name/:surname/",
234-
"/show/:name/:surname/at/",
235-
"/show/:name/:surname/at/:address/",
236-
"/show/:name/:surname/at/:address/:id/",
237-
"/show/:name/:surname/at/:address/:id/:phone/",
238-
}
239-
r := New()
240-
r.GET("/show/:name/:surname?/at/:address?/:id/:phone?", handler)
241-
242-
for _, path := range expectedPaths {
243-
ctx := new(fasthttp.RequestCtx)
244-
245-
h, _ := r.Lookup("GET", path, ctx)
246-
247-
if h == nil {
248-
t.Errorf("Expected optional path '%s' is not registered", path)
249-
}
250-
}
251-
}
252-
253226
func TestRouterChaining(t *testing.T) {
254227
r1 := New()
255228
r2 := New()

tree.go

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,30 @@ import (
1414
"github.com/valyala/fasthttp"
1515
)
1616

17+
const (
18+
static nodeType = iota // default
19+
root
20+
param
21+
catchAll
22+
)
23+
24+
type nodeType uint8
25+
1726
type buffer struct {
1827
b []byte
1928
}
2029

30+
type node struct {
31+
path string
32+
wildChild bool
33+
nType nodeType
34+
maxParams uint8
35+
indices string
36+
children []*node
37+
handle fasthttp.RequestHandler
38+
priority uint32
39+
}
40+
2141
var bufferPool = sync.Pool{
2242
New: func() interface{} {
2343
return &buffer{
@@ -55,24 +75,20 @@ func countParams(path string) uint8 {
5575
return uint8(n)
5676
}
5777

58-
type nodeType uint8
59-
60-
const (
61-
static nodeType = iota // default
62-
root
63-
param
64-
catchAll
65-
)
66-
67-
type node struct {
68-
path string
69-
wildChild bool
70-
nType nodeType
71-
maxParams uint8
72-
indices string
73-
children []*node
74-
handle fasthttp.RequestHandler
75-
priority uint32
78+
// shift bytes in array by n bytes left
79+
func shiftNRuneBytes(rb [4]byte, n int) [4]byte {
80+
switch n {
81+
case 0:
82+
return rb
83+
case 1:
84+
return [4]byte{rb[1], rb[2], rb[3], 0}
85+
case 2:
86+
return [4]byte{rb[2], rb[3]}
87+
case 3:
88+
return [4]byte{rb[3]}
89+
default:
90+
return [4]byte{}
91+
}
7692
}
7793

7894
// increments priority of the given child and reorders if necessary
@@ -482,22 +498,6 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) ([]by
482498
return fixedPath, found
483499
}
484500

485-
// shift bytes in array by n bytes left
486-
func shiftNRuneBytes(rb [4]byte, n int) [4]byte {
487-
switch n {
488-
case 0:
489-
return rb
490-
case 1:
491-
return [4]byte{rb[1], rb[2], rb[3], 0}
492-
case 2:
493-
return [4]byte{rb[2], rb[3]}
494-
case 3:
495-
return [4]byte{rb[3]}
496-
default:
497-
return [4]byte{}
498-
}
499-
}
500-
501501
// recursive case-insensitive lookup function used by n.findCaseInsensitivePath
502502
func (n *node) findCaseInsensitivePathRec(path, loPath string, ciPath []byte, rb [4]byte, fixTrailingSlash bool) ([]byte, bool) {
503503
loNPath := toLower(n.path)

0 commit comments

Comments
 (0)