Top Description Inners Fields Constructors Methods
org.apache.tomcat.util.http.fileupload

public Class MultipartStream

extends Object
Class Inheritance
Imports
java.io.ByteArrayOutputStream, .IOException, .InputStream, .OutputStream, .UnsupportedEncodingException, org.apache.tomcat.util.http.fileupload.impl.FileUploadIOException, org.apache.tomcat.util.http.fileupload.util.Closeable, .Streams

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
  }

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
MultipartStream.IllegalBoundaryException

Thrown upon attempt of setting an invalid boundary token.

public class
MultipartStream.ItemInputStream

An InputStream for reading an items contents.

public static class
MultipartStream.MalformedStreamException

Thrown to indicate that the input stream fails to follow the required syntax.

public static class
MultipartStream.ProgressNotifier

Internal class, which is used to invoke the ProgressListener.

Field Summary

Modifier and TypeField 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 (CRLF--).

private int
boundaryLength

The length of the boundary token plus the leading CRLF--.

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 (CRLF).

private int
head

The index of first valid character in the buffer.

public static final int
HEADER_PART_SIZE_MAX

The maximum length of header-part that will be processed (10 kilobytes = 10240 bytes.).

protected static final byte[]
HEADER_SEPARATOR

A byte sequence that marks the end of header-part (CRLFCRLF).

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.ProgressNotifier
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.

Constructor Summary

AccessConstructor and Description
public
MultipartStream(final InputStream
The InputStream to serve as a data source.
input
,
final byte[]
The token used for dividing the stream into encapsulations.
boundary
,
final int
The size of the buffer to be used, in bytes.
bufSize
,
final MultipartStream.ProgressNotifier
The notifier, which is used for calling the progress listener, if any.
pNotifier
)

Constructs a MultipartStream with a custom size buffer.

public
MultipartStream(final InputStream
The InputStream to serve as a data source.
input
,
final byte[]
The token used for dividing the stream into encapsulations.
boundary
,
final MultipartStream.ProgressNotifier
An object for calling the progress listener, if any.
pNotifier
)

Constructs a MultipartStream with a default size buffer.

Method Summary

Modifier and TypeMethod and Description
public static boolean

Returns:

true if count first bytes in arrays a and b are equal.
arrayequals
(final byte[]
The first array to compare.
a
,
final byte[]
The second array to compare.
b
,
final int
How many bytes should be compared.
count
)

Compares count first bytes in the arrays a and b.

private void
computeBoundaryTable()

Compute the table used for Knuth-Morris-Pratt search algorithm.

public int

Returns:

The amount of data discarded.
discardBodyData
()

Reads body-data from the current encapsulation and discards it.

protected int

Returns:

The position of the boundary found, counting from the beginning of the buffer, or -1 if not found.
findSeparator
()

Searches for the boundary in the buffer region delimited by head and tail.

public String

Returns:

The encoding used to read part headers.
getHeaderEncoding
()

Retrieves the character encoding used when reading the headers of an individual part.

public MultipartStream.ItemInputStream

Returns:

A new instance of ItemInputStream.
newInputStream
()

Creates a new ItemInputStream.

public int

Returns:

the amount of data written.
readBodyData
(final OutputStream
The Stream to write data into. May be null, in which case this method is equivalent to discardBodyData().
output
)

Reads body-data from the current encapsulation and writes its contents into the output Stream.

public boolean

Returns:

true if there are more encapsulations in this stream; false otherwise.
readBoundary
()

Skips a boundary token, and checks whether more encapsulations are contained in the stream.

public byte

Returns:

The next byte from the input stream.
readByte
()

Reads a byte from the buffer, and refills it as necessary.

public String

Returns:

The header-part of the current encapsulation.
readHeaders
()

Reads the header-part of the current encapsulation.

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.
skipPreamble
()

Finds the beginning of the first encapsulation.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

boundaryback to summary
private final byte[] boundary

The byte sequence that partitions the stream.

BOUNDARY_PREFIXback to summary
protected static final byte[] BOUNDARY_PREFIX

A byte sequence that precedes a boundary (CRLF--).

boundaryLengthback to summary
private int boundaryLength

The length of the boundary token plus the leading CRLF--.

boundaryTableback to summary
private final int[] boundaryTable

The table for Knuth-Morris-Pratt search algorithm.

bufferback to summary
private final byte[] buffer

The buffer used for processing the request.

bufSizeback to summary
private final int bufSize

The length of the buffer used for processing the request.

CRback to summary
public static final byte CR

The Carriage Return ASCII character value.

DASHback to summary
public static final byte DASH

The dash (-) ASCII character value.

DEFAULT_BUFSIZEback to summary
protected static final int DEFAULT_BUFSIZE

The default length of the buffer used for processing a request.

FIELD_SEPARATORback to summary
protected static final byte[] FIELD_SEPARATOR

A byte sequence that that follows a delimiter that will be followed by an encapsulation (CRLF).

HEADER_PART_SIZE_MAXback to summary
public static final int HEADER_PART_SIZE_MAX

The maximum length of header-part that will be processed (10 kilobytes = 10240 bytes.).

HEADER_SEPARATORback to summary
protected static final byte[] HEADER_SEPARATOR

A byte sequence that marks the end of header-part (CRLFCRLF).

headerEncodingback to summary
private String headerEncoding

The content encoding to use when reading headers.

inputback to summary
private final InputStream input

The input stream from which data is read.

keepRegionback 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.

LFback to summary
public static final byte LF

The Line Feed ASCII character value.

notifierback to summary
private final MultipartStream.ProgressNotifier notifier

The progress notifier, if any, or null.

STREAM_TERMINATORback to summary
protected static final byte[] STREAM_TERMINATOR

A byte sequence that that follows a delimiter of the last encapsulation in the stream (--).

tailback to summary
private int tail

The index of last valid character in the buffer + 1.
0 <= tail <= bufSize

Constructor Detail

MultipartStreamback to summary
public MultipartStream(final InputStream input, final byte[] boundary, final int bufSize, final MultipartStream.ProgressNotifier pNotifier)

Constructs a MultipartStream with a custom size buffer.

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.

Parameters
input:InputStream

The InputStream to serve as a data source.

boundary:byte[]

The token used for dividing the stream into encapsulations.

bufSize:int

The size of the buffer to be used, in bytes.

pNotifier:MultipartStream.ProgressNotifier

The notifier, which is used for calling the progress listener, if any.

Exceptions
IllegalArgumentException:
If the buffer size is too small
Since
1.3.1
MultipartStreamback to summary
public MultipartStream(final InputStream input, final byte[] boundary, final MultipartStream.ProgressNotifier pNotifier)

Constructs a MultipartStream with a default size buffer.

Parameters
input:InputStream

The InputStream to serve as a data source.

boundary:byte[]

The token used for dividing the stream into encapsulations.

pNotifier:MultipartStream.ProgressNotifier

An object for calling the progress listener, if any.

See Also
MultipartStream(InputStream, byte[], int, ProgressNotifier)

Method Detail

arrayequalsback to summary
public static boolean arrayequals(final byte[] a, final byte[] b, final int count)

Compares count first bytes in the arrays a and b.

Parameters
a:byte[]

The first array to compare.

b:byte[]

The second array to compare.

count:int

How many bytes should be compared.

Returns:boolean

true if count first bytes in arrays a and b are equal.

computeBoundaryTableback to summary
private void computeBoundaryTable()

Compute the table used for Knuth-Morris-Pratt search algorithm.

discardBodyDataback to summary
public int discardBodyData() throws MalformedStreamException, IOException

Reads body-data from the current encapsulation and discards it.

Use this method to skip encapsulations you don't need or don't understand.

Returns:int

The amount of data discarded.

Exceptions
MalformedStreamException:
if the stream ends unexpectedly.
IOException:
if an i/o error occurs.
findSeparatorback to summary
protected int findSeparator()

Searches for the boundary in the buffer region delimited by head and tail.

Returns:int

The position of the boundary found, counting from the beginning of the buffer, or -1 if not found.

getHeaderEncodingback to summary
public String getHeaderEncoding()

Retrieves the character encoding used when reading the headers of an individual part. When not specified, or null, the platform default encoding is used.

Returns:String

The encoding used to read part headers.

newInputStreamback to summary
public MultipartStream.ItemInputStream newInputStream()

Creates a new ItemInputStream.

Returns:MultipartStream.ItemInputStream

A new instance of ItemInputStream.

readBodyDataback to summary
public int readBodyData(final OutputStream output) throws MalformedStreamException, IOException

Reads body-data from the current encapsulation and writes its contents into the output Stream.

Arbitrary large amounts of data can be processed by this method using a constant size buffer. (see constructor).

Parameters
output:OutputStream

The Stream to write data into. May be null, in which case this method is equivalent to discardBodyData().

Returns:int

the amount of data written.

Exceptions
MalformedStreamException:
if the stream ends unexpectedly.
IOException:
if an i/o error occurs.
readBoundaryback to summary
public boolean readBoundary() throws FileUploadIOException, MalformedStreamException

Skips a boundary token, and checks whether more encapsulations are contained in the stream.

Returns:boolean

true if there are more encapsulations in this stream; false otherwise.

Exceptions
FileUploadIOException:
if the bytes read from the stream exceeded the size limits
MalformedStreamException:
if the stream ends unexpectedly or fails to follow required syntax.
readByteback to summary
public byte readByte() throws IOException

Reads a byte from the buffer, and refills it as necessary.

Returns:byte

The next byte from the input stream.

Exceptions
IOException:
if there is no more data available.
readHeadersback to summary
public String readHeaders() throws FileUploadIOException, MalformedStreamException

Reads the header-part of the current encapsulation.

Headers are returned verbatim to the input stream, including the trailing CRLF marker. Parsing is left to the application.

Todo

allow limiting maximum header size to protect against abuse.

Returns:String

The header-part of the current encapsulation.

Exceptions
FileUploadIOException:
if the bytes read from the stream exceeded the size limits.
MalformedStreamException:
if the stream ends unexpectedly.
setBoundaryback 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 required to be of the same length as the boundary token in parent stream.

Restoring the parent stream boundary token after processing of a nested stream is left to the application.

Parameters
boundary:byte[]

The boundary to be used for parsing of the nested stream.

Exceptions
IllegalBoundaryException:
if the boundary has a different length than the one being currently parsed.
setHeaderEncodingback 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 null, the platform default encoding is used.

Parameters
encoding:String

The encoding used to read part headers.

skipPreambleback to summary
public boolean skipPreamble() throws IOException

Finds the beginning of the first encapsulation.

Returns:boolean

true if an encapsulation was found in the stream.

Exceptions
IOException:
if an i/o error occurs.
org.apache.tomcat.util.http.fileupload back to summary

public Class MultipartStream.IllegalBoundaryException

extends IOException
Class Inheritance

Thrown upon attempt of setting an invalid boundary token.

Field Summary

Modifier and TypeField and Description
private static final long
serialVersionUID

Hides java.io.IOException.serialVersionUID.

The UID to use when serializing this instance.

Constructor Summary

AccessConstructor and Description
public
IllegalBoundaryException()

Constructs an IllegalBoundaryException with no detail message.

public
IllegalBoundaryException(final String
The detail message.
message
)

Constructs an IllegalBoundaryException with the specified detail message.

Field Detail

serialVersionUIDback to summary
private static final long serialVersionUID

Hides java.io.IOException.serialVersionUID.

The UID to use when serializing this instance.

Constructor Detail

IllegalBoundaryExceptionback to summary
public IllegalBoundaryException()

Constructs an IllegalBoundaryException with no detail message.

IllegalBoundaryExceptionback to summary
public IllegalBoundaryException(final String message)

Constructs an IllegalBoundaryException with the specified detail message.

Parameters
message:String

The detail message.

org.apache.tomcat.util.http.fileupload back to summary

public Class MultipartStream.ItemInputStream

extends InputStream
implements Closeable
Class Inheritance
All Implemented Interfaces
org.apache.tomcat.util.http.fileupload.util.Closeable

An InputStream for reading an items contents.

Field Summary

Modifier and TypeField 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.

Constructor Summary

AccessConstructor and Description
pack-priv
ItemInputStream()

Creates a new instance.

Method Summary

Modifier and TypeMethod and Description
public int

Returns:

Number of bytes in the buffer.
available
()

Overrides java.io.InputStream.available.

Returns the number of bytes, which are currently available, without blocking.

public void
public void
close(final boolean
Whether to close the underlying stream (hard close)
pCloseUnderlying
)

Closes the input stream.

private void
findSeparator()

Called for finding the separator.

public long

Returns:

Number of bytes, which have been read so far.
getBytesRead
()

Returns the number of bytes, which have been read by the stream.

public boolean

Returns:

True, if the stream is closed, otherwise false.
isClosed
()

Implements org.apache.tomcat.util.http.fileupload.util.Closeable.isClosed.

Returns, whether the stream is closed.

private int

Returns:

Number of available bytes
makeAvailable
()

Attempts to read more data.

public int

Returns:

The next byte in the stream, as a non-negative integer, or -1 for EOF.
read
()

Implements abstract java.io.InputStream.read.

Returns the next byte in the stream.

public int

Returns:

Number of bytes, which have been actually read, or -1 for EOF.
read
(final byte[]
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.io.InputStream.read.

Reads bytes into the given buffer.

public long

Returns:

The number of bytes, which have actually been skipped.
skip
(final long
Number of bytes to skip.
bytes
)

Overrides java.io.InputStream.skip.

Skips the given number of bytes.

Inherited from java.io.InputStream:
markmarkSupportednullInputStreamreadreadAllBytesreadNBytesreadNBytesresetskipNBytestransferTo

Field Detail

BYTE_POSITIVE_OFFSETback to summary
private static final int BYTE_POSITIVE_OFFSET

Offset when converting negative bytes to integers.

closedback to summary
private boolean closed

Whether the stream is already closed.

padback to summary
private int pad

The number of bytes, which must be hold, because they might be a part of the boundary.

posback to summary
private int pos

The current offset in the buffer.

totalback to summary
private long total

The number of bytes, which have been read so far.

Constructor Detail

ItemInputStreamback to summary
pack-priv ItemInputStream()

Creates a new instance.

Method Detail

availableback to summary
public int available() throws IOException

Overrides java.io.InputStream.available.

Returns the number of bytes, which are currently available, without blocking.

Returns:int

Number of bytes in the buffer.

Annotations
@Override
Exceptions
IOException:
An I/O error occurs.
closeback to summary
public void close() throws IOException

Overrides java.io.InputStream.close.

Implements org.apache.tomcat.util.http.fileupload.util.Closeable.close, java.io.Closeable.close.

Closes the input stream.

Annotations
@Override
Exceptions
IOException:
An I/O error occurred.
closeback to summary
public void close(final boolean pCloseUnderlying) throws IOException

Closes the input stream.

Parameters
pCloseUnderlying:boolean

Whether to close the underlying stream (hard close)

Exceptions
IOException:
An I/O error occurred.
findSeparatorback to summary
private void findSeparator()

Called for finding the separator.

getBytesReadback to summary
public long getBytesRead()

Returns the number of bytes, which have been read by the stream.

Returns:long

Number of bytes, which have been read so far.

isClosedback to summary
public boolean isClosed()

Implements org.apache.tomcat.util.http.fileupload.util.Closeable.isClosed.

Returns, whether the stream is closed.

Returns:boolean

True, if the stream is closed, otherwise false.

Annotations
@Override
makeAvailableback to summary
private int makeAvailable() throws IOException

Attempts to read more data.

Returns:int

Number of available bytes

Exceptions
IOException:
An I/O error occurred.
readback to summary
public int read() throws IOException

Implements abstract java.io.InputStream.read.

Returns the next byte in the stream.

Returns:int

The next byte in the stream, as a non-negative integer, or -1 for EOF.

Annotations
@Override
Exceptions
IOException:
An I/O error occurred.
readback to summary
public int read(final byte[] b, final int off, final int len) throws IOException

Overrides java.io.InputStream.read.

Reads bytes into the given buffer.

Parameters
b:byte[]

The destination buffer, where to write to.

off:int

Offset of the first byte in the buffer.

len:int

Maximum number of bytes to read.

Returns:int

Number of bytes, which have been actually read, or -1 for EOF.

Annotations
@Override
Exceptions
IOException:
An I/O error occurred.
skipback to summary
public long skip(final long bytes) throws IOException

Overrides java.io.InputStream.skip.

Skips the given number of bytes.

Parameters
bytes:long

Number of bytes to skip.

Returns:long

The number of bytes, which have actually been skipped.

Annotations
@Override
Exceptions
IOException:
An I/O error occurred.
org.apache.tomcat.util.http.fileupload back to summary

public Class MultipartStream.MalformedStreamException

extends IOException
Class Inheritance

Thrown to indicate that the input stream fails to follow the required syntax.

Field Summary

Modifier and TypeField and Description
private static final long
serialVersionUID

Hides java.io.IOException.serialVersionUID.

The UID to use when serializing this instance.

Constructor Summary

AccessConstructor and Description
public
MalformedStreamException()

Constructs a MalformedStreamException with no detail message.

public
MalformedStreamException(final String
The detail message.
message
)

Constructs an MalformedStreamException with the specified detail message.

Field Detail

serialVersionUIDback to summary
private static final long serialVersionUID

Hides java.io.IOException.serialVersionUID.

The UID to use when serializing this instance.

Constructor Detail

MalformedStreamExceptionback to summary
public MalformedStreamException()

Constructs a MalformedStreamException with no detail message.

MalformedStreamExceptionback to summary
public MalformedStreamException(final String message)

Constructs an MalformedStreamException with the specified detail message.

Parameters
message:String

The detail message.

org.apache.tomcat.util.http.fileupload back to summary

public Class MultipartStream.ProgressNotifier

extends Object
Class Inheritance
  • java.lang.Object
  • org.apache.tomcat.util.http.fileupload.MultipartStream.ProgressNotifier

Internal class, which is used to invoke the ProgressListener.

Field Summary

Modifier and TypeField 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.

Constructor Summary

AccessConstructor 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.

Method Summary

Modifier and TypeMethod 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
noteItem()

Called to indicate, that a new file item has been detected.

private void
notifyListener()

Called for notifying the listener.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

bytesReadback to summary
private long bytesRead

Number of bytes, which have been read so far.

contentLengthback to summary
private final long contentLength

Number of expected bytes, if known, or -1.

itemsback to summary
private int items

Number of items, which have been read so far.

listenerback to summary
private final ProgressListener listener

The listener to invoke.

Constructor Detail

ProgressNotifierback to summary
public ProgressNotifier(final ProgressListener pListener, final long pContentLength)

Creates a new instance with the given listener and content length.

Parameters
pListener:ProgressListener

The listener to invoke.

pContentLength:long

The expected content length.

Method Detail

noteBytesReadback to summary
pack-priv void noteBytesRead(final int pBytes)

Called to indicate that bytes have been read.

Parameters
pBytes:int

Number of bytes, which have been read.

noteItemback to summary
public void noteItem()

Called to indicate, that a new file item has been detected.

notifyListenerback to summary
private void notifyListener()

Called for notifying the listener.