Handling File Uploads and Downloads
1. Configuring Multipart Form Data
Example: multipart request
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----X
------X
Content-Disposition: form-data; name="file"; filename="a.png"
Content-Type: image/png
[binary]
------X--
| Setting | Tuning |
|---|---|
| Boundary detection | Auto from Content-Type |
| Streaming parse | Don't buffer full body |
| Per-part size limit | Reject huge fields |
| Field count limit | Anti-DoS |
2. Setting Upload Size Limits
| Use Case | Limit |
|---|---|
| Avatar | 2 MB |
| Document | 25 MB |
| Video | 500 MB - 5 GB |
| Backup | Multi-part / TUS |
3. Implementing Chunked Upload
| Protocol | Standard |
|---|---|
| HTTP chunked transfer | RFC 7230 §4.1 |
| TUS | tus.io resumable |
| S3 multipart | 5MB+ parts |
| Custom chunk + assemble | App-level |
4. Using Resumable Uploads
Example: TUS protocol
POST /files HTTP/1.1
Tus-Resumable: 1.0.0
Upload-Length: 104857600
Upload-Metadata: filename YS5tcDQ=
HTTP/1.1 201 Created
Location: /files/abc123
PATCH /files/abc123 HTTP/1.1
Tus-Resumable: 1.0.0
Upload-Offset: 0
Content-Type: application/offset+octet-stream
5. Configuring File Type Validation
| Method | Notes |
|---|---|
| Extension check | Easy to spoof, weak |
| MIME from header | Client-supplied, unreliable |
| Magic bytes | First bytes (libmagic) |
| Deep inspection | Parse PDF/image structure |
6. Setting Up Temporary Storage
| Location | Use |
|---|---|
| tmpfs (RAM) | Small, fast |
| Local disk | Medium files |
| Object store (S3) | Direct upload via signed URL |
| Cleanup job | Delete after N hours |
7. Implementing Virus Scanning
| Engine | Notes |
|---|---|
| ClamAV | Open source, FOSS |
| VirusTotal API | Multi-engine, rate-limited |
| AWS GuardDuty Malware Protection | S3 native |
| Sandboxed exec | For binaries/macros |
8. Configuring Download Streaming
| Setting | Value |
|---|---|
proxy_buffering | off (for live streams) |
X-Accel-Redirect | Internal redirect (NGINX) |
sendfile | Zero-copy kernel send |
| Range support | Accept-Ranges: bytes |
9. Using Content-Disposition Headers
| Value | Effect |
|---|---|
inline | Render in browser |
attachment | Force download |
filename="report.pdf" | Suggested name |
filename*=UTF-8''r%C3%A9.pdf | RFC 5987 unicode |
10. Setting Up Signed URLs
Example: Pre-signed S3 URL
PresignedGetObjectRequest req = s3Presigner.presignGetObject(b -> b
.signatureDuration(Duration.ofMinutes(15))
.getObjectRequest(GetObjectRequest.builder()
.bucket("uploads").key("abc.pdf").build()));
return req.url().toString();
| Parameter | Purpose |
|---|---|
| Expiry | Short TTL (5-60 min) |
| IP binding | Restrict to source IP |
| Method restriction | GET only or PUT only |
| Content-Type lock | Force upload type |