diff options
Diffstat (limited to 'psr7/request.go')
-rw-r--r-- | psr7/request.go | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/psr7/request.go b/psr7/request.go new file mode 100644 index 00000000..41fbb4bf --- /dev/null +++ b/psr7/request.go @@ -0,0 +1,127 @@ +package psr7 + +import ( + "net/http" + "fmt" + "encoding/json" + "github.com/spiral/roadrunner" + "github.com/sirupsen/logrus" + "strings" + "io/ioutil" +) + +type Request struct { + Protocol string `json:"protocol"` + Uri string `json:"uri"` + Method string `json:"method"` + Headers http.Header `json:"headers"` + Cookies map[string]string `json:"cookies"` + RawQuery string `json:"rawQuery"` + Uploads fileData `json:"fileUploads"` + ParsedBody bool `json:"parsedBody"` + + // buffers + postData postData + body []byte +} + +func ParseRequest(r *http.Request) (req *Request, err error) { + req = &Request{ + Protocol: r.Proto, + Uri: fmt.Sprintf("%s%s", r.Host, r.URL.String()), + Method: r.Method, + Headers: r.Header, + Cookies: make(map[string]string), + RawQuery: r.URL.RawQuery, + } + + for _, c := range r.Cookies() { + req.Cookies[c.Name] = c.Value + } + + if req.HasBody() { + r.ParseMultipartForm(32 << 20) + + if req.postData, err = parseData(r); err != nil { + return nil, err + } + + if req.Uploads, err = parseFiles(r); err != nil { + return nil, err + } + + if req.Uploads != nil { + logrus.Debug("opening files") + } + req.ParsedBody = true + } else { + req.body, _ = ioutil.ReadAll(r.Body) + } + + return req, nil +} + +func (r *Request) Payload() *roadrunner.Payload { + ctx, err := json.Marshal(r) + if err != nil { + panic(err) //todo: change it + } + + var body []byte + if r.ParsedBody { + // todo: non parseble payloads + body, err = json.Marshal(r.postData) + if err != nil { + panic(err) //todo: change it + } + } else { + body = r.body + } + + return &roadrunner.Payload{Context: ctx, Body: body} +} + +func (r *Request) Close() { + if r.Uploads != nil { + + } +} + +// HasBody returns true if request might include POST data or file uploads. +func (r *Request) HasBody() bool { + if r.Method != "POST" && r.Method != "PUT" && r.Method != "PATCH" { + return false + } + + contentType := r.Headers.Get("content-type") + + if strings.Contains(contentType, "multipart/form-data") { + return true + } + + if contentType == "application/x-www-form-urlencoded" { + return true + } + + return false +} + +// parse incoming data request into JSON (including multipart form data) +func parseData(r *http.Request) (postData, error) { + data := make(postData) + for k, v := range r.MultipartForm.Value { + data.push(k, v) + } + + return data, nil +} + +// parse incoming data request into JSON (including multipart form data) +func parseFiles(r *http.Request) (fileData, error) { + data := make(fileData) + for k, v := range r.MultipartForm.File { + data.push(k, v) + } + + return data, nil +} |