[GH-ISSUE #2019] /batch/storage/v1 returns unexpected EOF for DELETE parts without body #244

Open
opened 2026-03-03 12:09:23 +03:00 by kerem · 1 comment
Owner

Originally created by @pohanhuang on GitHub (Sep 5, 2025).
Original GitHub issue: https://github.com/fsouza/fake-gcs-server/issues/2019

Context

  • Client: OpenDAL GCS batch delete (remove_all)
  • Server: fake-gcs /batch/storage/v1 (multipart/mixed with application/http parts)

Repro

curl -v -X POST http://localhost:4443/batch/storage/v1 \
  -H "Content-Type: multipart/mixed; boundary=boundary" \
  --data-binary @- <<'EOF'
--boundary
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 0

DELETE /storage/v1/b/test-bucket/o/a.txt HTTP/1.1

--boundary--
EOF

Expected

  • DELETE subrequests should be accepted without a body (GCS JSON API behavior).
  • Batch handler should not fail framing and return 400s.

Actual

  • http.ReadRequest fails with io.ErrUnexpectedEOF (missing body despite Content-Length or missing \r\n\r\n), causing 400 responses in the batch.

Proposal (minimal, safe)

  • In handleBatchCall, add a lenient parse path for application/http parts:

    • Try http.ReadRequest normally.

    • On io.ErrUnexpectedEOF and method DELETE, normalize once and retry:

      • inject {} with Content-Length: 2 for compatibility.
  • Only applies to DELETE parts; no change for other methods.

Tests

  • DELETE with no body, no Content-Length → OK.
Originally created by @pohanhuang on GitHub (Sep 5, 2025). Original GitHub issue: https://github.com/fsouza/fake-gcs-server/issues/2019 # **Context** * Client: OpenDAL GCS batch delete (`remove_all`) * Server: fake-gcs `/batch/storage/v1` (multipart/mixed with `application/http` parts) **Repro** ```bash curl -v -X POST http://localhost:4443/batch/storage/v1 \ -H "Content-Type: multipart/mixed; boundary=boundary" \ --data-binary @- <<'EOF' --boundary Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: 0 DELETE /storage/v1/b/test-bucket/o/a.txt HTTP/1.1 --boundary-- EOF ``` **Expected** * DELETE subrequests should be accepted without a body (GCS JSON API behavior). * Batch handler should not fail framing and return 400s. **Actual** * `http.ReadRequest` fails with `io.ErrUnexpectedEOF` (missing body despite `Content-Length` or missing `\r\n\r\n`), causing 400 responses in the batch. **Proposal (minimal, safe)** * In `handleBatchCall`, add a lenient parse path for `application/http` parts: * Try `http.ReadRequest` normally. * On `io.ErrUnexpectedEOF` and method `DELETE`, normalize once and retry: * inject `{}` with `Content-Length: 2` for compatibility. * Only applies to DELETE parts; no change for other methods. **Tests** * DELETE with no body, no `Content-Length` → OK.
Author
Owner

@pohanhuang commented on GitHub (Sep 5, 2025):

Hi @fsouza,
while integrating OpenDAL, I ran into an issue where the fake server returns an error when handling a batch DELETE request without a body (unexpected EOF).

This change adds a small adjustment so that such requests are handled gracefully.
It should not affect existing behavior or the overall framework, but it makes the fake server easier to use as a test backend for OpenDAL.

Please let me know if this direction looks good — I’d be happy to adjust the patch if needed.

<!-- gh-comment-id:3257226477 --> @pohanhuang commented on GitHub (Sep 5, 2025): Hi @fsouza, while integrating OpenDAL, I ran into an issue where the fake server returns an error when handling a batch DELETE request without a body (unexpected EOF). This change adds a small adjustment so that such requests are handled gracefully. It should not affect existing behavior or the overall framework, but it makes the fake server easier to use as a test backend for OpenDAL. Please let me know if this direction looks good — I’d be happy to adjust the patch if needed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/fake-gcs-server#244
No description provided.