From a63e227538fd893be4b6590fcb972c895d71d2f1 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Wed, 1 May 2019 00:02:28 +0200 Subject: [PATCH] ref 0: internal/request --- internal/config/builder.go | 3 +- internal/request/dataset.go | 49 ++++++++++++++- .../request/{utils.go => param_reflect.go} | 34 ----------- internal/request/parameter.go | 15 +++++ internal/request/request.go | 36 ++++++++++- internal/request/types.go | 61 ------------------- server.go | 11 ++-- util.go | 5 +- 8 files changed, 108 insertions(+), 106 deletions(-) rename internal/request/{utils.go => param_reflect.go} (67%) delete mode 100644 internal/request/types.go diff --git a/internal/config/builder.go b/internal/config/builder.go index ca11510..4a76b57 100644 --- a/internal/config/builder.go +++ b/internal/config/builder.go @@ -2,9 +2,10 @@ package config import ( "fmt" - "git.xdrm.io/go/aicra/driver" "os" "path/filepath" + + "git.xdrm.io/go/aicra/driver" ) // InferFromFolder fills the 'Map' by browsing recursively the diff --git a/internal/request/dataset.go b/internal/request/dataset.go index 8abd470..79891c1 100644 --- a/internal/request/dataset.go +++ b/internal/request/dataset.go @@ -3,12 +3,45 @@ package request import ( "encoding/json" "fmt" - "git.xdrm.io/go/aicra/internal/multipart" "log" "net/http" "strings" + + "git.xdrm.io/go/aicra/internal/multipart" ) +// DataSet represents all data that can be caught: +// - URI (guessed from the URI by removing the controller path) +// - GET (default url data) +// - POST (from json, form-data, url-encoded) +type DataSet struct { + + // ordered values from the URI + // catches all after the controller path + // + // points to DataSet.Data + URI []*Parameter + + // uri parameters following the QUERY format + // + // points to DataSet.Data + Get map[string]*Parameter + + // form data depending on the Content-Type: + // 'application/json' => key-value pair is parsed as json into the map + // 'application/x-www-form-urlencoded' => standard parameters as QUERY parameters + // 'multipart/form-data' => parse form-data format + // + // points to DataSet.Data + Form map[string]*Parameter + + // contains URL+GET+FORM data with prefixes: + // - FORM: no prefix + // - URL: 'URL#' followed by the index in Uri + // - GET: 'GET@' followed by the key in GET + Set map[string]*Parameter +} + // NewDataset creates an empty request dataset func NewDataset() *DataSet { return &DataSet{ @@ -245,3 +278,17 @@ func (i *DataSet) parseMultipart(req *http.Request) { return } + +// nameInjection returns whether there is +// a parameter name injection: +// - inferred GET parameters +// - inferred URL parameters +func nameInjection(pName string) bool { + return strings.HasPrefix(pName, "GET@") || strings.HasPrefix(pName, "URL#") +} + +// validName returns whether a parameter name (without the GET@ or URL# prefix) is valid +// if fails if the name begins/ends with underscores +func validName(pName string) bool { + return strings.Trim(pName, "_") == pName +} diff --git a/internal/request/utils.go b/internal/request/param_reflect.go similarity index 67% rename from internal/request/utils.go rename to internal/request/param_reflect.go index f8c1853..2adf371 100644 --- a/internal/request/utils.go +++ b/internal/request/param_reflect.go @@ -4,42 +4,8 @@ import ( "encoding/json" "fmt" "reflect" - "strings" ) -// normaliseURI removes the trailing '/' to always -// have the same Uri format for later processing -func normaliseURI(uri string) string { - - if len(uri) < 1 { - return uri - } - - if uri[0] == '/' { - uri = uri[1:] - } - - if len(uri) > 1 && uri[len(uri)-1] == '/' { - uri = uri[0 : len(uri)-1] - } - - return uri -} - -// nameInjection returns whether there is -// a parameter name injection: -// - inferred GET parameters -// - inferred URL parameters -func nameInjection(pName string) bool { - return strings.HasPrefix(pName, "GET@") || strings.HasPrefix(pName, "URL#") -} - -// validName returns whether a parameter name (without the GET@ or URL# prefix) is valid -// if fails if the name begins/ends with underscores -func validName(pName string) bool { - return strings.Trim(pName, "_") == pName -} - // parseParameter parses http GET/POST data // - []string // - size = 1 : return json of first element diff --git a/internal/request/parameter.go b/internal/request/parameter.go index 0d21d83..4848cd6 100644 --- a/internal/request/parameter.go +++ b/internal/request/parameter.go @@ -1,5 +1,20 @@ package request +// Parameter represents an http request parameter +// that can be of type URL, GET, or FORM (multipart, json, urlencoded) +type Parameter struct { + // whether the value has been json-parsed + // for optimisation purpose, parameters are only parsed + // if they are required by the current controller + Parsed bool + + // whether the value is a file + File bool + + // the actual parameter value + Value interface{} +} + // Parse parameter (json-like) if not already done func (i *Parameter) Parse() { diff --git a/internal/request/request.go b/internal/request/request.go index 3bc3e61..42973b5 100644 --- a/internal/request/request.go +++ b/internal/request/request.go @@ -5,8 +5,21 @@ import ( "strings" ) -// FromHTTP builds an interface request from a http.Request -func FromHTTP(req *http.Request) (*Request, error) { +// Request represents an API request i.e. HTTP +type Request struct { + // corresponds to the list of uri components + // featuring in the request URI + URI []string + + // controller path (portion of 'Uri') + Path []string + + // contains all data from URL, GET, and FORM + Data *DataSet +} + +// New builds an interface request from a http.Request +func New(req *http.Request) (*Request, error) { /* (1) Get useful data */ uri := normaliseURI(req.URL.Path) @@ -24,3 +37,22 @@ func FromHTTP(req *http.Request) (*Request, error) { return inst, nil } + +// normaliseURI removes the trailing '/' to always +// have the same Uri format for later processing +func normaliseURI(uri string) string { + + if len(uri) < 1 { + return uri + } + + if uri[0] == '/' { + uri = uri[1:] + } + + if len(uri) > 1 && uri[len(uri)-1] == '/' { + uri = uri[0 : len(uri)-1] + } + + return uri +} diff --git a/internal/request/types.go b/internal/request/types.go deleted file mode 100644 index 4b38c4b..0000000 --- a/internal/request/types.go +++ /dev/null @@ -1,61 +0,0 @@ -package request - -// Request represents a request by its URI, controller path and data (uri, get, post) -type Request struct { - // corresponds to the list of uri components - // featuring in the request URI - URI []string - - // controller path (portion of 'Uri') - Path []string - - // contains all data from URL, GET, and FORM - Data *DataSet -} - -// DataSet represents all data that can be caught: -// - URI (guessed from the URI by removing the controller path) -// - GET (default url data) -// - POST (from json, form-data, url-encoded) -type DataSet struct { - - // ordered values from the URI - // catches all after the controller path - // - // points to DataSet.Data - URI []*Parameter - - // uri parameters following the QUERY format - // - // points to DataSet.Data - Get map[string]*Parameter - - // form data depending on the Content-Type: - // 'application/json' => key-value pair is parsed as json into the map - // 'application/x-www-form-urlencoded' => standard parameters as QUERY parameters - // 'multipart/form-data' => parse form-data format - // - // points to DataSet.Data - Form map[string]*Parameter - - // contains URL+GET+FORM data with prefixes: - // - FORM: no prefix - // - URL: 'URL#' followed by the index in Uri - // - GET: 'GET@' followed by the key in GET - Set map[string]*Parameter -} - -// Parameter represents an http request parameter -// that can be of type URL, GET, or FORM (multipart, json, urlencoded) -type Parameter struct { - // whether the value has been json-parsed - // for optimisation purpose, parameters are only parsed - // if they are required by the current controller - Parsed bool - - // whether the value is a file - File bool - - // the actual parameter value - Value interface{} -} diff --git a/server.go b/server.go index 4d7604e..e717440 100644 --- a/server.go +++ b/server.go @@ -2,6 +2,11 @@ package aicra import ( "errors" + "log" + "net/http" + "path/filepath" + "strings" + "git.xdrm.io/go/aicra/api" "git.xdrm.io/go/aicra/driver" e "git.xdrm.io/go/aicra/err" @@ -10,10 +15,6 @@ import ( "git.xdrm.io/go/aicra/internal/config" apirequest "git.xdrm.io/go/aicra/internal/request" "git.xdrm.io/go/aicra/middleware" - "log" - "net/http" - "path/filepath" - "strings" ) // Server represents an AICRA instance featuring: @@ -111,7 +112,7 @@ func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) { defer req.Body.Close() /* (1) Build request */ - apiRequest, err := apirequest.FromHTTP(req) + apiRequest, err := apirequest.New(req) if err != nil { log.Fatal(err) } diff --git a/util.go b/util.go index 335549c..153b21b 100644 --- a/util.go +++ b/util.go @@ -2,12 +2,13 @@ package aicra import ( "encoding/json" + "log" + "net/http" + "git.xdrm.io/go/aicra/api" "git.xdrm.io/go/aicra/err" "git.xdrm.io/go/aicra/internal/apidef" apireq "git.xdrm.io/go/aicra/internal/request" - "log" - "net/http" ) func (s *Server) matchController(req *apireq.Request) *apidef.Controller {