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 }