Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Insert middleware to allow org and prod id on requests (#142)
* add integration test for middleware * WIP try to edit URL * roundtripper updates URL with profile org/proj IDs * tweak middleware test * fix linter * refactor roundtripper, make profile integration test local only * update changelog * refactor tests to cover profile and source channel middlewares * WIP - adding middleware function signature as struct field * (wip) working middleware funcs implementation * roundtripper now has array of Middleware functions * add proj ID/org ID validation * update middleware test * remove unnecessary httpclient test * move middleware into its own file for organization * withProfile -> withOrgAndProjectIDs * update changelog entry * update changelog (again) Co-authored-by: Paras Prajapati <paras.prajapati@hashicorp.com> Co-authored-by: Brenna Hewer-Darroch <21015366+bcmdarroch@users.noreply.github.com>
- Loading branch information
1 parent
04fd8cf
commit 1d28ede
Showing
6 changed files
with
138 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
```release-note:improvement | ||
Add middleware support to httpclient package | ||
``` | ||
|
||
```release-note:improvement | ||
Add middleware that gets org ID and project ID from user profile and sets on request | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package httpclient | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// MiddlewareOption is a function that modifies an HTTP request. | ||
type MiddlewareOption = func(req *http.Request) error | ||
|
||
// roundTripperWithMiddleware takes a plain Roundtripper and an array of MiddlewareOptions to apply to the Roundtripper's request. | ||
type roundTripperWithMiddleware struct { | ||
OriginalRoundTripper http.RoundTripper | ||
MiddlewareOptions []MiddlewareOption | ||
} | ||
|
||
// withSourceChannel updates the request header to include the HCP Go SDK source channel stamp. | ||
func withSourceChannel(sourceChannel string) MiddlewareOption { | ||
return func(req *http.Request) error { | ||
req.Header.Set("X-HCP-Source-Channel", sourceChannel) | ||
return nil | ||
} | ||
} | ||
|
||
// withProfile takes the user profile's org ID and project ID and sets them in the request path if needed. | ||
func withOrgAndProjectIDs(orgID, projID string) MiddlewareOption { | ||
return func(req *http.Request) error { | ||
path := req.URL.Path | ||
path = strings.Replace(path, "organizations//", fmt.Sprintf("organizations/%s/", orgID), 1) | ||
path = strings.Replace(path, "projects//", fmt.Sprintf("projects/%s/", projID), 1) | ||
req.URL.Path = path | ||
return nil | ||
} | ||
} | ||
|
||
// RoundTrip attaches MiddlewareOption modifications to the request before sending along. | ||
func (rt *roundTripperWithMiddleware) RoundTrip(req *http.Request) (*http.Response, error) { | ||
|
||
for _, mw := range rt.MiddlewareOptions { | ||
if err := mw(req); err != nil { | ||
// Failure to apply middleware should not fail the request | ||
fmt.Printf("failed to apply middleware: %#v", mw(req)) | ||
continue | ||
} | ||
} | ||
|
||
return rt.OriginalRoundTripper.RoundTrip(req) | ||
} |