blob: a69d9dbc2cdb059475bd402bf5d2a1615bf63d11 [file] [log] [blame] [edit]
// Copyright 2019 Julien Schmidt. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
package httprouter
import (
"net/http"
)
const (
idxGET = iota
idxHEAD
idxPOST
idxPUT
idxPATCH
idxDELETE
idxCONNECT
idxOPTIONS
idxTRACE
idxEnd
)
type customMethod struct {
method string
root *node
}
type methodIndex struct {
roots [idxEnd]*node
custom []customMethod
}
func (m *methodIndex) init(method string) (root *node) {
var idx int
switch method {
case http.MethodGet:
idx = idxGET
case http.MethodPatch:
idx = idxPATCH
case http.MethodPost:
idx = idxPOST
case http.MethodPut:
idx = idxPUT
case http.MethodDelete:
idx = idxDELETE
case http.MethodHead:
idx = idxHEAD
case http.MethodOptions:
idx = idxOPTIONS
case http.MethodConnect:
idx = idxCONNECT
case http.MethodTrace:
idx = idxTRACE
default: // custom methods
for _, c := range m.custom {
if c.method == method {
return c.root
}
}
root = new(node)
m.custom = append(m.custom, customMethod{method, root})
return root
}
root = m.roots[idx]
if root == nil {
root = new(node)
m.roots[idx] = root
}
return root
}
func (m *methodIndex) get(method string) *node {
switch method[0] {
case 'G':
if method == http.MethodGet {
return m.roots[idxGET]
}
case 'P':
switch len(method) {
case 5:
if method == http.MethodPatch {
return m.roots[idxPATCH]
}
case 4:
if method == http.MethodPost {
return m.roots[idxPOST]
}
case 3:
if method == http.MethodPut {
return m.roots[idxPUT]
}
}
case 'D':
if method == http.MethodDelete {
return m.roots[idxDELETE]
}
case 'H':
if method == http.MethodHead {
return m.roots[idxHEAD]
}
case 'O':
if method == http.MethodOptions {
return m.roots[idxOPTIONS]
}
case 'C':
if method == http.MethodConnect {
return m.roots[idxCONNECT]
}
case 'T':
if method == http.MethodTrace {
return m.roots[idxTRACE]
}
}
// custom methods
for _, c := range m.custom {
if c.method == method {
return c.root
}
}
return nil
}