diff options
Diffstat (limited to 'cmd/_____/http/server.go')
-rw-r--r-- | cmd/_____/http/server.go | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/cmd/_____/http/server.go b/cmd/_____/http/server.go new file mode 100644 index 00000000..db1f22ef --- /dev/null +++ b/cmd/_____/http/server.go @@ -0,0 +1,87 @@ +package http + +import ( + "errors" + "github.com/sirupsen/logrus" + "github.com/spiral/roadrunner" + "net/http" + "strconv" +) + +// service 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 dataTree (if any). +type Server struct { + cfg *Config + static *staticServer + rr *roadrunner.Server +} + +// NewServer returns new instance of HTTP PSR7 server. +func NewServer(cfg *Config, server *roadrunner.Server) *Server { + h := &Server{cfg: cfg, rr: server} + + if cfg.ServeStatic { + h.static = &staticServer{root: http.Dir(h.cfg.Root)} + } + + return h +} + +// ServeHTTP serve using PSR-7 requests passed to underlying application. Attempts to serve static files first if enabled. +func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if srv.cfg.ServeStatic && srv.static.serve(w, r) { + return + } + + // validating request size + if srv.cfg.MaxRequest != 0 { + if length := r.Header.Get("content-length"); length != "" { + if size, err := strconv.ParseInt(length, 10, 64); err != nil { + srv.sendError(w, r, err) + return + } else if size > srv.cfg.MaxRequest { + srv.sendError(w, r, errors.New("request body max size is exceeded")) + return + } + } + } + + req, err := NewRequest(r) + if err != nil { + srv.sendError(w, r, err) + return + } + + if err = req.Open(srv.cfg); err != nil { + srv.sendError(w, r, err) + return + } + defer req.Close() + + p, err := req.Payload() + if err != nil { + srv.sendError(w, r, err) + return + } + + rsp, err := srv.rr.Exec(p) + if err != nil { + srv.sendError(w, r, err) + return + } + + resp, err := NewResponse(rsp) + if err != nil { + srv.sendError(w, r, err) + return + } + + resp.Write(w) +} + +// sendError sends error +func (srv *Server) sendError(w http.ResponseWriter, r *http.Request, err error) { + logrus.Errorf("http: %s", err) + w.WriteHeader(500) + w.Write([]byte(err.Error())) +} |