-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(RELTEC-12011): added implementation as standard HttpClient Round…
…Tripper interface
- Loading branch information
1 parent
993c0d2
commit 012cde9
Showing
8 changed files
with
290 additions
and
46 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,45 @@ | ||
package aurestcapture | ||
|
||
import ( | ||
"fmt" | ||
aurestclientapi "github.com/StephanHCB/go-autumn-restclient/api" | ||
"io" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
func NewRoundTripper(wrapped aurestclientapi.Client) http.RoundTripper { | ||
return &RequestCaptureImpl{Wrapped: wrapped} | ||
} | ||
|
||
func (c *RequestCaptureImpl) RoundTrip(req *http.Request) (*http.Response, error) { | ||
requestStr := fmt.Sprintf("%s %s %v", req.Method, req.URL.String(), req.Body) | ||
c.recording = append(c.recording, requestStr) | ||
|
||
var bodyDto *[]byte | ||
parsedResponse := aurestclientapi.ParsedResponse{ | ||
Body: &bodyDto, | ||
} | ||
|
||
err := c.Wrapped.Perform(req.Context(), req.Method, req.URL.String(), req.Body, &parsedResponse) | ||
|
||
newReader := strings.NewReader(string(**(parsedResponse.Body.(**[]byte)))) | ||
readCloser := io.NopCloser(newReader) | ||
|
||
return &http.Response{ | ||
Status: "", | ||
StatusCode: parsedResponse.Status, | ||
Proto: "", | ||
ProtoMajor: 0, | ||
ProtoMinor: 0, | ||
Header: parsedResponse.Header, | ||
Body: readCloser, | ||
ContentLength: 0, | ||
TransferEncoding: nil, | ||
Close: false, | ||
Uncompressed: false, | ||
Trailer: nil, | ||
Request: nil, | ||
TLS: nil, | ||
}, err | ||
} |
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,60 @@ | ||
package auresthttpclient | ||
|
||
import ( | ||
aurestclientapi "github.com/StephanHCB/go-autumn-restclient/api" | ||
"net/http" | ||
"time" | ||
) | ||
|
||
type AuRestHttpClient struct { | ||
*http.Client | ||
|
||
// Now is exposed so tests can fixate the time by overwriting this field | ||
Now func() time.Time | ||
} | ||
|
||
func NewHttpClient(timeout time.Duration, customCACert []byte, | ||
requestManipulator aurestclientapi.RequestManipulatorCallback, customHttpTransport *http.RoundTripper) (*AuRestHttpClient, error) { | ||
|
||
var httpTransport http.RoundTripper | ||
if customHttpTransport == nil { | ||
httpTransport = &HttpClientRoundTripper{ | ||
wrapped: createHttpTransport(customCACert), | ||
RequestManipulator: requestManipulator, | ||
RequestMetricsCallback: doNothingMetricsCallback, | ||
ResponseMetricsCallback: doNothingMetricsCallback, | ||
} | ||
} else { | ||
httpTransport = *customHttpTransport | ||
} | ||
|
||
return &AuRestHttpClient{ | ||
Client: &http.Client{ | ||
Transport: httpTransport, | ||
Timeout: timeout, | ||
}, | ||
Now: time.Now, | ||
}, nil | ||
} | ||
|
||
type HttpClientRoundTripper struct { | ||
wrapped http.RoundTripper | ||
|
||
RequestManipulator aurestclientapi.RequestManipulatorCallback | ||
RequestMetricsCallback aurestclientapi.MetricsCallbackFunction | ||
ResponseMetricsCallback aurestclientapi.MetricsCallbackFunction | ||
} | ||
|
||
func (c *HttpClientRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { | ||
if c.RequestManipulator != nil { | ||
c.RequestManipulator(req.Context(), req) | ||
} | ||
|
||
c.RequestMetricsCallback(req.Context(), req.Method, req.URL.String(), 0, nil, 0, int(req.ContentLength)) | ||
|
||
response, err := c.wrapped.RoundTrip(req) | ||
|
||
c.ResponseMetricsCallback(req.Context(), req.Method, req.URL.String(), 0, nil, 0, int(req.ContentLength)) | ||
|
||
return response, err | ||
} |
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,63 @@ | ||
package aurestrecorder | ||
|
||
import ( | ||
"bytes" | ||
aurestclientapi "github.com/StephanHCB/go-autumn-restclient/api" | ||
"io" | ||
"net/http" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type RecorderRoundTripper struct { | ||
wrapped http.RoundTripper | ||
recorderPath string | ||
constructFilenameFunc ConstructFilenameFunction | ||
} | ||
|
||
func NewRecorderRoundTripper(wrapped http.RoundTripper, additionalOptions ...RecorderOptions) *RecorderRoundTripper { | ||
recorderPath, filenameFunc := initRecorderPathAndFilenameFunc(additionalOptions) | ||
return &RecorderRoundTripper{ | ||
wrapped: wrapped, | ||
recorderPath: recorderPath, | ||
constructFilenameFunc: filenameFunc, | ||
} | ||
} | ||
|
||
func (c *RecorderRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { | ||
response, err := c.wrapped.RoundTrip(req) | ||
|
||
if response != nil && c.recorderPath != "" { | ||
parsedResponse := aurestclientapi.ParsedResponse{ | ||
Body: string(readBodyAndReset(response)), | ||
Status: response.StatusCode, | ||
Header: response.Header, | ||
Time: time.Now(), | ||
} | ||
|
||
var requestBodyString string | ||
var requestBody io.ReadCloser | ||
if req.Body != nil { | ||
requestBody, _ = req.GetBody() | ||
requestBodyString = readBody(requestBody) | ||
} | ||
recordResponseData(req.Method, req.URL.String(), requestBodyString, &parsedResponse, err, c.recorderPath, c.constructFilenameFunc) | ||
} | ||
return response, err | ||
} | ||
|
||
func readBodyAndReset(res *http.Response) []byte { | ||
bodyBytes, _ := io.ReadAll(res.Body) | ||
//reset the response body to the original unread state | ||
res.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) | ||
return bodyBytes | ||
} | ||
|
||
func readBody(requestBody io.ReadCloser) string { | ||
if requestBody != nil { | ||
buf := new(strings.Builder) | ||
_, _ = io.Copy(buf, requestBody) | ||
return buf.String() | ||
} | ||
return "" | ||
} |
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
Oops, something went wrong.