diff options
| author | jwijenbergh <jeroenwijenbergh@protonmail.com> | 2022-03-18 10:45:10 +0100 |
|---|---|---|
| committer | jwijenbergh <jeroenwijenbergh@protonmail.com> | 2022-04-05 12:26:15 +0200 |
| commit | 343836597df3efd6f31a68e29ff82b6ec4979f69 (patch) | |
| tree | fa00080e0379859a9b4b770bbd36743f56731d61 /src | |
| parent | 42488834f8f60627830732428017cdf26733f12c (diff) | |
Move HTTP GET/POST methods to its own file
Diffstat (limited to 'src')
| -rw-r--r-- | src/api.go | 46 | ||||
| -rw-r--r-- | src/error.go | 42 | ||||
| -rw-r--r-- | src/http.go | 119 | ||||
| -rw-r--r-- | src/oauth.go | 31 | ||||
| -rw-r--r-- | src/server.go | 27 |
5 files changed, 136 insertions, 129 deletions
@@ -2,8 +2,6 @@ package eduvpn import ( "encoding/json" - "errors" - "io/ioutil" "net/http" ) @@ -24,21 +22,10 @@ type EduVPNEndpoints struct { func APIGetEndpoints(vpnState *EduVPNState) (*EduVPNEndpoints, error) { url := vpnState.Server + "/.well-known/vpn-user-portal" - resp, reqErr := http.Get(url) - if reqErr != nil { - return nil, reqErr - } - // Close the response body at the end - defer resp.Body.Close() + body, bodyErr := HTTPGet(url) - // Check if http response code is ok - if resp.StatusCode != http.StatusOK { - panic("http code not ok") - } - // Read the body - body, readErr := ioutil.ReadAll(resp.Body) - if readErr != nil { - return nil, readErr + if bodyErr != nil { + return nil, bodyErr } structure := &EduVPNEndpoints{} @@ -54,29 +41,10 @@ func APIGetEndpoints(vpnState *EduVPNState) (*EduVPNEndpoints, error) { func APIAuthenticatedInfo(vpnState *EduVPNState) (string, error) { url := vpnState.Endpoints.API.V3.API + "/info" - client := &http.Client{} - req, reqErr := http.NewRequest(http.MethodGet, url, nil) - if reqErr != nil { - return "", reqErr - } - req.Header.Add("Authorization", "Bearer "+vpnState.OAuthToken.Access) - resp, reqErr := client.Do(req) - - if reqErr != nil { - return "", reqErr - } - // Close the response body at the end - defer resp.Body.Close() - - // Check if http response code is ok - if resp.StatusCode != http.StatusOK { - return "", errors.New("HTTP code not ok") - } - - // Read the body - body, readErr := ioutil.ReadAll(resp.Body) - if readErr != nil { - return "", readErr + headers := &http.Header{"Authorization": {"Bearer " + vpnState.OAuthToken.Access}} + body, bodyErr := HTTPGetWithOptionalParams(url, &HTTPOptionalParams{Headers: headers}) + if bodyErr != nil { + return "", bodyErr } return string(body), nil } diff --git a/src/error.go b/src/error.go deleted file mode 100644 index 13803cc..0000000 --- a/src/error.go +++ /dev/null @@ -1,42 +0,0 @@ -package eduvpn - -import "fmt" - -// Error structures defined here are used throughout the code - -type HTTPResourceError struct { - URL string - Err error -} - -func (e *HTTPResourceError) Error() string { - return fmt.Sprintf("failed obtaining HTTP resource %s with error %v", e.URL, e.Err) -} - -type HTTPStatusError struct { - URL string - Status int -} - -func (e *HTTPStatusError) Error() string { - return fmt.Sprintf("failed obtaining HTTP resource %s as it gave an unsuccesful status code %d", e.URL, e.Status) -} - -type HTTPReadError struct { - URL string - Err error -} - -func (e *HTTPReadError) Error() string { - return fmt.Sprintf("failed reading HTTP resource %s with error %v", e.URL, e.Err) -} - -type HTTPParseJsonError struct { - URL string - Body string - Err error -} - -func (e *HTTPParseJsonError) Error() string { - return fmt.Sprintf("failed parsing json %s for HTTP resource %s with error %v", e.Body, e.URL, e.Err) -} diff --git a/src/http.go b/src/http.go new file mode 100644 index 0000000..57e5939 --- /dev/null +++ b/src/http.go @@ -0,0 +1,119 @@ +package eduvpn + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +type HTTPResourceError struct { + URL string + Err error +} + +func (e *HTTPResourceError) Error() string { + return fmt.Sprintf("failed obtaining HTTP resource %s with error %v", e.URL, e.Err) +} + +type HTTPStatusError struct { + URL string + Status int +} + +func (e *HTTPStatusError) Error() string { + return fmt.Sprintf("failed obtaining HTTP resource %s as it gave an unsuccesful status code %d", e.URL, e.Status) +} + +type HTTPReadError struct { + URL string + Err error +} + +func (e *HTTPReadError) Error() string { + return fmt.Sprintf("failed reading HTTP resource %s with error %v", e.URL, e.Err) +} + +type HTTPParseJsonError struct { + URL string + Body string + Err error +} + +func (e *HTTPParseJsonError) Error() string { + return fmt.Sprintf("failed parsing json %s for HTTP resource %s with error %v", e.Body, e.URL, e.Err) +} + +type HTTPRequestCreateError struct { + URL string + Err error +} + +func (e *HTTPRequestCreateError) Error() string { + return fmt.Sprintf("failed to create HTTP request with url %s and error %v", e.URL, e.Err) +} + +type HTTPOptionalParams struct { + Headers *http.Header +} + +func HTTPGet(url string) ([]byte, error) { + return HTTPGetWithOptionalParams(url, nil) +} + +func HTTPGetWithOptionalParams(url string, opts *HTTPOptionalParams) ([]byte, error) { + client := &http.Client{} + req, reqErr := http.NewRequest(http.MethodGet, url, nil) + if reqErr != nil { + return nil, &HTTPRequestCreateError{URL: url, Err: reqErr} + } + if opts != nil && opts.Headers != nil { + for k, v := range *opts.Headers { + req.Header.Add(k, v[0]) + } + } + resp, respErr := client.Do(req) + + if respErr != nil { + return nil, &HTTPResourceError{URL: url, Err: respErr} + } + defer resp.Body.Close() + + body, readErr := ioutil.ReadAll(resp.Body) + if readErr != nil { + return nil, &HTTPReadError{URL: url, Err: readErr} + } + + return body, nil +} + +func HTTPPost(url string, body url.Values) ([]byte, error) { + return HTTPPostWithOptionalParams(url, body, nil) +} + +func HTTPPostWithOptionalParams(url string, data url.Values, opts *HTTPOptionalParams) ([]byte, error) { + client := &http.Client{} + req, reqErr := http.NewRequest(http.MethodPost, url, strings.NewReader(data.Encode())) + if reqErr != nil { + return nil, &HTTPRequestCreateError{URL: url, Err: reqErr} + } + if opts != nil && opts.Headers != nil { + for k, v := range *opts.Headers { + req.Header.Add(k, v[0]) + } + } + resp, respErr := client.Do(req) + + if respErr != nil { + return nil, &HTTPResourceError{URL: url, Err: respErr} + } + defer resp.Body.Close() + + body, readErr := ioutil.ReadAll(resp.Body) + if readErr != nil { + return nil, &HTTPReadError{URL: url, Err: readErr} + } + + return body, nil +} diff --git a/src/oauth.go b/src/oauth.go index 5b7a5c4..2da7af5 100644 --- a/src/oauth.go +++ b/src/oauth.go @@ -6,10 +6,8 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io/ioutil" "net/http" "net/url" - "strings" ) type OAuthGenStateUnableError struct { @@ -124,6 +122,7 @@ func (eduvpn *EduVPNOAuthSession) getTokens(authCode string) error { // Make sure the verifier is set as the parameter // so that the server can verify that we are the actual owner of the authorization code + reqURL := eduvpn.VPNState.Endpoints.API.V3.Token data := url.Values{ "client_id": {eduvpn.VPNState.Name}, "code": {authCode}, @@ -131,33 +130,19 @@ func (eduvpn *EduVPNOAuthSession) getTokens(authCode string) error { "grant_type": {"authorization_code"}, "redirect_uri": {"http://127.0.0.1:8000/callback"}, } - client := &http.Client{} - url := eduvpn.VPNState.Endpoints.API.V3.Token - req, reqErr := http.NewRequest(http.MethodPost, url, strings.NewReader(data.Encode())) - if reqErr != nil { // shouldn't happen - panic(reqErr) - } - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - resp, reqErr := client.Do(req) - - if reqErr != nil { - return &HTTPResourceError{URL: url, Err: reqErr} - } - - // Close the response body at the end - defer resp.Body.Close() - - // Read the body - body, readErr := ioutil.ReadAll(resp.Body) - if readErr != nil { - return &HTTPReadError{URL: url, Err: readErr} + headers := &http.Header{ + "content-type": {"application/x-www-form-urlencoded"}} + opts := &HTTPOptionalParams{Headers: headers} + body, bodyErr := HTTPPostWithOptionalParams(reqURL, data, opts) + if bodyErr != nil { + return bodyErr } tokenStructure := &EduVPNOAuthToken{} jsonErr := json.Unmarshal(body, tokenStructure) if jsonErr != nil { - return &HTTPParseJsonError{URL: url, Body: string(body), Err: jsonErr} + return &HTTPParseJsonError{URL: reqURL, Body: string(body), Err: jsonErr} } eduvpn.VPNState.OAuthToken = tokenStructure diff --git a/src/server.go b/src/server.go index ca130d0..ced7716 100644 --- a/src/server.go +++ b/src/server.go @@ -2,31 +2,8 @@ package eduvpn import ( "fmt" - "io/ioutil" - "net/http" ) -func getFileUrl(url string) ([]byte, error) { - // Do a Get request to the specified url - resp, reqErr := http.Get(url) - if reqErr != nil { - return nil, &HTTPResourceError{URL: url, Err: reqErr} - } - // Close the response body at the end - defer resp.Body.Close() - - // Check if http response code is ok - if resp.StatusCode != http.StatusOK { - return nil, &HTTPStatusError{URL: url, Status: resp.StatusCode} - } - // Read the body - body, readErr := ioutil.ReadAll(resp.Body) - if readErr != nil { - return nil, &HTTPReadError{URL: url, Err: readErr} - } - return body, nil -} - type DiscoFileError struct { URL string Err error @@ -60,7 +37,7 @@ func getDiscoFile(jsonFile string) (string, error) { // Get json data discoURL := "https://disco.eduvpn.org/v2/" fileURL := discoURL + jsonFile - fileBody, fileErr := getFileUrl(fileURL) + fileBody, fileErr := HTTPGet(fileURL) if fileErr != nil { return "", &DiscoFileError{fileURL, fileErr} @@ -69,7 +46,7 @@ func getDiscoFile(jsonFile string) (string, error) { // Get signature sigFile := jsonFile + ".minisig" sigURL := discoURL + sigFile - sigBody, sigFileErr := getFileUrl(sigURL) + sigBody, sigFileErr := HTTPGet(sigURL) if sigFileErr != nil { return "", &DiscoSigFileError{URL: sigURL, Err: sigFileErr} |
