Low level API for processing file uploads.
This class can be used to process data streams conforming to MIME 'multipart' format as defined in RFC 1867. Arbitrarily large amounts of data in the stream can be processed under constant memory usage.
The format of the stream is defined in the following way:
multipart-body := preamble 1*encapsulation close-delimiter epilogue
encapsulation := delimiter body CRLF
delimiter := "--" boundary CRLF
close-delimiter := "--" boundary "--"
preamble := <ignore>
epilogue := <ignore>
body := header-part CRLF body-part
header-part := 1*header CRLF
header := header-name ":" header-value
header-name := <printable ascii characters except ":">
header-value := <any ascii characters except CR & LF>
body-data := <arbitrary data>
Note that body-data can contain another mulipart entity. There
is limited support for single pass processing of such nested
streams. The nested stream is required to have a
boundary token of the same length as the parent stream (see setBoundary(byte[])).
Here is an example of usage of this class.
try {
MultipartStream multipartStream = new MultipartStream(input, boundary);
boolean nextPart = multipartStream.skipPreamble();
OutputStream output;
while(nextPart) {
String header = multipartStream.readHeaders();
// process headers
// create some output stream
multipartStream.readBodyData(output);
nextPart = multipartStream.readBoundary();
}
} catch(MultipartStream.MalformedStreamException e) {
// the stream failed to follow required syntax
} catch(IOException e) {
// a read or write error occurred
}
| Modifier and Type | Class and Description |
|---|---|
| public static class | MultipartStream.
Thrown upon attempt of setting an invalid boundary token. |
| public class | MultipartStream.
An |
| public static class | MultipartStream.
Thrown to indicate that the input stream fails to follow the required syntax. |
| public static class | MultipartStream.
Internal class, which is used to invoke the
|
| Modifier and Type | Field and Description |
|---|---|
| private final byte[] | boundary
The byte sequence that partitions the stream. |
| protected static final byte[] | BOUNDARY_PREFIX
A byte sequence that precedes a boundary ( |
| private int | boundaryLength
The length of the boundary token plus the leading |
| private final int[] | boundaryTable
The table for Knuth-Morris-Pratt search algorithm. |
| private final byte[] | buffer
The buffer used for processing the request. |
| private final int | bufSize
The length of the buffer used for processing the request. |
| public static final byte | CR
The Carriage Return ASCII character value. |
| public static final byte | DASH
The dash (-) ASCII character value. |
| protected static final int | DEFAULT_BUFSIZE
The default length of the buffer used for processing a request. |
| protected static final byte[] | FIELD_SEPARATOR
A byte sequence that that follows a delimiter that will be
followed by an encapsulation ( |
| private int | head
The index of first valid character in the buffer. |
| public static final int | HEADER_PART_SIZE_MAX
The maximum length of |
| protected static final byte[] | HEADER_SEPARATOR
A byte sequence that marks the end of |
| private String | headerEncoding
The content encoding to use when reading headers. |
| private final InputStream | input
The input stream from which data is read. |
| private final int | keepRegion
The amount of data, in bytes, that must be kept in the buffer in order to detect delimiters reliably. |
| public static final byte | LF
The Line Feed ASCII character value. |
| private final MultipartStream. | notifier
The progress notifier, if any, or null. |
| protected static final byte[] | STREAM_TERMINATOR
A byte sequence that that follows a delimiter of the last
encapsulation in the stream ( |
| private int | tail
The index of last valid character in the buffer + 1. |
| Access | Constructor and Description |
|---|---|
| public | MultipartStream(final InputStream
The input, final byte[] InputStream to serve as a data source.The token used for dividing the stream into
boundary, final int encapsulations.The size of the buffer to be used, in bytes. bufSize, final MultipartStream.The notifier, which is used for calling the
progress listener, if any. pNotifier Constructs a |
| public | MultipartStream(final InputStream
The input, final byte[] InputStream to serve as a data source.The token used for dividing the stream into
boundary, final MultipartStream.encapsulations.An object for calling the progress listener, if any. pNotifier Constructs a |
| Modifier and Type | Method and Description |
|---|---|
| public static boolean | Returns: true if count first bytes in arrays
a and b are equal.The first array to compare. a, final byte[] The second array to compare. b, final int How many bytes should be compared. count)Compares |
| private void | |
| public int | Returns: The amount of data discarded. Reads |
| protected int | Returns: The position of the boundary found, counting from the beginning of thebuffer, or -1 if
not found.Searches for the |
| public String | Returns: The encoding used to read part headers.Retrieves the character encoding used when reading the headers of an individual part. |
| public MultipartStream. | |
| public int | Returns: the amount of data written.The output)Stream to write data into. May
be null, in which case this method is equivalent
to discardBodyData().Reads |
| public boolean | Returns: true if there are more encapsulations in
this stream; false otherwise.Skips a |
| public byte | Returns: The next byte from the input stream.Reads a byte from the |
| public String | Returns: Theheader-part of the current encapsulation.Reads the |
| public void | setBoundary(final byte[]
The boundary to be used for parsing of the nested
stream. boundary)Changes the boundary token used for partitioning the stream. |
| public void | setHeaderEncoding(final String
The encoding used to read part headers. encoding)Specifies the character encoding to be used when reading the headers of individual parts. |
| public boolean | Returns: true if an encapsulation was found in
the stream.Finds the beginning of the first |
| boundary | back to summary |
|---|---|
| private final byte[] boundary The byte sequence that partitions the stream. | |
| BOUNDARY_PREFIX | back to summary |
|---|---|
| protected static final byte[] BOUNDARY_PREFIX A byte sequence that precedes a boundary ( | |
| boundaryLength | back to summary |
|---|---|
| private int boundaryLength The length of the boundary token plus the leading | |
| boundaryTable | back to summary |
|---|---|
| private final int[] boundaryTable The table for Knuth-Morris-Pratt search algorithm. | |
| buffer | back to summary |
|---|---|
| private final byte[] buffer The buffer used for processing the request. | |
| bufSize | back to summary |
|---|---|
| private final int bufSize The length of the buffer used for processing the request. | |
| CR | back to summary |
|---|---|
| public static final byte CR The Carriage Return ASCII character value. | |
| DASH | back to summary |
|---|---|
| public static final byte DASH The dash (-) ASCII character value. | |
| DEFAULT_BUFSIZE | back to summary |
|---|---|
| protected static final int DEFAULT_BUFSIZE The default length of the buffer used for processing a request. | |
| FIELD_SEPARATOR | back to summary |
|---|---|
| protected static final byte[] FIELD_SEPARATOR A byte sequence that that follows a delimiter that will be
followed by an encapsulation ( | |
| head | back to summary |
|---|---|
| private int head The index of first valid character in the buffer.
| |
| HEADER_PART_SIZE_MAX | back to summary |
|---|---|
| public static final int HEADER_PART_SIZE_MAX The maximum length of | |
| HEADER_SEPARATOR | back to summary |
|---|---|
| protected static final byte[] HEADER_SEPARATOR A byte sequence that marks the end of | |
| headerEncoding | back to summary |
|---|---|
| private String headerEncoding The content encoding to use when reading headers. | |
| input | back to summary |
|---|---|
| private final InputStream input The input stream from which data is read. | |
| keepRegion | back to summary |
|---|---|
| private final int keepRegion The amount of data, in bytes, that must be kept in the buffer in order to detect delimiters reliably. | |
| LF | back to summary |
|---|---|
| public static final byte LF The Line Feed ASCII character value. | |
| notifier | back to summary |
|---|---|
| private final MultipartStream. The progress notifier, if any, or null. | |
| STREAM_TERMINATOR | back to summary |
|---|---|
| protected static final byte[] STREAM_TERMINATOR A byte sequence that that follows a delimiter of the last
encapsulation in the stream ( | |
| tail | back to summary |
|---|---|
| private int tail The index of last valid character in the buffer + 1.
| |
| MultipartStream | back to summary |
|---|---|
| public MultipartStream(final InputStream input, final byte[] boundary, final int bufSize, final MultipartStream. Constructs a Note that the buffer must be at least big enough to contain the boundary string, plus 4 characters for CR/LF and double dash, plus at least one byte of data. Too small a buffer size setting will degrade performance.
| |
| MultipartStream | back to summary |
|---|---|
| public MultipartStream(final InputStream input, final byte[] boundary, final MultipartStream. Constructs a
| |
| arrayequals | back to summary |
|---|---|
| public static boolean arrayequals(final byte[] a, final byte[] b, final int count) Compares
| |
| computeBoundaryTable | back to summary |
|---|---|
| private void computeBoundaryTable() Compute the table used for Knuth-Morris-Pratt search algorithm. | |
| discardBodyData | back to summary |
|---|---|
| public int discardBodyData() throws MalformedStreamException, IOException Reads Use this method to skip encapsulations you don't need or don't understand.
| |
| findSeparator | back to summary |
|---|---|
| protected int findSeparator() Searches for the
| |
| getHeaderEncoding | back to summary |
|---|---|
| public String getHeaderEncoding() Retrieves the character encoding used when reading the headers of an
individual part. When not specified, or
| |
| newInputStream | back to summary |
|---|---|
| public MultipartStream. Creates a new
| |
| readBodyData | back to summary |
|---|---|
| public int readBodyData(final OutputStream output) throws MalformedStreamException, IOException Reads Arbitrary large amounts of data can be processed by this
method using a constant size buffer. (see
| |
| readBoundary | back to summary |
|---|---|
| public boolean readBoundary() throws FileUploadIOException, MalformedStreamException Skips a
| |
| readByte | back to summary |
|---|---|
| public byte readByte() throws IOException Reads a byte from the
| |
| readHeaders | back to summary |
|---|---|
| public String readHeaders() throws FileUploadIOException, MalformedStreamException Reads the Headers are returned verbatim to the input stream, including the
trailing Todo allow limiting maximum header size to protect against abuse.
| |
| setBoundary | back to summary |
|---|---|
| public void setBoundary(final byte[] boundary) throws IllegalBoundaryException Changes the boundary token used for partitioning the stream. This method allows single pass processing of nested multipart streams. The boundary token of the nested stream is Restoring the parent stream boundary token after processing of a nested stream is left to the application.
| |
| setHeaderEncoding | back to summary |
|---|---|
| public void setHeaderEncoding(final String encoding) Specifies the character encoding to be used when reading the headers of
individual parts. When not specified, or
| |
| skipPreamble | back to summary |
|---|---|
| public boolean skipPreamble() throws IOException Finds the beginning of the first
| |
| Modifier and Type | Field and Description |
|---|---|
| private static final long | serialVersionUID
The UID to use when serializing this instance.
|
| Access | Constructor and Description |
|---|---|
| public | |
| public | IllegalBoundaryException(final String
The detail message. message)Constructs an |
| serialVersionUID | back to summary |
|---|---|
| private static final long serialVersionUID Hides java. The UID to use when serializing this instance. | |
| IllegalBoundaryException | back to summary |
|---|---|
| public IllegalBoundaryException() Constructs an | |
| IllegalBoundaryException | back to summary |
|---|---|
| public IllegalBoundaryException(final String message) Constructs an
| |
InputStream for reading an items contents.
| Modifier and Type | Field and Description |
|---|---|
| private static final int | BYTE_POSITIVE_OFFSET
Offset when converting negative bytes to integers. |
| private boolean | closed
Whether the stream is already closed. |
| private int | pad
The number of bytes, which must be hold, because they might be a part of the boundary. |
| private int | pos
The current offset in the buffer. |
| private long | total
The number of bytes, which have been read so far. |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public int | Returns: Number of bytes in the buffer.Overrides java. Returns the number of bytes, which are currently available, without blocking. |
| public void | close()
Overrides java. Implements org. Closes the input stream. |
| public void | close(final boolean
Whether to close the underlying stream
(hard close) pCloseUnderlying)Closes the input stream. |
| private void | |
| public long | Returns: Number of bytes, which have been read so far.Returns the number of bytes, which have been read by the stream. |
| public boolean | Returns: True, if the stream is closed, otherwise false.Implements org. Returns, whether the stream is closed. |
| private int | |
| public int | Returns: The next byte in the stream, as a non-negative integer, or -1 for EOF.Implements abstract java. Returns the next byte in the stream. |
| public int | Returns: Number of bytes, which have been actually read, or -1 for EOF.The destination buffer, where to write to. b, final int Offset of the first byte in the buffer. off, final int Maximum number of bytes to read. len)Overrides java. Reads bytes into the given buffer. |
| public long | Returns: The number of bytes, which have actually been skipped.Number of bytes to skip. bytes)Overrides java. Skips the given number of bytes. |
| BYTE_POSITIVE_OFFSET | back to summary |
|---|---|
| private static final int BYTE_POSITIVE_OFFSET Offset when converting negative bytes to integers. | |
| closed | back to summary |
|---|---|
| private boolean closed Whether the stream is already closed. | |
| pad | back to summary |
|---|---|
| private int pad The number of bytes, which must be hold, because they might be a part of the boundary. | |
| pos | back to summary |
|---|---|
| private int pos The current offset in the buffer. | |
| total | back to summary |
|---|---|
| private long total The number of bytes, which have been read so far. | |
| ItemInputStream | back to summary |
|---|---|
| pack-priv ItemInputStream() Creates a new instance. | |
| available | back to summary |
|---|---|
| public int available() throws IOException Overrides java. Returns the number of bytes, which are currently available, without blocking.
| |
| close | back to summary |
|---|---|
| public void close() throws IOException Overrides java. Implements org. Closes the input stream.
| |
| close | back to summary |
|---|---|
| public void close(final boolean pCloseUnderlying) throws IOException Closes the input stream.
| |
| findSeparator | back to summary |
|---|---|
| private void findSeparator() Called for finding the separator. | |
| getBytesRead | back to summary |
|---|---|
| public long getBytesRead() Returns the number of bytes, which have been read by the stream.
| |
| isClosed | back to summary |
|---|---|
| public boolean isClosed() Implements org. Returns, whether the stream is closed.
| |
| makeAvailable | back to summary |
|---|---|
| private int makeAvailable() throws IOException Attempts to read more data.
| |
| read | back to summary |
|---|---|
| public int read() throws IOException Implements abstract java. Returns the next byte in the stream.
| |
| read | back to summary |
|---|---|
| public int read(final byte[] b, final int off, final int len) throws IOException Overrides java. Reads bytes into the given buffer.
| |
| skip | back to summary |
|---|---|
| public long skip(final long bytes) throws IOException Overrides java. Skips the given number of bytes.
| |
| Modifier and Type | Field and Description |
|---|---|
| private static final long | serialVersionUID
The UID to use when serializing this instance.
|
| Access | Constructor and Description |
|---|---|
| public | |
| public | MalformedStreamException(final String
The detail message. message)Constructs an |
| serialVersionUID | back to summary |
|---|---|
| private static final long serialVersionUID Hides java. The UID to use when serializing this instance. | |
| MalformedStreamException | back to summary |
|---|---|
| public MalformedStreamException() Constructs a | |
| MalformedStreamException | back to summary |
|---|---|
| public MalformedStreamException(final String message) Constructs an
| |
ProgressListener.
| Modifier and Type | Field and Description |
|---|---|
| private long | bytesRead
Number of bytes, which have been read so far. |
| private final long | contentLength
Number of expected bytes, if known, or -1. |
| private int | items
Number of items, which have been read so far. |
| private final ProgressListener | listener
The listener to invoke. |
| Access | Constructor and Description |
|---|---|
| public | ProgressNotifier(final ProgressListener
The listener to invoke. pListener, final long The expected content length. pContentLength)Creates a new instance with the given listener and content length. |
| Modifier and Type | Method and Description |
|---|---|
| pack-priv void | noteBytesRead(final int
Number of bytes, which have been read. pBytes)Called to indicate that bytes have been read. |
| public void | |
| private void |
| bytesRead | back to summary |
|---|---|
| private long bytesRead Number of bytes, which have been read so far. | |
| contentLength | back to summary |
|---|---|
| private final long contentLength Number of expected bytes, if known, or -1. | |
| items | back to summary |
|---|---|
| private int items Number of items, which have been read so far. | |
| listener | back to summary |
|---|---|
| private final ProgressListener listener The listener to invoke. | |
| ProgressNotifier | back to summary |
|---|---|
| public ProgressNotifier(final ProgressListener pListener, final long pContentLength) Creates a new instance with the given listener and content length.
| |
| noteBytesRead | back to summary |
|---|---|
| pack-priv void noteBytesRead(final int pBytes) Called to indicate that bytes have been read.
| |
| noteItem | back to summary |
|---|---|
| public void noteItem() Called to indicate, that a new file item has been detected. | |
| notifyListener | back to summary |
|---|---|
| private void notifyListener() Called for notifying the listener. | |