erouter

package module
v0.0.0-...-40ba262 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2019 License: MIT Imports: 6 Imported by: 0

README

erouter

Go Report Card GoDoc

erouter是高性能高扩展http路由库,具有零内存复制、严格路由匹配顺序、代码复制度低、组路由、中间件功能、默认参数、常量匹配、变量匹配、通配符匹配、变量校验匹配、通配符校验匹配、基于Host路由这些特点功能。

设计说明

基于eudore框架路由分离,修改中间件机制并移除MVC。

RouterRadix

RouterRadix使用基数树实现,具有零内存复制、严格路由匹配顺序、组路由、中间件功能、默认参数、常量匹配、变量匹配、通配符匹配功能。

example:

package main

import "log"
import "net/http"
import "github.com/eudore/erouter"

func main() {
	router := erouter.NewRouterRadix()
	router.AddMiddleware("ANY", "", func(h erouter.Handler) erouter.Handler {
		return func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
			log.Printf("%s %s route: %s", r.Method, r.URL.Path, p.GetParam("route"))
			h(w, r, p)
		}
	})
	router.Any("/*", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("hello\n"))
	})
	router.Get("/api/*action version=v0", func(w http.ResponseWriter, _ *http.Request, p erouter.Params) {
		w.Write([]byte("access api " + p.GetParam("version") +": " + p.GetParam("action") + "\n"))
	})
	router.Get("/api/v1/*action version=v1", func(w http.ResponseWriter, _ *http.Request, p erouter.Params) {
		w.Write([]byte("access api " + p.GetParam("version") +": " + p.GetParam("action") + "\n"))
	})
	apiv2 := router.Group("/api/v2 version=v2")
	apiv2.Any("/*action", func(w http.ResponseWriter, _ *http.Request, p erouter.Params) {
		w.Write([]byte("access api " + p.GetParam("version") +": " + p.GetParam("action") + "\n"))
	})
	http.ListenAndServe(":8080", router)
}

测试命令:

curl 127.0.0.1:8080/get
curl 127.0.0.1:8080/api/getuser
curl 127.0.0.1:8080/api/v1/getuser
curl 127.0.0.1:8080/api/v2/getuser

RouterFull

RouterFull基于RouterRadix扩展,实现变量校验匹配、通配符校验匹配功能。

用法:在正常变量和通配符后,使用'|'符号分割,后为校验规则,isnum是校验函数;min:100为动态检验函数,min是动态校验函数名称,':'后为参数;如果为'^'开头为正则校验,并且要使用'$'作为结尾。

注意: 正则表达式不要使用空格,会导致参数切割错误,使用\u002代替空格。

:num|isnum
:num|min:100
:num|^0.*$
*num|isnum
*num|min:100
*num|^0.*$

example:

package main

import "net/http"
import "github.com/eudore/erouter"

func main() {
	router := erouter.NewRouterFull()
	router.Any("/*", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("hello\n"))
	})
	router.Get("/:num|^0.*$", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("first char is '0', num is: " + p.GetParam("num") + "\n"))
	})
	router.Get("/:num|min:100", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("num great 100, num is: " + p.GetParam("num") + "\n"))
	})
	router.Get("/:num|isnum", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("num is: " + p.GetParam("num") + "\n"))
	})
	router.Get("/*var|^E.*$", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("first char is 'E', var is: " + p.GetParam("var") + "\n"))
	})
	http.ListenAndServe(":8080", router)
}

测试命令:

curl 127.0.0.1:8080/get
curl 127.0.0.1:8080/012
curl 127.0.0.1:8080/123
curl 127.0.0.1:8080/12
curl 127.0.0.1:8080/Erouter/123

RouterHost

RouterHost基于Host匹配,通过选择Host对应子路由器执行注册和匹配,实现基于Host路由功能。

当前使用遍历匹配,Host匹配函数为path.Match,未来匹配规则仅保留'*'通配符和常量。

用法:需要给Host路由器注册域名规则下的子路由器,注册路由时使用host参数匹配注册的路由器添加路由,匹配时使用请求的Host来匹配注册的路由。

example:

package main

import "net/http"
import "github.com/eudore/erouter"

func main() {
	router := erouter.NewRouterHost().(*erouter.RouterHost)
	router.RegisterHost("*.example.com", erouter.NewRouterRadix())
	router.Any("/*", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("hello\n"))
	})
	router.Get("/* host=*.example.com", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("host is " + r.Host + ", match host: " + p.GetParam("host") + "\n"))
	})
	http.ListenAndServe(":8080", router)
}

测试命令:

curl 127.0.0.1:8080
curl -XPUT 127.0.0.1:8080
curl -H 'Host: www.example.com' 127.0.0.1:8080
curl -H 'Host: www.example.com' -XPUT 127.0.0.1:8080
curl -H 'Host: www.example.com' -Xput 127.0.0.1:8080

Middleware

package main

import (
	"net/http"
	"github.com/eudore/erouter"
	"github.com/eudore/erouter/middleware"
)

func main() {
	router := erouter.NewRouterRadix()
	router.AddMiddleware("ANY", "", 
		middleware.NewLoggerFunc(),
		middleware.NewCors(nil, map[string]string{
			"Access-Control-Allow-Credentials": "true",
			"Access-Control-Allow-Headers": "Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Parent-Id",	
			"Access-Control-Expose-Headers": "X-Request-Id",
			"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, HEAD",
			"Access-Control-Max-Age": "1000",
		}).NewMiddleware(),
		middleware.NewCircuitBreaker().InjectRoutes(router.Group("/debug/breaker")).NewMiddleware(),
		middleware.NewRate(10, 30).NewMiddleware(),
	)
	router.Any("/*", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		w.Write([]byte("hello\n"))
	})
	router.Get("/api/*action version=v0", func(w http.ResponseWriter, _ *http.Request, p erouter.Params) {
		w.Write([]byte("access api " + p.GetParam("version") +": " + p.GetParam("action") + "\n"))
	})
	router.Get("/api/v1/*action version=v1", func(w http.ResponseWriter, _ *http.Request, p erouter.Params) {
		w.Write([]byte("access api " + p.GetParam("version") +": " + p.GetParam("action") + "\n"))
	})
	apiv2 := router.Group("/api/v2 version=v2")
	apiv2.Any("/*action", func(w http.ResponseWriter, _ *http.Request, p erouter.Params) {
		w.Write([]byte("access api " + p.GetParam("version") +": " + p.GetParam("action") + "\n"))
	})
	http.ListenAndServe(":8080", router)
}

Benchmark

使用GithubApi进行Benchmark性能测试,Erouter匹配性能静态路由具有httprouter的70%,api匹配性能具有90%且内存分配仅消耗httprouter六分之一,但是具有严格路由匹配顺序、易扩展重写和代码复杂度低的特点。

测试命令:

go get github.com/eudore/web-framework-benchmark
go test -bench=router github.com/eudore/web-framework-benchmark

测试结果:

goos: linux
goarch: amd64
pkg: github.com/eudore/web-framework-benchmark
BenchmarkHttprouterStatic-2        	   50000	     25686 ns/op	    1949 B/op	     157 allocs/op
BenchmarkHttprouterGitHubAPI-2     	   30000	     52997 ns/op	   16571 B/op	     370 allocs/op
BenchmarkHttprouterGplusAPI-2      	  500000	      2570 ns/op	     813 B/op	      24 allocs/op
BenchmarkHttprouterParseAPI-2      	  500000	      3791 ns/op	     986 B/op	      42 allocs/op
BenchmarkErouterRadixStatic-2      	   50000	     34314 ns/op	    1950 B/op	     157 allocs/op
BenchmarkErouterRadixGitHubAPI-2   	   30000	     57850 ns/op	    2786 B/op	     203 allocs/op
BenchmarkErouterRadixGplusAPI-2    	  500000	      2468 ns/op	     173 B/op	      13 allocs/op
BenchmarkErouterRadixParseAPI-2    	  300000	      4551 ns/op	     323 B/op	      26 allocs/op
BenchmarkErouterFullStatic-2       	   50000	     34728 ns/op	    1950 B/op	     157 allocs/op
BenchmarkErouterFullGitHubAPI-2    	   30000	     62151 ns/op	    2787 B/op	     203 allocs/op
BenchmarkErouterFullGplusAPI-2     	  500000	      2570 ns/op	     173 B/op	      13 allocs/op
BenchmarkErouterFullParseAPI-2     	  300000	      4362 ns/op	     323 B/op	      26 allocs/op
PASS
ok  	github.com/eudore/web-framework-benchmark	22.356s

Api

列出了主要使用的方法,具体参考文档

Router接口定义:

type (
	// Params读写请求处理中的参数。
	Params interface {
		GetParam(string) string
		AddParam(string, string)
		SetParam(string, string)
	}
	// Erouter处理一个请求的方法,在http.HandlerFunc基础上增加了Parmas。
	Handler func(http.ResponseWriter, *http.Request, Params)
	// 定义请求处理中间件函数,通过传入处理然后返回一个处理,使用装饰器组装处理请求。
	Middleware func(Handler) Handler
	// The route is directly registered by default. Other methods can be directly registered using the RouterRegister interface.
	//
	// 路由默认直接注册的方法,其他方法可以使用RouterRegister接口直接注册。
	RouterMethod interface {
		Group(string) RouterMethod
		AddHandler(string, string, Handler) RouterMethod
		AddMiddleware(string, string, ...Middleware) RouterMethod
		NotFound(Handler)
		MethodNotAllowed(Handler)
		Any(string, Handler)
		Delete(string, Handler)
		Get(string, Handler)
		Head(string, Handler)
		Options(string, Handler)
		Patch(string, Handler)
		Post(string, Handler)
		Put(string, Handler)
	}
	// Router core interface, performing routing, middleware registration, and processing http requests.
	//
	// 路由器核心接口,执行路由、中间件的注册和处理http请求。
	RouterCore interface {
		RegisterMiddleware(string, string, []Middleware)
		RegisterHandler(string, string, Handler)
		ServeHTTP(http.ResponseWriter, *http.Request)
	}
	// The router interface needs to implement two methods: the router method and the router core.
	//
	// 路由器接口,需要实现路由器方法、路由器核心两个接口。
	Router interface {
		RouterCore
		RouterMethod
	}
)

NewRouter

当前拥有三种实现,每种路由器都实现了Router接口。

func NewRouterRadix() Router
func NewRouterFull() Router
func NewRouterHost() Router
router1 := erouter.NewRouterRadix()
router2 := erouter.NewRouterFull()
router3 := erouter.NewRouterHost()

Group

func Group(path string) RouterMethod

Group实现路由器分组。

router := erouter.NewRouterRadix()
apiv1 := router.Group("/api/v1 version=v1")
apiv1.Get("/*", ...)

AddHandler

func AddHandler(method string, path string, handler Handler) RouterMethod

AddHandler用于添加新路由。

router := erouter.NewRouterRadix()
router.AddHandle("GET", "/*", ...)

AddMiddleware

func AddMiddleware(method string, path string, midds ...Middleware) RouterMethod

AddMiddleware给当前路由方法添加处理中间件。

router := erouter.NewRouterRadix()
router.AddMiddleware("ANY", "", func(h erouter.Handler) erouter.Handler {
	return func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
		// befor执行
		...
		// 调用next处理汇总函数
		h(w, r, p)
		// after执行
		...
	}
})

NotFound

func NotFound(Handler)

设置路由器404处理。

MethodNotAllowed

func MethodNotAllowed(Handler)

设置路由器405处理。

Any

func Any(path string, handler Handler)

注册Any方法,相当于AddHandler的方法为"ANY"。

Any方法的集合为erouter.RouterAllMethod,扩展新方法Radix和Full不支持。

Get

func Get(path string, handler Handler)

注册Get方法,相当于AddHandler的方法为"GET",post、put等方法函数类似。

router := erouter.NewRouterRadix()
router.Get("/*", func(w http.ResponseWriter, r *http.Request, p erouter.Params) {
	// 执行处理
})

Documentation

Index

Constants

View Source
const (
	MethodAny     = "ANY"
	MethodGet     = "GET"
	MethodPost    = "POST"
	MethodPut     = "PUT"
	MethodDelete  = "DELETE"
	MethodHead    = "HEAD"
	MethodPatch   = "PATCH"
	MethodOptions = "OPTIONS"
	MethodConnect = "CONNECT"
	MethodTrace   = "TRACE"
)

默认http请求方法

Variables

View Source
var (
	// ParamRoute 是路由参数键值
	ParamRoute = "route"
	// Page404 是404返回的body
	Page404 = []byte("404 page not found\n")
	// Page405 是405返回的body
	Page405 = []byte("405 method not allowed\n")
	// RouterAllMethod 是默认Any的全部方法
	RouterAllMethod = []string{MethodGet, MethodPost, MethodPut, MethodDelete, MethodHead, MethodPatch, MethodOptions}
)

Functions

func SetRouterCheckFunc

func SetRouterCheckFunc(name string, fn RouterCheckFunc)

SetRouterCheckFunc 保存一个RouterCheckFunc函数,用于参数校验使用。

func SetRouterNewCheckFunc

func SetRouterNewCheckFunc(name string, fn RouterNewCheckFunc)

SetRouterNewCheckFunc 保存一个RouterNewCheckFunc函数,用于参数动态校验使用。

Types

type Handler

type Handler func(http.ResponseWriter, *http.Request, Params)

Handler 是Erouter处理一个请求的方法,在http.HandlerFunc基础上增加了Parmas。

func CombineHandler

func CombineHandler(handler Handler, m []Middleware) Handler

CombineHandler 合并全部中间件处理函数。

func NewHandler

func NewHandler(i interface{}) Handler

NewHandler 根据http.Handler和http.HandlerFunc返回erouter.Handler

type Middleware

type Middleware func(Handler) Handler

Middleware 定义请求处理中间件函数,通过传入处理然后返回一个处理,使用装饰器组装处理请求。

type Params

type Params interface {
	GetParam(string) string
	AddParam(string, string)
	SetParam(string, string)
}

Params 读写请求处理中的参数。

type ParamsArray

type ParamsArray struct {
	Keys []string
	Vals []string
}

ParamsArray 默认参数实现,使用数组保存键值对。

func (*ParamsArray) AddParam

func (p *ParamsArray) AddParam(key string, val string)

AddParam 追加一个参数的值。

func (*ParamsArray) GetParam

func (p *ParamsArray) GetParam(key string) string

GetParam 读取参数的值,如果不存在返回空字符串。

func (*ParamsArray) Reset

func (p *ParamsArray) Reset()

Reset 清空数组,配合sync.Pool减少GC。

func (*ParamsArray) SetParam

func (p *ParamsArray) SetParam(key string, val string)

SetParam 设置一个参数的值。

type Router

type Router interface {
	RouterCore
	RouterMethod
}

Router interface needs to implement two methods: the router method and the router core.

路由器接口,需要实现路由器方法、路由器核心两个接口。

func NewRouterFull

func NewRouterFull() Router

NewRouterFull 创建一个Full路由器,基于基数数实现,使用Radix路由器扩展,新增参数校验功能。

func NewRouterHost

func NewRouterHost() Router

NewRouterHost 创建一个Host路由器,默认子路由器为Radix,其他Host匹配需要将Router类型转换成*RouterHost,然后使用RegisterHost方法注册。

func NewRouterRadix

func NewRouterRadix() Router

NewRouterRadix 创建一个Radix路由器,基于基数数实现基本路由器功能。

type RouterCheckFunc

type RouterCheckFunc func(string) bool

RouterCheckFunc Route data validation function to check if a string parameter is valid.

RouterCheckFunc路由数据校验函数,检查一个字符串参数是否有效。

func GetRouterCheckFunc

func GetRouterCheckFunc(name string) RouterCheckFunc

GetRouterCheckFunc 获得一个RouterCheckFunc函数

type RouterCore

type RouterCore interface {
	RegisterMiddleware(string, string, []Middleware)
	RegisterHandler(string, string, Handler)
	ServeHTTP(http.ResponseWriter, *http.Request)
}

RouterCore interface, performing routing, middleware registration, and processing http requests.

路由器核心接口,执行路由、中间件的注册和处理http请求。

type RouterFull

type RouterFull struct {
	RouterMethod
	// contains filtered or unexported fields
}

RouterFull is implemented based on the radix tree to implement all router related features.

Based on the RouterRadix extension, RouterFull implements variable check matching and wildcard check matching.

RouterFull基于基数树实现,实现全部路由器相关特性。

RouterFull基于RouterRadix扩展,实现变量校验匹配、通配符校验匹配功能。

func (*RouterFull) Match

func (r *RouterFull) Match(method, path string, params Params) Handler

Match a request, if the method does not allow direct return to node405, no match returns node404.

匹配一个请求,如果方法不不允许直接返回node405,未匹配返回node404。

func (*RouterFull) RegisterHandler

func (r *RouterFull) RegisterHandler(method string, path string, handler Handler)

RegisterHandler Register a new method request path to the router

The router matches the handlers available to the current path from the middleware tree and adds them to the front of the handler.

RegisterHandler给路由器注册一个新的方法请求路径

路由器会从中间件树中匹配当前路径可使用的处理者,并添加到处理者前方。

func (*RouterFull) RegisterMiddleware

func (r *RouterFull) RegisterMiddleware(method, path string, hs []Middleware)

RegisterMiddleware Register the middleware into the middleware tree and append the handler if it exists.

If the method is not empty, the path is empty and the modified path is '/'.

RegisterMiddleware注册中间件到中间件树中,如果存在则追加处理者。

如果方法非空,路径为空,修改路径为'/'。

func (*RouterFull) ServeHTTP

func (r *RouterFull) ServeHTTP(w http.ResponseWriter, req *http.Request)

实现http.Handler接口,进行路由匹配并处理http请求。

type RouterHost

type RouterHost struct {
	RouterMethod
	Default Router
	Hosts   []string
	Routers []Router
}

RouterHost 基于Host匹配进行路由。

func (*RouterHost) RegisterHandler

func (r *RouterHost) RegisterHandler(method string, path string, handler Handler)

RegisterHandler 从路径参数中获得host参数,选择对应子路由器注册新路由。

func (*RouterHost) RegisterHost

func (r *RouterHost) RegisterHost(host string, router Router)

RegisterHost 给Host路由器注册域名的子路由器。

如果host为空字符串,设置为默认子路由器。

func (*RouterHost) RegisterMiddleware

func (r *RouterHost) RegisterMiddleware(method, path string, hs []Middleware)

RegisterMiddleware 从路径参数中获得host参数,选择对应子路由器注册中间件函数。

func (*RouterHost) ServeHTTP

func (r *RouterHost) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP 获取请求的Host匹配对应子路由器处理http请求。

type RouterMethod

type RouterMethod interface {
	Group(string) RouterMethod
	AddHandler(string, string, Handler) RouterMethod
	AddMiddleware(string, string, ...Middleware) RouterMethod
	NotFound(Handler)
	MethodNotAllowed(Handler)
	Any(string, Handler)
	Delete(string, Handler)
	Get(string, Handler)
	Head(string, Handler)
	Options(string, Handler)
	Patch(string, Handler)
	Post(string, Handler)
	Put(string, Handler)
}

RouterMethod route is directly registered by default. Other methods can be directly registered using the RouterRegister interface.

路由默认直接注册的方法,其他方法可以使用RouterRegister接口直接注册。

type RouterMethodStd

type RouterMethodStd struct {
	RouterCore
	// contains filtered or unexported fields
}

RouterMethodStd 默认路由器方法添加一个实现

func (*RouterMethodStd) AddHandler

func (m *RouterMethodStd) AddHandler(method, path string, hs Handler) RouterMethod

AddHandler 添加一个新路由。

方法和RegisterHandler方法的区别在于AddHandler方法不会继承Group的路径和参数信息,AddMiddleware相同。

func (*RouterMethodStd) AddMiddleware

func (m *RouterMethodStd) AddMiddleware(method, path string, hs ...Middleware) RouterMethod

AddMiddleware 给路由器添加一个中间件函数。

func (*RouterMethodStd) Any

func (m *RouterMethodStd) Any(path string, h Handler)

Any Router Register handler。

func (*RouterMethodStd) Delete

func (m *RouterMethodStd) Delete(path string, h Handler)

Delete 添加一个DELETE方法请求处理。

func (*RouterMethodStd) Get

func (m *RouterMethodStd) Get(path string, h Handler)

Get 添加一个GET方法请求处理。

func (*RouterMethodStd) Group

func (m *RouterMethodStd) Group(path string) RouterMethod

Group 返回一个组路由方法。

func (*RouterMethodStd) Head

func (m *RouterMethodStd) Head(path string, h Handler)

Head 添加一个HEAD方法请求处理。

func (*RouterMethodStd) MethodNotAllowed

func (m *RouterMethodStd) MethodNotAllowed(h Handler)

MethodNotAllowed 设置405处理。

func (*RouterMethodStd) NotFound

func (m *RouterMethodStd) NotFound(h Handler)

NotFound 设置404处理。

func (*RouterMethodStd) Options

func (m *RouterMethodStd) Options(path string, h Handler)

Options 添加一个OPTIONS方法请求处理。

func (*RouterMethodStd) Patch

func (m *RouterMethodStd) Patch(path string, h Handler)

Patch 添加一个PATCH方法请求处理。

func (*RouterMethodStd) Post

func (m *RouterMethodStd) Post(path string, h Handler)

Post 添加一个POST方法请求处理。

func (*RouterMethodStd) Put

func (m *RouterMethodStd) Put(path string, h Handler)

Put 添加一个PUT方法请求处理。

type RouterNewCheckFunc

type RouterNewCheckFunc func(string) RouterCheckFunc

RouterNewCheckFunc Routing data validation function creation function

Construct a new validation function by specifying a string.

RouterNewCheckFunc路由数据校验函数的创建函数

通过指定字符串构造出一个新的校验函数。

func GetRouterNewCheckFunc

func GetRouterNewCheckFunc(name string) RouterNewCheckFunc

GetRouterNewCheckFunc 获得一个RouterNewCheckFunc函数

type RouterRadix

type RouterRadix struct {
	RouterMethod
	// contains filtered or unexported fields
}

RouterRadix Basic function router based on radix tree implementation.

Features such as zero memory copy, strict route matching order, group routing, middleware function, default parameters, constant matching, variable matching, wildcard matching, variable check matching, wildcard check matching, and host routing. // 基于基数树实现的基本功能路由器。

RouterRadix基于基数树实现基本的路由器功能。

具有零内存复制、严格路由匹配顺序、组路由、中间件功能、默认参数、常量匹配、变量匹配、通配符匹配、变量校验匹配、通配符校验匹配、基于Host路由这些特点功能。

func (*RouterRadix) Match

func (r *RouterRadix) Match(method, path string, params Params) Handler

Match a request, if the method does not allow direct return to node405, no match returns node404.

匹配一个请求,如果方法不不允许直接返回node405,未匹配返回node404。

func (*RouterRadix) RegisterHandler

func (r *RouterRadix) RegisterHandler(method string, path string, handler Handler)

RegisterHandler method register a new method request path to the router

The router matches the handlers available to the current path from the middleware tree and adds them to the front of the handler.

RegisterHandler给路由器注册一个新的方法请求路径

路由器会从中间件树中匹配当前路径可使用的处理者,并添加到处理者前方。

func (*RouterRadix) RegisterMiddleware

func (r *RouterRadix) RegisterMiddleware(method, path string, hs []Middleware)

RegisterMiddleware method register the middleware into the middleware tree and append the handler if it exists.

If the method is not empty, the path is empty and the modified path is '/'.

RegisterMiddleware注册中间件到中间件树中,如果存在则追加处理者。

如果方法非空,路径为空,修改路径为'/'。

func (*RouterRadix) ServeHTTP

func (r *RouterRadix) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP 实现http.Handler接口,进行路由匹配并处理http请求。

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL