File Upload, Download, Stream, and Multipart

File Upload

Upload a file from a Path to a remote server.

Http http = Http.create();
HttpResult result = http.upload(HttpMethod.POST, "https://api.example.com/files",
        Map.of("Content-Type", "application/octet-stream"),
        Path.of("document.pdf")).execute();
System.out.println(result.statusCode());

Memory Safety

The file is streamed from disk using BodyPublishers.ofFile(). The library does not load the entire file into memory.

Error Handling

try {
    http.upload(HttpMethod.POST, "https://api.example.com/files",
            Map.of("Content-Type", "application/octet-stream"),
            Path.of("nonexistent.pdf")).execute();
} catch (HttpException e) {
    System.err.println("Upload failed: " + e.getMessage());
}

Download to File

Download the response body directly to a file on disk.

Http http = Http.create();
HttpDownloadResult result = http.download(HttpMethod.GET, "https://api.example.com/files/123",
        Map.of(),
        Path.of("downloaded.pdf")).execute();
System.out.println("Downloaded " + result.bytesWritten() + " bytes to " + result.file());

Memory Safety

The response body is streamed directly to the file. The library never holds the full response in memory. Works for files of any size.

Parent Directory Creation

If the target directory does not exist, it is created automatically before the download begins.

Overwrite Behavior

If the target file exists, it is overwritten.

Error Handling

try {
    http.download(HttpMethod.GET, "https://api.example.com/files/999",
            Map.of(),
            Path.of("output.pdf")).execute();
} catch (HttpException e) {
    System.err.println("Download failed: " + e.getMessage());
    System.err.println("Status: " + e.statusCode());
}

Stream Response as InputStream

Get the response body as an InputStream for caller-controlled reading.

Http http = Http.create();
HttpStreamResult result = http.stream(HttpMethod.GET, "https://api.example.com/stream",
        Map.of(), null).execute();
try (InputStream is = result.inputStream()) {
    is.transferTo(System.out);
}

Caller Responsibility

Use Cases

Multipart/form-data

Send form fields and files as multipart/form-data.

Http http = Http.create();
HttpResult result = http.multipart(HttpMethod.POST, "https://api.example.com/upload",
        Map.of("Authorization", "Bearer token"),
        Map.of("name", "Arthur", "email", "arthur@example.com"),
        Map.of("avatar", Path.of("photo.jpg"), "resume", Path.of("cv.pdf"))).execute();
System.out.println(result.statusCode());

Content-Type Header

The Content-Type: multipart/form-data; boundary=... header is set automatically. Do not set it manually.

Text Fields

Text fields are passed as Map<String, String>. Each entry becomes a form-data part:

--boundary
Content-Disposition: form-data; name="name"

Arthur

File Fields

File fields are passed as Map<String, Path>. Each entry becomes a form-data part with the filename:

--boundary
Content-Disposition: form-data; name="avatar"; filename="photo.jpg"
Content-Type: application/octet-stream

<binary content>

Memory Safety

File content is streamed from disk. The library does not load entire files into memory. Each file part is read sequentially during the upload.

Empty Fields or Files

Error Handling

try {
    http.multipart(HttpMethod.POST, "https://api.example.com/upload",
            Map.of(),
            Map.of("name", "Arthur"),
            Map.of("file", Path.of("missing.txt"))).execute();
} catch (HttpException e) {
    System.err.println("Upload failed: " + e.getMessage());
}

toCurl for File Operations

// Upload
http.upload(HttpMethod.POST, "https://api.example.com/files", Map.of(), Path.of("doc.pdf")).toCurl();
// curl -X POST 'https://api.example.com/files' --data-binary '@doc.pdf'

// Download
http.download(HttpMethod.GET, "https://api.example.com/files/123", Map.of(), Path.of("out.pdf")).toCurl();
// curl 'https://api.example.com/files/123' -o 'out.pdf'

// Multipart
http.multipart(HttpMethod.POST, "https://api.example.com/upload", Map.of(),
        Map.of("name", "Arthur"), Map.of("file", Path.of("photo.jpg"))).toCurl();
// curl -X POST 'https://api.example.com/upload' -F 'name=Arthur' -F 'file=@photo.jpg'

Use HttpMethod constants for standard methods. Raw method strings are accepted for custom or uncommon methods.