ref 0: internal/request
This commit is contained in:
parent
b428c75f25
commit
a63e227538
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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{}
|
||||
}
|
11
server.go
11
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)
|
||||
}
|
||||
|
|
5
util.go
5
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 {
|
||||
|
|
Loading…
Reference in New Issue