How to Test Multipart Upload Integrity Through a Proxy

Several Internet data parts pass through a transparent proxy gateway and reassemble into one intact package

An HTTP proxy can succeed on ordinary page requests and still fail a real upload workflow. Multipart requests combine text fields, repeated names, filenames, per-part headers and arbitrary binary bytes inside one body. A route that buffers, truncates, retries or transforms that body can produce a successful-looking response while the application receives missing fields, corrupted files or duplicate submissions.

This guide creates a deterministic acceptance test for multipart/form-data. Use only an endpoint you own or are explicitly authorized to test. The goal is to verify correctness and useful outcomes, not to push large files through unrelated services.

Understand the boundary contract

The request Content-Type includes a boundary parameter. That same boundary separates every part in the body, with exact delimiter syntax and a closing delimiter at the end. Each part has its own headers, a blank line and a payload.

The client library should normally generate both the body and matching header. In browser code, manually setting Content-Type: multipart/form-data often omits the generated boundary and creates an invalid request. The test must inspect what was actually transmitted, not only the code that constructed the form.

A compliant intermediary should transport the body without silently changing boundaries, part headers or bytes. It may legitimately use different transfer framing on either hop, so compare the decoded HTTP message rather than assuming identical packet boundaries.

Build an owned upload fixture

Create a laboratory endpoint that accepts one request and returns a compact receipt. Include these parts:

PartTest valuePurpose
textshort ASCII valuebasic field preservation
notemultilingual UTF-8 textencoding and length handling
tagtwo fields with the same namerepeated-field order and multiplicity
emptyzero-byte fieldempty-value preservation
file_adeterministic binary filebyte integrity
file_bzero-byte fileempty-file behavior

Generate the binary fixture locally from a fixed seed and record its SHA-256 digest. Include zero bytes, high-bit bytes, CRLF sequences and chunks that resemble ordinary boundary text. Do not include credentials, personal data or production files.

The server receipt should report only safe evidence: field counts, ordered field-name hashes, sanitized filename, declared media type, received byte count, per-file digest and one application result ID.

Establish a direct baseline

Send the fixture without a proxy using the exact client and version planned for production. Confirm:

  • the header boundary matches the body delimiters;
  • every expected part appears exactly once, except the intentionally repeated field;
  • repeated values retain the application-required order;
  • empty field and empty file remain present;
  • UTF-8 text round-trips correctly;
  • both file length and digest match;
  • the closing delimiter is present;
  • one request creates one application result.

Save a redacted receipt as the baseline. Do not store raw upload bodies when hashes and counts are sufficient.

Compare one proxy route at a time

Keep the client, fixture, endpoint and timeout constant. Change only the proxy gateway, region, authentication mode, session policy or address family. For every attempt record:

test_id
route_alias
client_version
client_to_proxy_protocol
proxy_to_origin_protocol
request_content_type_hash
part_count
repeated_field_count
received_file_bytes
received_file_digest_match
final_status
application_result_count
retry_count

Hash the complete Content-Type value if it contains a random boundary. Never log proxy credentials, cookies, authorization headers, raw session IDs or private file contents.

Use the proxy request-header integrity test if the boundary parameter disappears or changes. Use the proxy response-integrity test when the receipt arrives incomplete.

Test buffered and streamed bodies

Run two client modes when supported:

  1. a body whose total length is known before transmission;
  2. a streamed body whose transfer framing may be decided at runtime.

The application-level multipart structure must be identical even if the transport uses Content-Length on one path and chunked or protocol-native framing on another. Test small and moderately large synthetic files, but keep volume below provider and endpoint limits.

If a streamed upload fails only through the proxy, capture whether failure occurs during proxy authentication, tunnel establishment, headers, first body bytes, mid-body transfer or final response. A total timeout alone is not enough evidence.

Exercise filenames and repeated fields safely

Clients and servers differ in how they encode non-ASCII filenames. Test a plain filename first, then a harmless multilingual name if the application supports it. The server must strip directory components and must never trust a client-supplied filename as a filesystem path.

Repeated field names are legal and common. Verify the framework returns all values rather than keeping only the first or last. If order matters, make that contract explicit and test it. Avoid treating dictionary equality as proof of multipart equality because dictionaries can erase duplicates.

Test redirects deliberately

An upload endpoint should avoid unnecessary redirects. If a redirect is part of the owned workflow, test the exact status code and client behavior. Some redirect handling can change the method or decline to replay a body. Record whether the client resent the request, which destination received it and how many application results were created.

Do not allow a redirect to an unapproved host. Keep an allowlist and stop when the destination changes outside the owned test scope.

Make retries safe

Network failure after the final body byte creates ambiguity: the server may have committed the upload even when the client did not receive the receipt. Blindly rotating the proxy and repeating can create duplicates.

Use an application idempotency key or an owned upload session identifier. Bound attempts, elapsed time and transmitted bytes. The same logical operation must return or reference one result. Follow the retry-storm prevention guide before enabling automated failover.

Pair this test with the Expect: 100-continue upload test when large bodies may be rejected from headers. The multipart test validates the body and application result; the Expect test validates the header/body handshake.

Diagnose failure patterns

SymptomLikely investigation
missing boundary parameterclient manually set Content-Type or header was altered
server reports one giant fieldmalformed delimiter or line endings
last part missingtruncation or missing closing delimiter
binary digest mismatchbody transformation, truncation or fixture error
one repeated value survivesframework or application collapsed duplicates
direct works, streamed proxy failsbuffering, framing, timeout or gateway limit
two application resultsunsafe replay after an ambiguous failure
success status but wrong receiptapplication validation or response-integrity failure

Do not label every multipart failure as poor exit-IP reputation. Most failures in this test concern message construction, transport framing, buffering, limits or retry logic.

Acceptance checklist

  • Client-generated boundary matches the body.
  • Expected part count and repeated values are preserved.
  • Empty fields and zero-byte files remain present.
  • Multilingual text round-trips correctly.
  • Sanitized filenames match the application contract.
  • File lengths and SHA-256 digests match.
  • Buffered and streamed modes are tested.
  • Redirect destinations and replay behavior are controlled.
  • One logical upload creates one application result.
  • Retries are bounded and idempotent.
  • Logs contain hashes and counts, not secrets or raw private files.

FAQ

Should browser code set the multipart Content-Type header manually?

Usually no. When a browser or form library generates the body, let it set the header so the boundary parameter matches. Confirm the behavior of the exact client you use.

Does a 200 response prove the upload is intact?

No. Validate the server receipt, part counts, byte lengths, file digests and application result count.

Can a proxy change transport framing without breaking multipart?

Yes. The two hops may use different legal framing. What must remain correct is the decoded HTTP message and multipart structure.

Should a failed upload immediately rotate the proxy IP?

No. First identify the failing phase and determine whether the server already committed the operation. Rotate only under a bounded, idempotent policy.

Compliance note

Test multipart uploads only against systems you own or have explicit permission to use. Respect file-size limits, rate limits, content policies, regional data requirements and proxy terms. Use synthetic fixtures, sanitize filenames, minimize retention and never use proxy rotation to bypass upload controls.