diff options
-rw-r--r-- | cmd/rr-php/cmd/serve.go | 26 | ||||
-rw-r--r-- | http/files.go (renamed from server/psr7/files.go) | 2 | ||||
-rw-r--r-- | http/post.go (renamed from server/psr7/post.go) | 2 | ||||
-rw-r--r-- | http/request.go (renamed from server/psr7/request.go) | 52 | ||||
-rw-r--r-- | http/response.go | 34 | ||||
-rw-r--r-- | http/server.go (renamed from server/http.go) | 41 | ||||
-rw-r--r-- | server/psr7/response.go | 21 |
7 files changed, 117 insertions, 61 deletions
diff --git a/cmd/rr-php/cmd/serve.go b/cmd/rr-php/cmd/serve.go index dc15b6df..ce19414b 100644 --- a/cmd/rr-php/cmd/serve.go +++ b/cmd/rr-php/cmd/serve.go @@ -20,7 +20,7 @@ import ( "os/exec" "time" "github.com/sirupsen/logrus" - "github.com/spiral/roadrunner/server" + rrhttp "github.com/spiral/roadrunner/http" "net/http" ) @@ -40,9 +40,10 @@ func serveHandler(cmd *cobra.Command, args []string) { ) err := rr.Configure(roadrunner.Config{ - NumWorkers: 1, + NumWorkers: 4, AllocateTimeout: time.Minute, DestroyTimeout: time.Minute, + //MaxExecutions: 10, }) rr.Observe(func(event int, ctx interface{}) { @@ -55,8 +56,25 @@ func serveHandler(cmd *cobra.Command, args []string) { logrus.Info("serving") - http.ListenAndServe(":8080", server.NewHTTP( - server.HTTPConfig{ + //Enable http2 + //srv := http.Server{ + // Addr: ":8080", + // Handler: rrhttp.NewServer( + // rrhttp.Config{ + // ServeStatic: true, + // Root: "/Users/wolfy-j/Projects/phpapp/webroot", + // }, + // rr, + // ), + //} + + // srv.ListenAndServe() + + //http2.ConfigureServer(&srv, nil) + //srv.ListenAndServeTLS("localhost.cert", "localhost.key") + + http.ListenAndServe(":8080", rrhttp.NewServer( + rrhttp.Config{ ServeStatic: true, Root: "/Users/wolfy-j/Projects/phpapp/webroot", }, diff --git a/server/psr7/files.go b/http/files.go index 31ddfec8..06e5fd24 100644 --- a/server/psr7/files.go +++ b/http/files.go @@ -1,4 +1,4 @@ -package psr7 +package http import ( "mime/multipart" diff --git a/server/psr7/post.go b/http/post.go index 30af7e3a..64c60d98 100644 --- a/server/psr7/post.go +++ b/http/post.go @@ -1,4 +1,4 @@ -package psr7 +package http import "strings" diff --git a/server/psr7/request.go b/http/request.go index f8dedd8f..032c70b5 100644 --- a/server/psr7/request.go +++ b/http/request.go @@ -1,4 +1,4 @@ -package psr7 +package http import ( "net/http" @@ -6,19 +6,23 @@ import ( "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"` + 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) { @@ -49,6 +53,9 @@ func ParseRequest(r *http.Request) (req *Request, err error) { if req.Uploads != nil { logrus.Debug("opening files") } + req.ParsedBody = true + } else { + req.body, _ = ioutil.ReadAll(r.Body) } return req, nil @@ -60,10 +67,15 @@ func (r *Request) Payload() *roadrunner.Payload { panic(err) //todo: change it } - // todo: non parseble payloads - body, err := json.Marshal(r.postData) - 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} @@ -77,7 +89,21 @@ func (r *Request) Close() { // HasBody returns true if request might include POST data or file uploads. func (r *Request) HasBody() bool { - return r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" + 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) diff --git a/http/response.go b/http/response.go new file mode 100644 index 00000000..6a094bf3 --- /dev/null +++ b/http/response.go @@ -0,0 +1,34 @@ +package http + +import ( + "net/http" + "github.com/sirupsen/logrus" +) + +type Response struct { + Status int `json:"status"` + Headers map[string][]string `json:"headers"` +} + +func (r *Response) Write(w http.ResponseWriter) { + push := make([]string, 0) + for k, v := range r.Headers { + for _, h := range v { + if k == "http2-push" { + push = append(push, h) + } else { + w.Header().Add(k, h) + } + } + } + + if p, ok := w.(http.Pusher); ok { + logrus.Info("PUSH SUPPORTED") + for _, f := range push { + logrus.Info("pushing HTTP2 file ", f) + p.Push(f, nil) + } + } + + w.WriteHeader(r.Status) +} diff --git a/server/http.go b/http/server.go index 63551703..b0d0b56a 100644 --- a/server/http.go +++ b/http/server.go @@ -1,8 +1,7 @@ -package server +package http import ( "github.com/spiral/roadrunner" - "github.com/spiral/roadrunner/server/psr7" "net/http" "strings" "path" @@ -17,7 +16,7 @@ var ( ) // Configures http rr -type HTTPConfig struct { +type Config struct { // ServeStatic enables static file serving from desired root directory. ServeStatic bool @@ -25,17 +24,17 @@ type HTTPConfig struct { Root string } -// HTTP serves http connections to underlying PHP application using PSR-7 protocol. Context will include request headers, +// Server serves http connections to underlying PHP application using PSR-7 protocol. Context will include request headers, // parsed files and query, payload will include parsed form data (if any) - todo: do we need to do that?. -type HTTP struct { - cfg HTTPConfig +type Server struct { + cfg Config root http.Dir rr *roadrunner.Server } -// NewHTTP returns new instance of HTTP PSR7 server. -func NewHTTP(cfg HTTPConfig, server *roadrunner.Server) *HTTP { - h := &HTTP{cfg: cfg, rr: server} +// NewServer returns new instance of Server PSR7 server. +func NewServer(cfg Config, server *roadrunner.Server) *Server { + h := &Server{cfg: cfg, rr: server} if cfg.ServeStatic { h.root = http.Dir(h.cfg.Root) } @@ -44,31 +43,31 @@ func NewHTTP(cfg HTTPConfig, server *roadrunner.Server) *HTTP { } // ServeHTTP serve using PSR-7 requests passed to underlying application. -func (h *HTTP) ServeHTTP(w http.ResponseWriter, r *http.Request) () { - if h.cfg.ServeStatic && h.serveStatic(w, r) { +func (svr *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) () { + if svr.cfg.ServeStatic && svr.serveStatic(w, r) { // server always attempt to serve static files first return } - req, err := psr7.ParseRequest(r) + req, err := ParseRequest(r) if err != nil { - w.Write([]byte(err.Error())) //todo: better errors w.WriteHeader(500) + w.Write([]byte(err.Error())) //todo: better errors return } defer req.Close() - rsp, err := h.rr.Exec(req.Payload()) + rsp, err := svr.rr.Exec(req.Payload()) if err != nil { - w.Write([]byte(err.Error())) //todo: better errors w.WriteHeader(500) + w.Write([]byte(err.Error())) //todo: better errors return } - resp := &psr7.Response{} + resp := &Response{} if err = json.Unmarshal(rsp.Context, resp); err != nil { - w.Write([]byte(err.Error())) //todo: better errors w.WriteHeader(500) + w.Write([]byte(err.Error())) //todo: better errors return } @@ -78,19 +77,19 @@ func (h *HTTP) ServeHTTP(w http.ResponseWriter, r *http.Request) () { // serveStatic attempts to serve static file and returns true in case of success, will return false in case if file not // found, not allowed or on read error. -func (h *HTTP) serveStatic(w http.ResponseWriter, r *http.Request) bool { +func (svr *Server) serveStatic(w http.ResponseWriter, r *http.Request) bool { fpath := r.URL.Path if !strings.HasPrefix(fpath, "/") { fpath = "/" + fpath } fpath = path.Clean(fpath) - if h.excluded(fpath) { + if svr.excluded(fpath) { logrus.Warningf("attempt to access forbidden file %s", fpath) return false } - f, err := h.root.Open(fpath) + f, err := svr.root.Open(fpath) if err != nil { if !os.IsNotExist(err) { // rr or access error @@ -118,7 +117,7 @@ func (h *HTTP) serveStatic(w http.ResponseWriter, r *http.Request) bool { } // excluded returns true if file has forbidden extension. -func (h *HTTP) excluded(path string) bool { +func (svr *Server) excluded(path string) bool { ext := strings.ToLower(filepath.Ext(path)) for _, exl := range excludeFiles { if ext == exl { diff --git a/server/psr7/response.go b/server/psr7/response.go deleted file mode 100644 index c0d739a7..00000000 --- a/server/psr7/response.go +++ /dev/null @@ -1,21 +0,0 @@ -package psr7 - -import ( - "net/http" -) - -type Response struct { - Status int `json:"status"` - Headers map[string][]string `json:"headers"` -} - -func (r *Response) Write(w http.ResponseWriter) { - for k, v := range r.Headers { - for _, h := range v { - w.Header().Add(k, h) - - } - } - - w.WriteHeader(r.Status) -} |