How to Test Multipart Upload Integrity Through a Proxy

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:
| Part | Test value | Purpose |
|---|---|---|
| text | short ASCII value | basic field preservation |
| note | multilingual UTF-8 text | encoding and length handling |
| tag | two fields with the same name | repeated-field order and multiplicity |
| empty | zero-byte field | empty-value preservation |
| file_a | deterministic binary file | byte integrity |
| file_b | zero-byte file | empty-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:
- a body whose total length is known before transmission;
- 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
| Symptom | Likely investigation |
|---|---|
| missing boundary parameter | client manually set Content-Type or header was altered |
| server reports one giant field | malformed delimiter or line endings |
| last part missing | truncation or missing closing delimiter |
| binary digest mismatch | body transformation, truncation or fixture error |
| one repeated value survives | framework or application collapsed duplicates |
| direct works, streamed proxy fails | buffering, framing, timeout or gateway limit |
| two application results | unsafe replay after an ambiguous failure |
| success status but wrong receipt | application 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.
Related Recommendations
- How to Sanitize HAR Files Before Sharing Proxy Debug Logs
- Proxy Bandwidth Cost Benchmark: Measure the Price of Useful Data
- How to Validate a Proxy SLA Before You Buy
- Proxy NAT64 and DNS64 Compatibility Test for IPv6-Only Networks
- How to Test Residential Proxy ASN Targeting Before You Buy
- How to Test HTTPS Proxy TLS and Cipher Compatibility Before Purchase
- How to set up an HTTP proxy server on iPhone or iPad
- Proxy Client Ephemeral Port Exhaustion: Diagnose Failures and Plan Capacity
- Replay Proxy Requests Safely with Chrome DevTools 152
- How to Estimate Proxy Bandwidth Before Choosing a Plan