cubefs

Форк
0
170 строк · 5.7 Кб
1
// Copyright 2022 The CubeFS Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
14

15
package rpc
16

17
import (
18
	"net/http"
19
	"reflect"
20
	"runtime"
21

22
	"github.com/julienschmidt/httprouter"
23

24
	"github.com/cubefs/cubefs/blobstore/util/log"
25
)
26

27
type (
28
	// Router router with interceptors
29
	// Interceptor is middleware for http serve but named `interceptor`.
30
	// Middleware within this Router called `interceptor`.
31
	//
32
	// headMiddlewares is middlewares run firstly.
33
	// Running order is:
34
	//     headMiddlewares --> middlewares --> interceptors --> handler
35
	//
36
	// example:
37
	// router := New()
38
	// router.Use(interceptor1, interceptor2)
39
	// router.Handle(http.MethodGet, "/get/:name", handlerGet)
40
	// router.Handle(http.MethodPut, "/put/:name", handlerPut)
41
	Router struct {
42
		Router          *httprouter.Router // router
43
		hasMiddleware   bool               // true if the router with Middleware*
44
		headMiddlewares []ProgressHandler  // middlewares run firstly of all
45
		headHandler     http.HandlerFunc   // run this handler if has no middlewares
46
		interceptors    []HandlerFunc      // interceptors after middlewares
47
	}
48
)
49

50
// ServeHTTP makes the router implement the http.Handler interface.
51
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
52
	if !r.hasMiddleware {
53
		r.headHandler(w, req)
54
		return
55
	}
56
	r.Router.ServeHTTP(w, req)
57
}
58

59
// DefaultRouter default router for server
60
var DefaultRouter *Router
61

62
func init() {
63
	initDefaultRouter()
64
}
65

66
func initDefaultRouter() {
67
	DefaultRouter = New()
68
	DefaultRouter.Router.PanicHandler = defaultRecovery
69
}
70

71
// New alias of httprouter.New
72
// Return a Router, control by yourself
73
func New() *Router {
74
	r := &Router{
75
		Router:          httprouter.New(),
76
		hasMiddleware:   false,
77
		headMiddlewares: []ProgressHandler{&crcDecoder{}},
78
	}
79
	r.headHandler = buildHTTPHandler(r.Router.ServeHTTP, r.headMiddlewares...)
80
	return r
81
}
82

83
// Use attaches a global interceptor to the router.
84
// You should Use interceptor before register handler.
85
// It is sorted by registered order.
86
func (r *Router) Use(interceptors ...HandlerFunc) {
87
	if len(r.interceptors)+len(interceptors) >= int(abortIndex) {
88
		panic("too many regiter handlers")
89
	}
90
	r.interceptors = append(r.interceptors, interceptors...)
91
}
92

93
// Handle registers a new request handle with the given path and method.
94
//
95
// For HEAD, GET, POST, PUT, PATCH and DELETE requests the respective shortcut
96
// functions can be used.
97
func (r *Router) Handle(method, path string, handler HandlerFunc, opts ...ServerOption) {
98
	// Notice: in golang, sentence [ sliceA := append(sliceA, item) ]
99
	// the pointer of sliceA is the pointer of sliceB, if sliceB has enough capacity.
100
	// so we need make a new slice.
101
	handlers := make([]HandlerFunc, 0, len(r.interceptors)+1)
102
	handlers = append(handlers, r.interceptors...)
103
	handlers = append(handlers, handler)
104
	if len(handlers) >= int(abortIndex) {
105
		panic("too many regiter handlers")
106
	}
107
	r.Router.Handle(method, path, makeHandler(handlers, opts...))
108

109
	opt := new(serverOptions)
110
	for _, o := range opts {
111
		o.apply(opt)
112
	}
113
	icnames := make([]string, 0, len(r.interceptors))
114
	for _, ic := range r.interceptors {
115
		icnames = append(icnames, runtime.FuncForPC(reflect.ValueOf(ic).Pointer()).Name())
116
	}
117
	name := runtime.FuncForPC(reflect.ValueOf(handler).Pointer()).Name()
118
	log.Infof("register handler method:%s, path:%s, interceptors:%s, handler:%s, opts:%+v",
119
		method, path, icnames, name, opt)
120
}
121

122
// Use attaches a global interceptor to the default router.
123
// You should Use interceptor before register handler.
124
// It is sorted by registered order.
125
func Use(interceptors ...HandlerFunc) {
126
	DefaultRouter.interceptors = append(DefaultRouter.interceptors, interceptors...)
127
}
128

129
// HEAD is a shortcut for Handle(http.MethodHead, path, handle)
130
func HEAD(path string, handler HandlerFunc, opts ...ServerOption) {
131
	Handle(http.MethodHead, path, handler, opts...)
132
}
133

134
// GET is a shortcut for Handle(http.MethodGet, path, handle)
135
func GET(path string, handler HandlerFunc, opts ...ServerOption) {
136
	Handle(http.MethodGet, path, handler, opts...)
137
}
138

139
// POST is a shortcut for Handle(http.MethodPost, path, handle)
140
func POST(path string, handler HandlerFunc, opts ...ServerOption) {
141
	Handle(http.MethodPost, path, handler, opts...)
142
}
143

144
// PUT is a shortcut for Handle(http.MethodPut, path, handle)
145
func PUT(path string, handler HandlerFunc, opts ...ServerOption) {
146
	Handle(http.MethodPut, path, handler, opts...)
147
}
148

149
// DELETE is a shortcut for Handle(http.MethodDelete, path, handle)
150
func DELETE(path string, handler HandlerFunc, opts ...ServerOption) {
151
	Handle(http.MethodDelete, path, handler, opts...)
152
}
153

154
// OPTIONS is a shortcut for Handle(http.MethodOptions, path, handle)
155
func OPTIONS(path string, handler HandlerFunc, opts ...ServerOption) {
156
	Handle(http.MethodOptions, path, handler, opts...)
157
}
158

159
// PATCH is a shortcut for Handle(http.MethodPatch, path, handle)
160
func PATCH(path string, handler HandlerFunc, opts ...ServerOption) {
161
	Handle(http.MethodPatch, path, handler, opts...)
162
}
163

164
// Handle registers a new request handle with the given path and method.
165
//
166
// For HEAD, GET, POST, PUT, PATCH and DELETE requests the respective shortcut
167
// functions can be used.
168
func Handle(method, path string, handler HandlerFunc, opts ...ServerOption) {
169
	DefaultRouter.Handle(method, path, handler, opts...)
170
}
171

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.