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--
SettingTuning
Boundary detectionAuto from Content-Type
Streaming parseDon't buffer full body
Per-part size limitReject huge fields
Field count limitAnti-DoS

2. Setting Upload Size Limits

Use CaseLimit
Avatar2 MB
Document25 MB
Video500 MB - 5 GB
BackupMulti-part / TUS

3. Implementing Chunked Upload

ProtocolStandard
HTTP chunked transferRFC 7230 §4.1
TUStus.io resumable
S3 multipart5MB+ parts
Custom chunk + assembleApp-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

MethodNotes
Extension checkEasy to spoof, weak
MIME from headerClient-supplied, unreliable
Magic bytesFirst bytes (libmagic)
Deep inspectionParse PDF/image structure

6. Setting Up Temporary Storage

LocationUse
tmpfs (RAM)Small, fast
Local diskMedium files
Object store (S3)Direct upload via signed URL
Cleanup jobDelete after N hours

7. Implementing Virus Scanning

EngineNotes
ClamAVOpen source, FOSS
VirusTotal APIMulti-engine, rate-limited
AWS GuardDuty Malware ProtectionS3 native
Sandboxed execFor binaries/macros

8. Configuring Download Streaming

SettingValue
proxy_bufferingoff (for live streams)
X-Accel-RedirectInternal redirect (NGINX)
sendfileZero-copy kernel send
Range supportAccept-Ranges: bytes

9. Using Content-Disposition Headers

ValueEffect
inlineRender in browser
attachmentForce download
filename="report.pdf"Suggested name
filename*=UTF-8''r%C3%A9.pdfRFC 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();
ParameterPurpose
ExpiryShort TTL (5-60 min)
IP bindingRestrict to source IP
Method restrictionGET only or PUT only
Content-Type lockForce upload type