Core HTTP protocol support library for Eclipse Jetty providing header handling, parsing, generation, compliance validation, and content processing capabilities
—
Multi-part content handling for form data, file uploads, and byte ranges with async processing support, compliance validation, and streaming capabilities.
Namespace class for multi-part content processing with parsing, generation, and boundary utilities.
/**
* Namespace class for multi-part content support
*/
class MultiPart {
/** Extract boundary parameter from Content-Type header */
static String extractBoundary(String contentType);
/** Generate multipart boundary with prefix and random characters */
static String generateBoundary(String prefix, int randomLength);
/**
* Individual part within multi-part content
*/
abstract static class Part implements Content.Source.Factory, Closeable {
/** Get part name from Content-Disposition header */
String getName();
/** Get filename from Content-Disposition header */
String getFileName();
/** Get part headers */
HttpFields getHeaders();
/** Get part content as source */
Content.Source getContentSource();
/** Get part content length */
long getLength();
/** Get part content type */
String getContentType();
/** Check if part represents a file upload */
boolean isFile();
/** Close part and release resources */
void close();
}
/**
* Multi-part content parser
*/
static class Parser {
/** Create parser with boundary and buffer pool */
Parser(String boundary, ByteBufferPool bufferPool);
/** Parse content source into parts */
void parse(Content.Source source, PartHandler handler);
/** Interface for handling parsed parts */
interface PartHandler {
/** Handle parsed part */
void handle(Part part);
}
}
}Specialized multi-part processing for form data with async parsing.
/**
* Multi-part form data processing with async support
*/
class MultiPartFormData {
/** Create form data processor with default configuration */
MultiPartFormData();
/** Create with custom configuration */
MultiPartFormData(MultiPartConfig config);
/** Parse multi-part content asynchronously */
CompletableFuture<Parts> parse(Content.Source source);
/** Parse multi-part content synchronously (blocking) */
Parts from(Content.Source source);
/** Parse with content type header */
CompletableFuture<Parts> parse(Content.Source source, String contentType);
/** Get maximum part size */
long getMaxPartSize();
/** Set maximum part size */
void setMaxPartSize(long maxPartSize);
/** Get maximum file size for uploads */
long getMaxFileSize();
/** Set maximum file size for uploads */
void setMaxFileSize(long maxFileSize);
/** Get maximum request size */
long getMaxRequestSize();
/** Set maximum request size */
void setMaxRequestSize(long maxRequestSize);
/**
* Collection of parsed multi-part form parts
*/
interface Parts extends Iterable<MultiPart.Part> {
/** Get part by name */
MultiPart.Part get(String name);
/** Get all parts with given name */
List<MultiPart.Part> getAll(String name);
/** Get part names */
Set<String> getNames();
/** Get all parts as list */
List<MultiPart.Part> asList();
/** Get number of parts */
int size();
/** Check if empty */
boolean isEmpty();
/** Release all parts */
void release();
}
}Multi-part byte range processing for HTTP Range requests.
/**
* Multi-part byte ranges for HTTP Range responses
*/
class MultiPartByteRanges {
/** Create byte ranges with content type */
MultiPartByteRanges(String contentType);
/** Add byte range part */
void addPart(ByteRange range, Content.Source content);
/** Get boundary string */
String getBoundary();
/** Get content type with boundary */
String getContentType();
/** Get parts as content source */
Content.Source getContentSource();
/** Get total content length */
long getContentLength();
}Configuration for multi-part processing with size limits and temp directory settings.
/**
* Configuration for multi-part processing
*/
class MultiPartConfig {
/** Create configuration with default settings */
MultiPartConfig();
/** Create with size limits */
MultiPartConfig(long maxFileSize, long maxRequestSize, int fileSizeThreshold);
/** Create with full configuration */
MultiPartConfig(long maxFileSize, long maxRequestSize,
int fileSizeThreshold, String location);
/** Get maximum file size for individual uploads */
long getMaxFileSize();
/** Get maximum total request size */
long getMaxRequestSize();
/** Get file size threshold for writing to disk */
int getFileSizeThreshold();
/** Get temporary file location */
String getLocation();
}Multi-part compliance modes and violation handling.
/**
* Multi-part compliance modes and validation
*/
class MultiPartCompliance {
/** RFC 7578 compliant parsing */
static final MultiPartCompliance RFC7578;
/** Legacy compatibility mode */
static final MultiPartCompliance LEGACY;
/** Check if violation is allowed */
boolean allows(Violation violation);
/** Get allowed violations */
Set<Violation> getAllowed();
/** Get compliance mode name */
String getName();
/**
* Multi-part compliance violations
*/
enum Violation {
/** No boundary specified */
NO_BOUNDARY,
/** Invalid boundary characters */
INVALID_BOUNDARY,
/** Missing final boundary */
NO_FINAL_BOUNDARY,
/** Invalid Content-Disposition header */
INVALID_CONTENT_DISPOSITION,
/** Duplicate part names */
DUPLICATE_NAMES;
}
}HTTP Range request processing for partial content delivery.
/**
* HTTP Range request processing
*/
class ByteRange {
/** Create byte range */
ByteRange(long first, long last);
/** Get first byte position */
long getFirst();
/** Get last byte position */
long getLast();
/** Get range length */
long getLength();
/** Check if range is suffix range */
boolean isSuffix();
/** Get range as Content-Range header value */
String toHeaderValue(long contentLength);
/** Parse Range header value */
static List<ByteRange> parse(String rangeHeader, long contentLength);
/** Parse single range specification */
static ByteRange parseRange(String range, long contentLength);
/** Check if ranges are satisfiable */
static boolean satisfiable(List<ByteRange> ranges, long contentLength);
}Usage Examples:
import org.eclipse.jetty.http.*;
import java.util.concurrent.CompletableFuture;
// Parse multi-part form data asynchronously
MultiPartConfig config = new MultiPartConfig(
10 * 1024 * 1024, // maxFileSize: 10MB
50 * 1024 * 1024, // maxRequestSize: 50MB
8192, // fileSizeThreshold: 8KB
"/tmp" // temp directory
);
MultiPartFormData formData = new MultiPartFormData(config);
// Async parsing
Content.Source requestBody = getRequestBodySource();
CompletableFuture<MultiPartFormData.Parts> future =
formData.parse(requestBody, "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
future.thenAccept(parts -> {
// Process form fields
MultiPart.Part textField = parts.get("username");
if (textField != null) {
String username = readPartContent(textField);
}
// Process file uploads
MultiPart.Part fileUpload = parts.get("avatar");
if (fileUpload != null && fileUpload.isFile()) {
String filename = fileUpload.getFileName();
String contentType = fileUpload.getContentType();
long size = fileUpload.getLength();
// Save uploaded file
saveFile(fileUpload.getContentSource(), filename);
}
// Release resources
parts.release();
});
// Synchronous parsing
MultiPartFormData.Parts parts = formData.from(requestBody);
// Iterate through all parts
for (MultiPart.Part part : parts) {
String name = part.getName();
String filename = part.getFileName();
HttpFields headers = part.getHeaders();
if (part.isFile()) {
// Handle file upload
processFileUpload(part);
} else {
// Handle form field
String value = readPartContent(part);
}
}
// Get multiple parts with same name (e.g., checkboxes)
List<MultiPart.Part> selectedItems = parts.getAll("items");
for (MultiPart.Part item : selectedItems) {
String value = readPartContent(item);
}
// Create multi-part content programmatically
MultiPart multiPart = new MultiPart("----WebKitFormBoundary7MA4YWxkTrZu0gW");
// Add text part
MultiPart.Part textPart = createTextPart("username", "john.doe");
multiPart.addPart(textPart);
// Add file part
MultiPart.Part filePart = createFilePart("document", "report.pdf",
"application/pdf", fileContent);
multiPart.addPart(filePart);
// Multi-part byte ranges for HTTP Range responses
MultiPartByteRanges byteRanges = new MultiPartByteRanges("text/plain");
// Add range parts
ByteRange range1 = new ByteRange(0, 499); // bytes 0-499
ByteRange range2 = new ByteRange(1000, 1499); // bytes 1000-1499
byteRanges.addPart(range1, getContentSource(0, 500));
byteRanges.addPart(range2, getContentSource(1000, 500));
String contentType = byteRanges.getContentType();
// "multipart/byteranges; boundary=..."
// Parse HTTP Range header
String rangeHeader = "bytes=0-499,1000-1499";
long contentLength = 2000;
List<ByteRange> ranges = ByteRange.parse(rangeHeader, contentLength);
for (ByteRange range : ranges) {
long first = range.getFirst();
long last = range.getLast();
long length = range.getLength();
String contentRange = range.toHeaderValue(contentLength);
// "bytes 0-499/2000" or "bytes 1000-1499/2000"
}
// Check if ranges are satisfiable
boolean satisfiable = ByteRange.satisfiable(ranges, contentLength);
// Multi-part compliance handling
MultiPartCompliance compliance = MultiPartCompliance.RFC7578;
ComplianceViolation.Listener listener =
(mode, violation, details) -> {
System.err.println("Multi-part violation: " + violation + " - " + details);
};
// Helper methods (implementation dependent)
private String readPartContent(MultiPart.Part part) {
// Read part content as string
return null; // Implementation specific
}
private void saveFile(Content.Source source, String filename) {
// Save file to disk
}
private void processFileUpload(MultiPart.Part part) {
// Process uploaded file
}
private MultiPart.Part createTextPart(String name, String value) {
// Create text form field part
return null; // Implementation specific
}
private MultiPart.Part createFilePart(String name, String filename,
String contentType, byte[] content) {
// Create file upload part
return null; // Implementation specific
}
private Content.Source getRequestBodySource() {
// Get request body content source
return null; // Implementation specific
}
private Content.Source getContentSource(long offset, long length) {
// Get content source for byte range
return null; // Implementation specific
}Install with Tessl CLI
npx tessl i tessl/maven-org-eclipse-jetty--jetty-http