191 lines
4.3 KiB
Go
191 lines
4.3 KiB
Go
package httputils
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/valyala/fasthttp"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
var fsHandler = (&fasthttp.FS{
|
|
Root: "/",
|
|
AcceptByteRange: true,
|
|
Compress: false,
|
|
CompressBrotli: false,
|
|
CacheDuration: time.Minute * 15,
|
|
PathRewrite: func(ctx *fasthttp.RequestCtx) []byte {
|
|
return ctx.Request.URI().PathOriginal()
|
|
},
|
|
}).NewRequestHandler()
|
|
|
|
type RequestContext struct {
|
|
fasthttp *fasthttp.RequestCtx
|
|
httpWriter *http.ResponseWriter
|
|
httpRequest *http.Request
|
|
server *Server
|
|
connTime time.Time
|
|
requestTime time.Time
|
|
timingEvents uint
|
|
}
|
|
|
|
func NewRequestContextFromFastHttp(server *Server, ctx *fasthttp.RequestCtx) RequestContext {
|
|
return RequestContext{
|
|
fasthttp: ctx,
|
|
connTime: ctx.ConnTime(),
|
|
requestTime: ctx.Time(),
|
|
server: server,
|
|
}
|
|
}
|
|
|
|
func NewRequestContextFromHttp(server *Server, w http.ResponseWriter, r *http.Request) RequestContext {
|
|
return RequestContext{
|
|
httpWriter: &w,
|
|
httpRequest: r,
|
|
connTime: time.Now(),
|
|
requestTime: time.Now(),
|
|
server: server,
|
|
}
|
|
}
|
|
|
|
func (c *RequestContext) GetExtraHeaders() map[string]string {
|
|
return c.server.GetExtraHeaders()
|
|
}
|
|
|
|
func (c *RequestContext) AddTiming(name string, desc string, d time.Duration) {
|
|
if d < 0 {
|
|
d = 0
|
|
}
|
|
|
|
c.addResponseHeader("Server-Timing", fmt.Sprintf("%d_%s;desc=\"%s\";dur=%.6F", c.timingEvents, name, desc, float64(d.Nanoseconds())/1e6))
|
|
c.timingEvents++
|
|
}
|
|
|
|
func (c *RequestContext) AddTimingInformational(name string, desc string) {
|
|
c.addResponseHeader("Server-Timing", fmt.Sprintf("%d_%s;desc=\"%s\"", c.timingEvents, name, desc))
|
|
c.timingEvents++
|
|
}
|
|
|
|
func (c *RequestContext) getPath() string {
|
|
if c.fasthttp != nil {
|
|
return string(c.fasthttp.Path())
|
|
} else if c.httpRequest != nil {
|
|
return c.httpRequest.URL.Path
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func (c *RequestContext) getConnectionTime() time.Time {
|
|
return c.connTime
|
|
}
|
|
|
|
func (c *RequestContext) getRequestTime() time.Time {
|
|
return c.requestTime
|
|
}
|
|
|
|
func (c *RequestContext) isFastHttp() bool {
|
|
return c.fasthttp != nil
|
|
}
|
|
|
|
func (c *RequestContext) getTLSServerName() string {
|
|
if c.fasthttp != nil {
|
|
return c.fasthttp.TLSConnectionState().ServerName
|
|
} else if c.httpRequest != nil {
|
|
return c.httpRequest.TLS.ServerName
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func (c *RequestContext) getRequestHeader(name string) string {
|
|
if c.fasthttp != nil {
|
|
return string(c.fasthttp.Request.Header.Peek(name))
|
|
} else if c.httpRequest != nil {
|
|
return c.httpRequest.Header.Get(name)
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func (c *RequestContext) getResponseHeader(name string) string {
|
|
if c.fasthttp != nil {
|
|
return string(c.fasthttp.Response.Header.Peek(name))
|
|
} else if c.httpWriter != nil {
|
|
return (*c.httpWriter).Header().Get(name)
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func (c *RequestContext) addResponseHeader(name string, value string) {
|
|
if c.fasthttp != nil {
|
|
c.fasthttp.Response.Header.Add(name, value)
|
|
} else if c.httpWriter != nil {
|
|
(*c.httpWriter).Header().Add(name, value)
|
|
}
|
|
}
|
|
|
|
func (c *RequestContext) setResponseHeader(name string, value string) {
|
|
if c.fasthttp != nil {
|
|
c.fasthttp.Response.Header.Set(name, value)
|
|
} else if c.httpWriter != nil {
|
|
(*c.httpWriter).Header().Set(name, value)
|
|
}
|
|
}
|
|
|
|
func (c *RequestContext) serveFile(path string) {
|
|
if c.fasthttp != nil {
|
|
c.fasthttp.Request.URI().Reset()
|
|
c.fasthttp.Request.URI().SetPath(path)
|
|
fsHandler(c.fasthttp)
|
|
} else if c.httpWriter != nil {
|
|
http.ServeFile(*c.httpWriter, c.httpRequest, path)
|
|
}
|
|
}
|
|
|
|
func (c *RequestContext) setResponseCode(code int) {
|
|
if c.fasthttp != nil {
|
|
c.fasthttp.Response.SetStatusCode(code)
|
|
} else if c.httpWriter != nil {
|
|
(*c.httpWriter).WriteHeader(code)
|
|
}
|
|
}
|
|
|
|
func (c *RequestContext) doRedirect(location string, code int) {
|
|
if c.fasthttp != nil {
|
|
c.fasthttp.Redirect(location, code)
|
|
} else if c.httpWriter != nil {
|
|
http.Redirect(*c.httpWriter, c.httpRequest, location, code)
|
|
}
|
|
}
|
|
|
|
func (c *RequestContext) isGet() bool {
|
|
if c.fasthttp != nil {
|
|
return c.fasthttp.IsGet()
|
|
} else if c.httpRequest != nil {
|
|
return c.httpRequest.Method == "GET"
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (c *RequestContext) isOptions() bool {
|
|
if c.fasthttp != nil {
|
|
return c.fasthttp.IsOptions()
|
|
} else if c.httpRequest != nil {
|
|
return c.httpRequest.Method == "OPTIONS"
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (c *RequestContext) isHead() bool {
|
|
if c.fasthttp != nil {
|
|
return c.fasthttp.IsHead()
|
|
} else if c.httpRequest != nil {
|
|
return c.httpRequest.Method == "HEAD"
|
|
}
|
|
|
|
return false
|
|
}
|