Files
apinto/node/http-context/request-reader.go
2021-11-11 20:23:52 +08:00

152 lines
3.4 KiB
Go

package http_context
import (
"net/http"
"net/url"
"strings"
http_service "github.com/eolinker/eosc/http-service"
"github.com/valyala/fasthttp"
)
var _ http_service.IRequestReader = (*RequestReader)(nil)
type RequestReader struct {
req *fasthttp.Request
bodyHandler *BodyRequestHandler
remoteAddr string
clientIP string
host string
method string
rawBody []byte
headers http.Header
scheme string
uri *url.URL
contentType string
}
func NewRequestReader(req *fasthttp.Request, remoteAddr string) *RequestReader {
return &RequestReader{req: req, remoteAddr: remoteAddr}
}
func (r *RequestReader) ContentType() string {
if r.contentType == "" {
r.contentType = string(r.req.Header.ContentType())
}
return r.contentType
}
func (r *RequestReader) BodyForm() (url.Values, error) {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.BodyForm()
}
func (r *RequestReader) Files() (map[string]*http_service.FileHeader, error) {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.Files()
}
func (r *RequestReader) GetForm(key string) string {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.GetForm(key)
}
func (r *RequestReader) GetFile(key string) (file *http_service.FileHeader, has bool) {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.GetFile(key)
}
func (r *RequestReader) RawBody() ([]byte, error) {
if r.bodyHandler == nil {
r.bodyHandler = newBodyRequestHandler(r.ContentType(), r.req.Body())
}
return r.bodyHandler.RawBody()
}
func (r *RequestReader) GetHeader(name string) string {
return r.Headers().Get(name)
}
func (r *RequestReader) Headers() http.Header {
if r.headers == nil {
r.headers = make(http.Header)
hs := strings.Split(r.req.Header.String(), "\r\n")
for _, h := range hs {
vs := strings.Split(h, ":")
if len(vs) < 2 {
if vs[0] == "" {
continue
}
r.headers[vs[0]] = []string{""}
continue
}
r.headers[vs[0]] = []string{strings.TrimSpace(vs[1])}
}
}
return r.headers
}
func (r *RequestReader) Method() string {
if r.method == "" {
r.method = string(r.req.Header.Method())
}
return r.method
}
func (r *RequestReader) URL() url.URL {
if r.uri == nil {
r.uri, _ = url.Parse(r.req.URI().String())
}
return *r.uri
}
func (r *RequestReader) RequestURI() string {
return string(r.req.RequestURI())
}
func (r *RequestReader) Host() string {
if r.host == "" {
r.host = strings.Split(string(r.req.Header.Host()), ":")[0]
}
return r.host
}
func (r *RequestReader) RemoteAddr() string {
if r.clientIP == "" {
clientIP := string(r.req.Header.Peek("X-Forwarded-For"))
if index := strings.IndexByte(clientIP, ','); index >= 0 {
clientIP = clientIP[0:index]
}
clientIP = strings.TrimSpace(clientIP)
if len(clientIP) < 1 {
clientIP = strings.TrimSpace(string(r.req.Header.Peek("X-Real-Ip")))
if len(clientIP) < 1 {
clientIP = r.remoteAddr
}
}
r.clientIP = clientIP
}
return r.clientIP
}
func (r *RequestReader) Scheme() string {
if r.scheme == "" {
r.scheme = string(r.req.URI().Scheme())
}
return r.scheme
}
func (r *RequestReader) Request() *fasthttp.Request {
return r.req
}