20 Star 167 Fork 29

qiqi/orange

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
input.go 8.45 KB
一键复制 编辑 原始数据 按行查看 历史
package request
import (
"bytes"
"errors"
"fmt"
"io"
"net"
"net/http"
"regexp"
"strings"
)
// TODO make sure these are correct
var (
maxParam = 50
acceptsHTMLRegex = regexp.MustCompile(`(text/html|application/xhtml\+xml)(?:,|$)`)
acceptsXMLRegex = regexp.MustCompile(`(application/xml|text/xml)(?:,|$)`)
acceptsJSONRegex = regexp.MustCompile(`(application/json)(?:,|$)`)
)
type OrangeInput struct {
request *http.Request
pnames []string
pvalues []string
data map[interface{}]interface{} // store some values in this context when calling context in filter or controller.
FormBody []byte
}
// NewInput return OrangeInput.
func NewInput(request *http.Request, maxMemory int64) (*OrangeInput, error) {
var buf []byte
if request.ContentLength > maxMemory && maxMemory >= 0 {
return nil, errors.New(fmt.Sprintf("request body is too large, max memory is %d", maxMemory))
}
orangeInput := &OrangeInput{
request: request,
pnames: make([]string, 0, maxParam),
pvalues: make([]string, 0, maxParam),
data: make(map[interface{}]interface{}),
FormBody: buf,
}
if request.Method != "GET" {
buf, _ = io.ReadAll(request.Body)
request.Body = io.NopCloser(bytes.NewBuffer(buf))
orangeInput.FormBody = buf
}
return orangeInput, nil
}
// Reset init the
func (input *OrangeInput) Reset(request *http.Request) {
input.request = request
input.pnames = input.pnames[:0]
input.pvalues = input.pvalues[:0]
input.data = nil
input.FormBody = []byte{}
}
// Protocol returns request protocol name, such as HTTP/1.1 .
func (input *OrangeInput) Protocol() string {
return input.request.Proto
}
// URI returns full request url with query string, fragment.
func (input *OrangeInput) URI() string {
return input.request.RequestURI
}
// URL returns request url path (without query string, fragment).
func (input *OrangeInput) URL() string {
return input.request.URL.Path
}
// Site returns base site url as scheme://domain type.
func (input *OrangeInput) Site() string {
return input.Scheme() + "://" + input.Domain()
}
// Scheme returns request scheme as "http" or "https".
func (input *OrangeInput) Scheme() string {
if scheme := input.Header("X-Forwarded-Proto"); scheme != "" {
return scheme
}
if input.request.URL.Scheme != "" {
return input.request.URL.Scheme
}
if input.request.TLS == nil {
return "http"
}
return "https"
}
// Domain returns host name.
// Alias of Host method.
func (input *OrangeInput) Domain() string {
return input.Host()
}
// Host returns host name.
// if no host info in request, return localhost.
func (input *OrangeInput) Host() string {
if input.request.Host != "" {
if hostPart, _, err := net.SplitHostPort(input.request.Host); err == nil {
return hostPart
}
return input.request.Host
}
return "localhost"
}
// Method returns http request method.
func (input *OrangeInput) Method() string {
return input.request.Method
}
// Is returns boolean of this request is on given method, such as Is("POST").
func (input *OrangeInput) Is(method string) bool {
return input.Method() == method
}
// IsGet Is this a GET method request?
func (input *OrangeInput) IsGet() bool {
return input.Is("GET")
}
// IsPost Is this a POST method request?
func (input *OrangeInput) IsPost() bool {
return input.Is("POST")
}
// IsHead Is this a Head method request?
func (input *OrangeInput) IsHead() bool {
return input.Is("HEAD")
}
// IsOptions Is this a OPTIONS method request?
func (input *OrangeInput) IsOptions() bool {
return input.Is("OPTIONS")
}
// IsPut Is this a PUT method request?
func (input *OrangeInput) IsPut() bool {
return input.Is("PUT")
}
// IsDelete Is this a DELETE method request?
func (input *OrangeInput) IsDelete() bool {
return input.Is("DELETE")
}
// IsPatch Is this a PATCH method request?
func (input *OrangeInput) IsPatch() bool {
return input.Is("PATCH")
}
// IsAjax returns boolean of this request is generated by ajax.
func (input *OrangeInput) IsAjax() bool {
return input.Header("X-Requested-With") == "XMLHttpRequest"
}
// IsSecure returns boolean of this request is in https.
func (input *OrangeInput) IsSecure() bool {
return input.Scheme() == "https"
}
// IsWebsocket returns boolean of this request is in webSocket.
func (input *OrangeInput) IsWebsocket() bool {
return input.Header("Upgrade") == "websocket"
}
// IsUpload returns boolean of whether file uploads in this request or not..
func (input *OrangeInput) IsUpload() bool {
return strings.Contains(input.Header("Content-Type"), "multipart/form-data")
}
// AcceptsHTML Checks if request accepts html response
func (input *OrangeInput) AcceptsHTML() bool {
return acceptsHTMLRegex.MatchString(input.Header("Accept"))
}
// AcceptsXML Checks if request accepts xml response
func (input *OrangeInput) AcceptsXML() bool {
return acceptsXMLRegex.MatchString(input.Header("Accept"))
}
// AcceptsJSON Checks if request accepts json response
func (input *OrangeInput) AcceptsJSON() bool {
return acceptsJSONRegex.MatchString(input.Header("Accept"))
}
// Header returns request header item string by a given string.
// if non-existed, return empty string.
func (input *OrangeInput) Header(key string) string {
return input.request.Header.Get(key)
}
// ParamsLen return the length of the params
func (input *OrangeInput) ParamsLen() int {
return len(input.pnames)
}
// Param returns router param by a given key.
func (input *OrangeInput) Param(key string) string {
for i, v := range input.pnames {
if v == key && i <= len(input.pvalues) {
return input.pvalues[i]
}
}
return ""
}
// Params returns the map[key]value.
func (input *OrangeInput) Params() map[string]string {
m := make(map[string]string)
for i, v := range input.pnames {
if i <= len(input.pvalues) {
m[v] = input.pvalues[i]
}
}
return m
}
// SetParam will set the param with key and value
func (input *OrangeInput) SetParam(key, val string) {
// check if already exists
for i, v := range input.pnames {
if v == key && i <= len(input.pvalues) {
input.pvalues[i] = val
return
}
}
input.pvalues = append(input.pvalues, val)
input.pnames = append(input.pnames, key)
}
// ResetParams clears any of the input's Params
// This function is used to clear parameters so they may be reset between filter
// passes.
func (input *OrangeInput) ResetParams() {
input.pnames = input.pnames[:0]
input.pvalues = input.pvalues[:0]
}
// IP returns request client ip.
// if in proxy, return first proxy id.
// if error, return RemoteAddr.
func (input *OrangeInput) IP() string {
ips := input.Proxy()
if len(ips) > 0 && ips[0] != "" {
rip, _, err := net.SplitHostPort(ips[0])
if err != nil {
rip = ips[0]
}
return rip
}
if ip, _, err := net.SplitHostPort(input.request.RemoteAddr); err == nil {
return ip
}
return input.request.RemoteAddr
}
// Proxy returns proxy client ips slice.
func (input *OrangeInput) Proxy() []string {
if ips := input.Header("X-Forwarded-For"); ips != "" {
return strings.Split(ips, ",")
}
return []string{}
}
// Referer returns http referer header.
func (input *OrangeInput) Referer() string {
return input.Header("Referer")
}
// Query returns input data item string by a given string.
func (input *OrangeInput) Query(key string) string {
if val := input.Param(key); val != "" {
return val
}
if input.request.Form == nil {
input.request.ParseForm()
}
return input.request.Form.Get(key)
}
// Data return the implicit data in the input
func (input *OrangeInput) Data() map[interface{}]interface{} {
if input.data == nil {
input.data = make(map[interface{}]interface{})
}
return input.data
}
// GetData returns the stored data in this context.
func (input *OrangeInput) GetData(key interface{}) interface{} {
if v, ok := input.data[key]; ok {
return v
}
return nil
}
// SetData stores data with given key in this context.
// This data are only available in this context.
func (input *OrangeInput) SetData(key, val interface{}) {
if input.data == nil {
input.data = make(map[interface{}]interface{})
}
input.data[key] = val
}
// ParseFormOrMulitForm parseForm or parseMultiForm based on Content-type
func (input *OrangeInput) ParseFormOrMulitForm(maxMemory int64) error {
// Parse the body depending on the content type.
if strings.Contains(input.Header("Content-Type"), "multipart/form-data") {
if err := input.request.ParseMultipartForm(maxMemory); err != nil {
return errors.New("Error parsing request body:" + err.Error())
}
} else if err := input.request.ParseForm(); err != nil {
return errors.New("Error parsing request body:" + err.Error())
}
return nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/zhucheer/orange.git
git@gitee.com:zhucheer/orange.git
zhucheer
orange
orange
v0.5.18

搜索帮助