diff options
author | Wolfy-J <[email protected]> | 2018-06-05 22:48:27 +0300 |
---|---|---|
committer | Wolfy-J <[email protected]> | 2018-06-05 22:48:27 +0300 |
commit | 6adaf713b47c9a3ab3a516e21d2d4ecf7f2075d6 (patch) | |
tree | 6bcf1bfea1e2f87a3ae7065612c0df43c90c1cdc /cmd | |
parent | 3112f9b58c73773cea972fd79f04d33f8f7d7edd (diff) |
breaking the tests
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/_____/bus.go | 94 | ||||
-rw-r--r-- | cmd/_____/http/data.go | 67 | ||||
-rw-r--r-- | cmd/_____/http/request.go | 137 | ||||
-rw-r--r-- | cmd/_____/http/response.go | 42 | ||||
-rw-r--r-- | cmd/_____/http/static.go | 4 | ||||
-rw-r--r-- | cmd/_____/http/uploads.go | 207 | ||||
-rw-r--r-- | cmd/rr/http/reload.go | 2 | ||||
-rw-r--r-- | cmd/rr/http/workers.go | 2 |
8 files changed, 3 insertions, 552 deletions
diff --git a/cmd/_____/bus.go b/cmd/_____/bus.go deleted file mode 100644 index 813a6c3b..00000000 --- a/cmd/_____/bus.go +++ /dev/null @@ -1,94 +0,0 @@ -package _____ - -import ( - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "net/rpc" - "sync" -) - -// Config provides ability to slice configuration sections and unmarshal configuration data into -// given structure. -type Config interface { - // Get nested config section (sub-map), returns nil if section not found. - Get(service string) Config - - // Unmarshal unmarshal config data into given struct. - Unmarshal(out interface{}) error -} - -var ( - dsnError = errors.New("invalid socket DSN (tcp://:6001, unix://sock.unix)") -) - -type Bus struct { - services []Service - wg sync.WaitGroup - enabled []Service - stop chan interface{} - rpc *rpc.Server - rpcConfig *RPCConfig -} - -func (b *Bus) Register(s Service) { - b.services = append(b.services, s) -} - -func (b *Bus) Services() []Service { - return b.services -} - -func (b *Bus) Configure(cfg Config) error { - b.enabled = make([]Service, 0) - - for _, s := range b.services { - segment := cfg.Get(s.Name()) - if segment == nil { - // no config has been provided for the Service - logrus.Debugf("%s: no config has been provided", s.Name()) - continue - } - - if enable, err := s.Configure(segment); err != nil { - return err - } else if !enable { - continue - } - - b.enabled = append(b.enabled, s) - } - - return nil -} - -func (b *Bus) Serve() { - b.rpc = rpc.NewServer() - - for _, s := range b.enabled { - // some candidates might provide net/rpc api for internal communications - if api := s.RPC(); api != nil { - b.rpc.RegisterName(s.Name(), api) - } - - b.wg.Add(1) - go func() { - defer b.wg.Done() - - if err := s.Serve(); err != nil { - logrus.Errorf("%s.start: %s", s.Name(), err) - } - }() - } - - b.wg.Wait() -} - -func (b *Bus) Stop() { - for _, s := range b.enabled { - if err := s.Stop(); err != nil { - logrus.Errorf("%s.stop: %s", s.Name(), err) - } - } - - b.wg.Wait() -} diff --git a/cmd/_____/http/data.go b/cmd/_____/http/data.go deleted file mode 100644 index e6b8344f..00000000 --- a/cmd/_____/http/data.go +++ /dev/null @@ -1,67 +0,0 @@ -package http - -import ( - "net/http" - "strings" -) - -const maxLevel = 127 - -type dataTree map[string]interface{} - -// parsePost parses incoming request body into data tree. -func parsePost(r *http.Request) (dataTree, error) { - data := make(dataTree) - - for k, v := range r.PostForm { - data.push(k, v) - } - - for k, v := range r.MultipartForm.Value { - data.push(k, v) - } - - return data, nil -} - -func (d dataTree) push(k string, v []string) { - if len(v) == 0 { - // skip empty values - return - } - - indexes := make([]string, 0) - for _, index := range strings.Split(k, "[") { - indexes = append(indexes, strings.Trim(index, "]")) - } - - if len(indexes) <= maxLevel { - d.mount(indexes, v) - } -} - -// mount mounts data tree recursively. -func (d dataTree) mount(i []string, v []string) { - if len(v) == 0 { - return - } - - if len(i) == 1 { - // single value context - d[i[0]] = v[0] - return - } - - if len(i) == 2 && i[1] == "" { - // non associated array of elements - d[i[0]] = v - return - } - - if p, ok := d[i[0]]; ok { - p.(dataTree).mount(i[1:], v) - } - - d[i[0]] = make(dataTree) - d[i[0]].(dataTree).mount(i[1:], v) -} diff --git a/cmd/_____/http/request.go b/cmd/_____/http/request.go deleted file mode 100644 index fd483744..00000000 --- a/cmd/_____/http/request.go +++ /dev/null @@ -1,137 +0,0 @@ -package http - -import ( - "encoding/json" - "fmt" - "github.com/spiral/roadrunner" - "io/ioutil" - "net/http" - "strings" -) - -const ( - defaultMaxMemory = 32 << 20 // 32 MB -) - -// Request maps net/http requests to PSR7 compatible structure and managed state of temporary uploaded files. -type Request struct { - // Protocol includes HTTP protocol version. - Protocol string `json:"protocol"` - - // Method contains name of HTTP method used for the request. - Method string `json:"method"` - - // Uri contains full request Uri with scheme and query. - Uri string `json:"uri"` - - // Headers contains list of request headers. - Headers http.Header `json:"headers"` - - // Cookies contains list of request cookies. - Cookies map[string]string `json:"cookies"` - - // RawQuery contains non parsed query string (to be parsed on php end). - RawQuery string `json:"rawQuery"` - - // Parsed indicates that request body has been parsed on RR end. - Parsed bool `json:"parsed"` - - // Uploads contains list of uploaded files, their names, sized and associations with temporary files. - Uploads *Uploads `json:"uploads"` - - // request body can be parsedData or []byte - body interface{} -} - -// NewRequest creates new PSR7 compatible request using net/http request. -func NewRequest(r *http.Request) (req *Request, err error) { - req = &Request{ - Protocol: r.Proto, - Method: r.Method, - Uri: uri(r), - 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.parsable() { - req.body, err = ioutil.ReadAll(r.Body) - return req, err - } - - if err = r.ParseMultipartForm(defaultMaxMemory); err != nil { - return nil, err - } - - if req.body, err = parsePost(r); err != nil { - return nil, err - } - - if req.Uploads, err = parseUploads(r); err != nil { - return nil, err - } - - req.Parsed = true - return req, nil -} - -// Open moves all uploaded files to temporary directory so it can be given to php later. -func (r *Request) Open(cfg *Config) error { - if r.Uploads == nil { - return nil - } - - return r.Uploads.Open(cfg) -} - -// Close clears all temp file uploads -func (r *Request) Close() { - if r.Uploads == nil { - return - } - - r.Uploads.Clear() -} - -// Payload request marshaled RoadRunner payload based on PSR7 data. Default encode method is JSON. Make sure to open -// files prior to calling this method. -func (r *Request) Payload() (p *roadrunner.Payload, err error) { - p = &roadrunner.Payload{} - - if p.Context, err = json.Marshal(r); err != nil { - return nil, err - } - - if r.Parsed { - if p.Body, err = json.Marshal(r.body); err != nil { - return nil, err - } - } else if r.body != nil { - p.Body = r.body.([]byte) - } - - return p, nil -} - -// parsable returns true if request payload can be parsed (POST dataTree, file tree). -func (r *Request) parsable() bool { - if r.Method != "POST" && r.Method != "PUT" && r.Method != "PATCH" { - return false - } - - ct := r.Headers.Get("content-type") - return strings.Contains(ct, "multipart/form-data") || ct == "application/x-www-form-urlencoded" -} - -// uri fetches full uri from request in a form of string (including https scheme if TLS connection is enabled). -func uri(r *http.Request) string { - if r.TLS != nil { - return fmt.Sprintf("https://%s%s", r.Host, r.URL.String()) - } - - return fmt.Sprintf("http://%s%s", r.Host, r.URL.String()) -} diff --git a/cmd/_____/http/response.go b/cmd/_____/http/response.go deleted file mode 100644 index 2736c4ab..00000000 --- a/cmd/_____/http/response.go +++ /dev/null @@ -1,42 +0,0 @@ -package http - -import ( - "encoding/json" - "github.com/spiral/roadrunner" - "net/http" -) - -// Response handles PSR7 response logic. -type Response struct { - // Status contains response status. - Status int `json:"status"` - - // Headers contains list of response headers. - Headers map[string][]string `json:"headers"` - - // associated body payload. - body []byte -} - -// NewResponse creates new response based on given roadrunner payload. -func NewResponse(p *roadrunner.Payload) (*Response, error) { - r := &Response{body: p.Body} - if err := json.Unmarshal(p.Context, r); err != nil { - return nil, err - } - - return r, nil -} - -// Write writes response headers, status and body into ResponseWriter. -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) - w.Write(r.body) -} diff --git a/cmd/_____/http/static.go b/cmd/_____/http/static.go index d7030c3f..b055099f 100644 --- a/cmd/_____/http/static.go +++ b/cmd/_____/http/static.go @@ -9,9 +9,7 @@ import ( "strings" ) -var ( - forbiddenFiles = []string{".php", ".htaccess"} -) +var forbiddenFiles = []string{".php", ".htaccess"} // staticServer serves static files type staticServer struct { diff --git a/cmd/_____/http/uploads.go b/cmd/_____/http/uploads.go deleted file mode 100644 index 468e8a19..00000000 --- a/cmd/_____/http/uploads.go +++ /dev/null @@ -1,207 +0,0 @@ -package http - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "os" - "strings" - "sync" -) - -const ( - // There is no error, the file uploaded with success. - UploadErrorOK = 0 - - // No file was uploaded. - UploadErrorNoFile = 4 - - // Missing a temporary folder. - UploadErrorNoTmpDir = 5 - - // Failed to write file to disk. - UploadErrorCantWrite = 6 - - // ForbidUploads file extension. - UploadErrorExtension = 7 -) - -// FileUpload represents singular file wrapUpload. -type FileUpload struct { - // Name contains filename specified by the client. - Name string `json:"name"` - - // MimeType contains mime-type provided by the client. - MimeType string `json:"type"` - - // Size of the uploaded file. - Size int64 `json:"size"` - - // Error indicates file upload error (if any). See http://php.net/manual/en/features.file-upload.errors.php - Error int `json:"error"` - - // TempFilename points to temporary file location. - TempFilename string `json:"tmpName"` - - // associated file header - header *multipart.FileHeader -} - -func (f *FileUpload) Open(cfg *Config) error { - if cfg.Forbidden(f.Name) { - f.Error = UploadErrorExtension - return nil - } - - file, err := f.header.Open() - if err != nil { - f.Error = UploadErrorNoFile - return err - } - defer file.Close() - - tmp, err := ioutil.TempFile(cfg.TmpDir, "upload") - if err != nil { - // most likely cause of this issue is missing tmp dir - f.Error = UploadErrorNoTmpDir - return err - } - - f.TempFilename = tmp.Name() - defer tmp.Close() - - if f.Size, err = io.Copy(tmp, file); err != nil { - f.Error = UploadErrorCantWrite - } - - return err -} - -func wrapUpload(f *multipart.FileHeader) *FileUpload { - return &FileUpload{ - Name: f.Filename, - MimeType: f.Header.Get("Content-Type"), - Error: UploadErrorOK, - header: f, - } -} - -type fileTree map[string]interface{} - -func (d fileTree) push(k string, v []*FileUpload) { - if len(v) == 0 { - // skip empty values - return - } - - indexes := make([]string, 0) - for _, index := range strings.Split(k, "[") { - indexes = append(indexes, strings.Trim(index, "]")) - } - - if len(indexes) <= maxLevel { - d.mount(indexes, v) - } -} - -// mount mounts data tree recursively. -func (d fileTree) mount(i []string, v []*FileUpload) { - if len(v) == 0 { - return - } - - if len(i) == 1 { - // single value context - d[i[0]] = v[0] - return - } - - if len(i) == 2 && i[1] == "" { - // non associated array of elements - d[i[0]] = v - return - } - - if p, ok := d[i[0]]; ok { - p.(fileTree).mount(i[1:], v) - } - - d[i[0]] = make(fileTree) - d[i[0]].(fileTree).mount(i[1:], v) -} - -// tree manages uploaded files tree and temporary files. -type Uploads struct { - // pre processed data tree for Uploads. - tree fileTree - - // flat list of all file Uploads. - list []*FileUpload -} - -// MarshalJSON marshal tree tree into JSON. -func (u *Uploads) MarshalJSON() ([]byte, error) { - return json.Marshal(u.tree) -} - -// Open moves all uploaded files to temp directory, return error in case of issue with temp directory. File errors -// will be handled individually. @todo: do we need it? -func (u *Uploads) Open(cfg *Config) error { - var wg sync.WaitGroup - for _, f := range u.list { - wg.Add(1) - go func(f *FileUpload) { - defer wg.Done() - f.Open(cfg) - }(f) - } - - wg.Wait() - return nil -} - -// Clear deletes all temporary files. -func (u *Uploads) Clear() { - for _, f := range u.list { - if f.TempFilename != "" && exists(f.TempFilename) { - os.Remove(f.TempFilename) - } - } -} - -// parse incoming dataTree request into JSON (including multipart form dataTree) -func parseUploads(r *http.Request) (*Uploads, error) { - u := &Uploads{ - tree: make(fileTree), - list: make([]*FileUpload, 0), - } - - for k, v := range r.MultipartForm.File { - files := make([]*FileUpload, 0, len(v)) - for _, f := range v { - files = append(files, wrapUpload(f)) - } - - u.list = append(u.list, files...) - u.tree.push(k, files) - } - - return u, nil -} - -// exists if file exists. by osutils; todo: better? -func exists(path string) bool { - _, err := os.Stat(path) - if err == nil { - return true - } - - if os.IsNotExist(err) { - return false - } - - panic(fmt.Errorf("unable to stat path %q; %v", path, err)) -} diff --git a/cmd/rr/http/reload.go b/cmd/rr/http/reload.go index 0fd3d7e9..23c36144 100644 --- a/cmd/rr/http/reload.go +++ b/cmd/rr/http/reload.go @@ -21,9 +21,9 @@ package http import ( + "errors" "github.com/spf13/cobra" rr "github.com/spiral/roadrunner/cmd/rr/cmd" - "github.com/go-errors/errors" "github.com/spiral/roadrunner/rpc" ) diff --git a/cmd/rr/http/workers.go b/cmd/rr/http/workers.go index 63ef0cce..61fee2a1 100644 --- a/cmd/rr/http/workers.go +++ b/cmd/rr/http/workers.go @@ -21,9 +21,9 @@ package http import ( + "errors" "github.com/spf13/cobra" rr "github.com/spiral/roadrunner/cmd/rr/cmd" - "errors" "github.com/spiral/roadrunner/rpc" ) |