github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/applicationproxy/pingrequest/pingrequest.go (about) 1 package pingrequest 2 3 import ( 4 "bufio" 5 "bytes" 6 "errors" 7 "net/http" 8 9 "github.com/vmihailenco/msgpack" 10 "go.aporeto.io/enforcerd/trireme-lib/policy" 11 ) 12 13 // PingHeaderKey holds the value for aporeto ping. 14 const PingHeaderKey = "X-APORETO-PING" 15 16 // CreateRaw is same as 'Create' but will return raw bytes of 17 // the request (wire format) returned by 'Create'. 18 func CreateRaw(host string, pingPayload *policy.PingPayload) ([]byte, error) { 19 20 req, err := Create(host, pingPayload) 21 if err != nil { 22 return nil, err 23 } 24 25 var buf bytes.Buffer 26 if err := req.Write(&buf); err != nil { 27 return nil, err 28 } 29 30 return buf.Bytes(), nil 31 } 32 33 // ExtractRaw is same as 'Extract' but will parse the raw 34 // bytes of the request passed and calls 'Validate'. 35 func ExtractRaw(rawReq []byte) (*policy.PingPayload, error) { 36 37 buf := bytes.NewBuffer(rawReq) 38 req, err := http.ReadRequest(bufio.NewReader(buf)) 39 if err != nil { 40 return nil, err 41 } 42 43 return Extract(req) 44 } 45 46 // Create creates a new http request with the given host. 47 // It encodes the pingPayload passed with msgpack encoding and 48 // adds the data bytes to the header with key 'X-APORETO-PING'. 49 // It also returns the request. 50 func Create(host string, pingPayload *policy.PingPayload) (*http.Request, error) { 51 52 req, err := http.NewRequest("GET", host, nil) 53 if err != nil { 54 return nil, err 55 } 56 57 payload, err := encode(pingPayload) 58 if err != nil { 59 return nil, err 60 } 61 62 req.Header.Add(PingHeaderKey, string(payload)) 63 64 return req, nil 65 } 66 67 // Extract verifies If the given request has the header 68 // 'X-APORETO-PING'. If it doesn't returns error, If it did have 69 // the header, it will try to decode the data using msgpack 70 // encoding and will return the ping payload. 71 func Extract(req *http.Request) (*policy.PingPayload, error) { 72 73 payload := req.Header.Get(PingHeaderKey) 74 if payload == "" { 75 return nil, errors.New("missing ping payload in header") 76 } 77 78 pingPayload, err := decode([]byte(payload)) 79 if err != nil { 80 return nil, err 81 } 82 83 return pingPayload, nil 84 } 85 86 func encode(pingPayload *policy.PingPayload) ([]byte, error) { 87 return msgpack.Marshal(pingPayload) 88 } 89 90 func decode(data []byte) (*policy.PingPayload, error) { 91 92 pingPayload := &policy.PingPayload{} 93 94 if err := msgpack.Unmarshal(data, pingPayload); err != nil { 95 return nil, err 96 } 97 98 return pingPayload, nil 99 }