github.com/MontFerret/ferret@v0.18.0/pkg/drivers/request.go (about) 1 package drivers 2 3 import ( 4 "context" 5 6 "github.com/wI2L/jettison" 7 8 "github.com/MontFerret/ferret/pkg/runtime/core" 9 "github.com/MontFerret/ferret/pkg/runtime/values" 10 "github.com/MontFerret/ferret/pkg/runtime/values/types" 11 ) 12 13 // HTTPRequest HTTP request object. 14 type ( 15 HTTPRequest struct { 16 URL string 17 Method string 18 Headers *HTTPHeaders 19 Body []byte 20 } 21 // requestMarshal is a structure that repeats HTTPRequest. It allows 22 // easily Marshal the HTTPRequest object. 23 requestMarshal struct { 24 URL string `json:"url"` 25 Method string `json:"method"` 26 Headers *HTTPHeaders `json:"headers"` 27 Body []byte `json:"body"` 28 } 29 ) 30 31 func (req *HTTPRequest) MarshalJSON() ([]byte, error) { 32 if req == nil { 33 return values.None.MarshalJSON() 34 } 35 36 return jettison.MarshalOpts(requestMarshal(*req), jettison.NoHTMLEscaping()) 37 } 38 39 func (req *HTTPRequest) Type() core.Type { 40 return HTTPRequestType 41 } 42 43 func (req *HTTPRequest) String() string { 44 return req.URL 45 } 46 47 func (req *HTTPRequest) Compare(other core.Value) int64 { 48 if other.Type() != HTTPRequestType { 49 return Compare(HTTPResponseType, other.Type()) 50 } 51 52 // this is a safe cast. Only *HTTPRequest implements core.Value. 53 // HTTPRequest does not. 54 otherReq := other.(*HTTPRequest) 55 56 comp := req.Headers.Compare(otherReq.Headers) 57 58 if comp != 0 { 59 return comp 60 } 61 62 comp = values.NewString(req.Method).Compare(values.NewString(otherReq.Method)) 63 64 if comp != 0 { 65 return comp 66 } 67 68 return values.NewString(req.URL). 69 Compare(values.NewString(otherReq.URL)) 70 } 71 72 func (req *HTTPRequest) Unwrap() interface{} { 73 return req 74 } 75 76 func (req *HTTPRequest) Hash() uint64 { 77 return values.Parse(req).Hash() 78 } 79 80 func (req *HTTPRequest) Copy() core.Value { 81 cop := *req 82 return &cop 83 } 84 85 func (req *HTTPRequest) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) { 86 if len(path) == 0 { 87 return req, nil 88 } 89 90 segmentIdx := 0 91 segment := path[segmentIdx] 92 93 if typ := segment.Type(); typ != types.String { 94 return values.None, core.NewPathError(core.TypeError(typ, types.String), segmentIdx) 95 } 96 97 field := segment.String() 98 99 switch field { 100 case "url", "URL": 101 return values.NewString(req.URL), nil 102 case "method": 103 return values.NewString(req.Method), nil 104 case "headers": 105 if len(path) == 1 { 106 return req.Headers, nil 107 } 108 109 out, pathErr := req.Headers.GetIn(ctx, path[1:]) 110 111 if pathErr != nil { 112 return values.None, core.NewPathErrorFrom(pathErr, segmentIdx) 113 } 114 115 return out, nil 116 case "body": 117 return values.NewBinary(req.Body), nil 118 } 119 120 return values.None, nil 121 }