Adding upstream version 2.52.6.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
a960158181
commit
6d002e9543
441 changed files with 95392 additions and 0 deletions
171
middleware/adaptor/adaptor.go
Normal file
171
middleware/adaptor/adaptor.go
Normal file
|
@ -0,0 +1,171 @@
|
|||
package adaptor
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fasthttp"
|
||||
"github.com/valyala/fasthttp/fasthttpadaptor"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
||||
// HTTPHandlerFunc wraps net/http handler func to fiber handler
|
||||
func HTTPHandlerFunc(h http.HandlerFunc) fiber.Handler {
|
||||
return HTTPHandler(h)
|
||||
}
|
||||
|
||||
// HTTPHandler wraps net/http handler to fiber handler
|
||||
func HTTPHandler(h http.Handler) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
handler := fasthttpadaptor.NewFastHTTPHandler(h)
|
||||
handler(c.Context())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertRequest converts a fiber.Ctx to a http.Request.
|
||||
// forServer should be set to true when the http.Request is going to be passed to a http.Handler.
|
||||
func ConvertRequest(c *fiber.Ctx, forServer bool) (*http.Request, error) {
|
||||
var req http.Request
|
||||
if err := fasthttpadaptor.ConvertRequest(c.Context(), &req, forServer); err != nil {
|
||||
return nil, err //nolint:wrapcheck // This must not be wrapped
|
||||
}
|
||||
return &req, nil
|
||||
}
|
||||
|
||||
// CopyContextToFiberContext copies the values of context.Context to a fasthttp.RequestCtx
|
||||
func CopyContextToFiberContext(context interface{}, requestContext *fasthttp.RequestCtx) {
|
||||
contextValues := reflect.ValueOf(context).Elem()
|
||||
contextKeys := reflect.TypeOf(context).Elem()
|
||||
if contextKeys.Kind() == reflect.Struct {
|
||||
var lastKey interface{}
|
||||
for i := 0; i < contextValues.NumField(); i++ {
|
||||
reflectValue := contextValues.Field(i)
|
||||
/* #nosec */
|
||||
reflectValue = reflect.NewAt(reflectValue.Type(), unsafe.Pointer(reflectValue.UnsafeAddr())).Elem()
|
||||
|
||||
reflectField := contextKeys.Field(i)
|
||||
|
||||
if reflectField.Name == "noCopy" {
|
||||
break
|
||||
} else if reflectField.Name == "Context" {
|
||||
CopyContextToFiberContext(reflectValue.Interface(), requestContext)
|
||||
} else if reflectField.Name == "key" {
|
||||
lastKey = reflectValue.Interface()
|
||||
} else if lastKey != nil && reflectField.Name == "val" {
|
||||
requestContext.SetUserValue(lastKey, reflectValue.Interface())
|
||||
} else {
|
||||
lastKey = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPMiddleware wraps net/http middleware to fiber middleware
|
||||
func HTTPMiddleware(mw func(http.Handler) http.Handler) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
var next bool
|
||||
nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
next = true
|
||||
// Convert again in case request may modify by middleware
|
||||
c.Request().Header.SetMethod(r.Method)
|
||||
c.Request().SetRequestURI(r.RequestURI)
|
||||
c.Request().SetHost(r.Host)
|
||||
c.Request().Header.SetHost(r.Host)
|
||||
for key, val := range r.Header {
|
||||
for _, v := range val {
|
||||
c.Request().Header.Set(key, v)
|
||||
}
|
||||
}
|
||||
CopyContextToFiberContext(r.Context(), c.Context())
|
||||
})
|
||||
|
||||
if err := HTTPHandler(mw(nextHandler))(c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if next {
|
||||
return c.Next()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// FiberHandler wraps fiber handler to net/http handler
|
||||
func FiberHandler(h fiber.Handler) http.Handler {
|
||||
return FiberHandlerFunc(h)
|
||||
}
|
||||
|
||||
// FiberHandlerFunc wraps fiber handler to net/http handler func
|
||||
func FiberHandlerFunc(h fiber.Handler) http.HandlerFunc {
|
||||
return handlerFunc(fiber.New(), h)
|
||||
}
|
||||
|
||||
// FiberApp wraps fiber app to net/http handler func
|
||||
func FiberApp(app *fiber.App) http.HandlerFunc {
|
||||
return handlerFunc(app)
|
||||
}
|
||||
|
||||
func handlerFunc(app *fiber.App, h ...fiber.Handler) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// New fasthttp request
|
||||
req := fasthttp.AcquireRequest()
|
||||
defer fasthttp.ReleaseRequest(req)
|
||||
// Convert net/http -> fasthttp request
|
||||
if r.Body != nil {
|
||||
n, err := io.Copy(req.BodyWriter(), r.Body)
|
||||
req.Header.SetContentLength(int(n))
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, utils.StatusMessage(fiber.StatusInternalServerError), fiber.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
req.Header.SetMethod(r.Method)
|
||||
req.SetRequestURI(r.RequestURI)
|
||||
req.SetHost(r.Host)
|
||||
req.Header.SetHost(r.Host)
|
||||
for key, val := range r.Header {
|
||||
for _, v := range val {
|
||||
req.Header.Set(key, v)
|
||||
}
|
||||
}
|
||||
if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil && err.(*net.AddrError).Err == "missing port in address" { //nolint:errorlint, forcetypeassert // overlinting
|
||||
r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80")
|
||||
}
|
||||
remoteAddr, err := net.ResolveTCPAddr("tcp", r.RemoteAddr)
|
||||
if err != nil {
|
||||
http.Error(w, utils.StatusMessage(fiber.StatusInternalServerError), fiber.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// New fasthttp Ctx
|
||||
var fctx fasthttp.RequestCtx
|
||||
fctx.Init(req, remoteAddr, nil)
|
||||
if len(h) > 0 {
|
||||
// New fiber Ctx
|
||||
ctx := app.AcquireCtx(&fctx)
|
||||
defer app.ReleaseCtx(ctx)
|
||||
// Execute fiber Ctx
|
||||
err := h[0](ctx)
|
||||
if err != nil {
|
||||
_ = app.Config().ErrorHandler(ctx, err) //nolint:errcheck // not needed
|
||||
}
|
||||
} else {
|
||||
// Execute fasthttp Ctx though app.Handler
|
||||
app.Handler()(&fctx)
|
||||
}
|
||||
|
||||
// Convert fasthttp Ctx > net/http
|
||||
fctx.Response.Header.VisitAll(func(k, v []byte) {
|
||||
w.Header().Add(string(k), string(v))
|
||||
})
|
||||
w.WriteHeader(fctx.Response.StatusCode())
|
||||
_, _ = w.Write(fctx.Response.Body()) //nolint:errcheck // not needed
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue