Add compressed request body echo endpoint#264
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #264 +/- ##
==========================================
- Coverage 94.81% 94.59% -0.23%
==========================================
Files 9 9
Lines 2027 2055 +28
==========================================
+ Hits 1922 1944 +22
- Misses 62 65 +3
- Partials 43 46 +3
🚀 New features to boost your workflow:
|
mccutchen
left a comment
There was a problem hiding this comment.
Seems like a useful addition to me, but my expectation of an /echo endpoint would be to echo the request body back verbatim (so a gzip'd body would be gzip'd on the way back out).
My first instinct would be make the auto-decoding optional, based on a ?decode query param, but maybe this implementation is what would be most useful most of the time, and we should instead support a ?raw query param that disables decoding? That could be deferred to a follow-up if/when there's an actual need to disable auto-decoding.
So, LGTM overall, but I have a couple of small questions/suggestions below.
| body, err := io.ReadAll(io.LimitReader(reader, h.MaxBodySize+1)) | ||
| if err != nil { | ||
| writeError(w, http.StatusBadRequest, fmt.Errorf("error reading request body: %w", err)) | ||
| return | ||
| } | ||
| if int64(len(body)) > h.MaxBodySize { | ||
| writeError(w, http.StatusBadRequest, fmt.Errorf("request body exceeds maximum size of %d bytes", h.MaxBodySize)) | ||
| return | ||
| } |
There was a problem hiding this comment.
Is the second check here necessary? My epxectation is that io.LimitReader will take effect after incoming bytes are decoded from gzip/deflate and should effectively enforce the limit itself.
| reader = zr | ||
| } | ||
|
|
||
| body, err := io.ReadAll(io.LimitReader(reader, h.MaxBodySize+1)) |
| return | ||
| } | ||
|
|
||
| writeResponse(w, http.StatusOK, textContentType, body) |
There was a problem hiding this comment.
I think we should take the content-type from the incoming request (if given) and falling back to plain text by default. That way a POST /echo with Content-Type: application/json (or image/jpeg or whatever) would have an appropriate content type in the response.
|
Pushed follow-up commit
Validation with local Go 1.25.0:
I left the optional raw/no-decode switch out of this commit since you mentioned it could be deferred unless there is a concrete need. |
|
Pushed follow-up commit
Validation with local Go 1.26.4:
|
|
Pushed test-only follow-up commit What changed:
Local validation with Go 1.26.4:
I am not assuming the hosted Codecov status until it runs on the pushed commit. Romeo / romeoapps.com |
|
Seems like a potentially useful endpoint, but I'm not interested in contributions from automated agents. Come back with a human. |
Summary
/echoto return the request body as plain text.MaxBodySize, including compressed payloads that expand past the cap.Why
Some client test suites need a small HTTP echo endpoint that can verify request-body compression without depending on
com.sun.net.httpserveror a custom local test server. This keeps that use case inside go-httpbin's reusable binary/server surface.Validation
gofmt -w httpbin/httpbin.go httpbin/handlers.go httpbin/handlers_test.gogo test ./httpbin -run '^TestEcho$'go test ./...go test -race ./...git diff --check