github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/requests/request.go (about) 1 /* 2 * Copyright (C) 2017 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package requests 19 20 import ( 21 "bytes" 22 "encoding/json" 23 "fmt" 24 "net/http" 25 "net/url" 26 27 "github.com/mysteriumnetwork/node/identity" 28 ) 29 30 const ( 31 mysteriumAgentName = "goclient-v0.1" 32 authenticationHeaderName = "Authorization" 33 authenticationSchemaName = "Signature" 34 ) 35 36 // NewGetRequest generates http Get request 37 func NewGetRequest(apiURI, path string, params url.Values) (*http.Request, error) { 38 if params != nil { 39 path = fmt.Sprintf("%v?%v", path, params.Encode()) 40 } 41 return newRequest(http.MethodGet, apiURI, path, nil) 42 } 43 44 // NewPostRequest generates http Post request 45 func NewPostRequest(apiURI, path string, requestBody interface{}) (*http.Request, error) { 46 encodedBody, err := encodeToJSON(requestBody) 47 if err != nil { 48 return nil, err 49 } 50 return newRequest(http.MethodPost, apiURI, path, encodedBody) 51 } 52 53 // NewSignedRequest signs payload and generates http request 54 func NewSignedRequest(httpMethod, apiURI, path string, requestBody interface{}, signer identity.Signer) (*http.Request, error) { 55 var encodedBody []byte = nil 56 if requestBody != nil { 57 var err error 58 encodedBody, err = encodeToJSON(requestBody) 59 if err != nil { 60 return nil, err 61 } 62 } 63 64 signature, err := getBodySignature(encodedBody, signer) 65 if err != nil { 66 return nil, err 67 } 68 69 req, err := newRequest(httpMethod, apiURI, path, encodedBody) 70 if err != nil { 71 return nil, err 72 } 73 74 req.Header.Add(authenticationHeaderName, authenticationSchemaName+" "+signature.Base64()) 75 76 return req, nil 77 } 78 79 // NewSignedGetRequest signs empty message and generates http Get request 80 func NewSignedGetRequest(apiURI, path string, signer identity.Signer) (*http.Request, error) { 81 return NewSignedRequest(http.MethodGet, apiURI, path, nil, signer) 82 } 83 84 // NewSignedPostRequest signs payload and generates http Post request 85 func NewSignedPostRequest(apiURI, path string, requestBody interface{}, signer identity.Signer) (*http.Request, error) { 86 return NewSignedRequest(http.MethodPost, apiURI, path, requestBody, signer) 87 } 88 89 // NewSignedPutRequest signs payload and generates http Put request 90 func NewSignedPutRequest(apiURI, path string, requestBody interface{}, signer identity.Signer) (*http.Request, error) { 91 return NewSignedRequest(http.MethodPut, apiURI, path, requestBody, signer) 92 } 93 94 func encodeToJSON(value interface{}) ([]byte, error) { 95 return json.Marshal(value) 96 } 97 98 func newRequest(method, apiURI, path string, body []byte) (*http.Request, error) { 99 url := apiURI 100 if len(path) > 0 { 101 url = fmt.Sprintf("%v/%v", apiURI, path) 102 } 103 req, err := http.NewRequest(method, url, bytes.NewBuffer(body)) 104 if err != nil { 105 return nil, err 106 } 107 req.Header.Set("User-Agent", mysteriumAgentName) 108 req.Header.Set("Content-Type", "application/json") 109 req.Header.Set("Accept", "application/json") 110 111 return req, nil 112 } 113 114 func getBodySignature(encodedBody []byte, signer identity.Signer) (identity.Signature, error) { 115 var message = encodedBody 116 if message == nil { 117 message = []byte("") 118 } 119 120 return signer.Sign(message) 121 }