MakyuuIchaival/httputils/context.go
2022-01-18 19:10:57 +01:00

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
}