|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object ccs.mime.HeaderedEntity
public class HeaderedEntity
This class represents a common construct in MIME and related applications: a "header" section, consisting of lines of the form "Name: value" in US-ASCII, followed by a blank line, followed by a binary content. MT-UNSAFE.
Headers come in one of two modes, collapsing (the default) and non-collapsing. In collapsing mode, where several headers have the same name, their values are concatenated, separated by a comma and a space. In non-collapsing, they stay separate. Collapsing mode is best for HTTP, but non-collapsing is required for SMTP (e.g. received: headers are best kept separate).
Headers are stored in the order they are received.
Nested Class Summary | |
---|---|
static class |
HeaderedEntity.UnmarshalModes
Body unmarshalling modes: none (no-op, existing state unchanged); headers only; full (headers + body); repeat (body is in a RepeatingSwappingBuffer.) |
Constructor Summary | |
---|---|
HeaderedEntity()
Construct a HeaderedEntity with collapsing headers. |
|
HeaderedEntity(boolean isCollapse)
Construct a HeaderedEntity. |
Method Summary | |
---|---|
void |
addHeader(int idx,
java.lang.String name,
java.lang.String value)
In non-collapsing mode only, add a new header at the specified index. |
void |
addHeader(java.lang.String name,
java.lang.String value)
Add a new header. |
int |
bodySize()
Return the length of the body, or -1 if the entity does not have a body. |
void |
cleanupRepeatableBody()
When the body was read using readRepeatableBodyFrom , you must
call this when you're done. |
void |
deleteHeader(int idx)
Delete the specified header. |
void |
deleteHeader(java.lang.String name)
Delete the specified header, by name, ignoring case. |
SwappingBuffer |
getBody()
Gets the current body. |
byte[] |
getBodyBytes()
Returns the bytes of the content (body) of the entity. |
boolean |
getBodyHasTrailer()
Whether the current body has a superfluous CRLF pair on the end. |
java.lang.String |
getHeader(java.lang.String name)
The value of the (first instance of the) named header. |
int |
getHeaderIndex(java.lang.String name)
Returns the index of the (first occurrence of) the header with the specified name, ignoring case. |
int |
getHeaderInt(java.lang.String name,
int defVal)
Utility method which returns the value of the (first instance of the) named header as an int, if it exists. |
java.lang.String[] |
getHeaderNames()
The set of available header names. |
java.lang.String |
getName(int idx)
The name of the header with this index. |
java.lang.String |
getValue(int idx)
The value of the header with this index. |
int |
getWireLength()
The "wire length" of this entity is its length when transmitted onto a stream in the standard format: headers, one blank line, then the body. |
protected boolean |
isBoundary(byte[] boundary,
byte[] wad,
int wlen)
|
void |
marshalTo(java.io.DataOutputStream dest)
Marshal the HeaderedEntity for storage. |
int |
nHeaders()
The total number of available headers. |
protected void |
out(java.lang.String s)
|
void |
readBodyFrom(java.io.InputStream is)
Read the entity body from a stream with no boundary. |
void |
readBodyFrom(LineInputStream lis,
byte[] boundary)
Read the entity body from the stream. |
void |
readFrom(LineInputStream lis,
byte[] boundary)
Read the complete entity from a stream. |
void |
readHeadersFrom(LineInputStream lis,
byte[] boundary)
Read only the headers from the stream. |
void |
readRepeatableBodyFrom(java.io.InputStream is)
As readBodyFrom , except that the body is held in a RepeatingSwappingBuffer . |
void |
readRepeatableBodyFrom(LineInputStream lis,
byte[] boundary)
Read the repeatable entity body from the stream. |
void |
readRepeatableFrom(LineInputStream lis,
byte[] boundary)
Read the complete entity from a stream, using a repeatable body. |
void |
setBody(SwappingBuffer body)
Set the body to be the content of the supplied SwappingBuffer. |
void |
setBodyHasTrailer(boolean hasTrailer)
Set whether the current body has a superfluous CRLF pair on the end. |
void |
setHeader(int idx,
java.lang.String newValue)
Set the value of a specified header. |
void |
setHeader(java.lang.String name,
java.lang.String value)
Set the value of a specified header. |
void |
swallowPreamble(LineInputStream lis,
byte[] boundary)
RFC2046 states that an area of non-compliant guff - the preamble - can precede a multipart. |
void |
unmarshalFrom(java.io.DataInputStream src,
HeaderedEntity.UnmarshalModes mode)
Unmarshal the HeaderedEntity from storage. |
boolean |
wasLastBoundary()
If the last read operation ( readFrom , readHeadersFrom ,
or readBodyFrom had non-null boundary (i.e. was reading from
an RFC2046 multipart MIME stream), this returns true if the encountered boundary
which ended the read was of the variant type (with two hyphens as a suffix) which
denotes the end of the multipart. |
void |
writeBodyTo(java.io.OutputStream os,
boolean isClose)
Write the body of the entity to a stream. |
void |
writeHeadersTo(java.io.OutputStream os)
Write the headers of the entity to a stream. |
protected void |
writeln(java.lang.String s,
java.io.OutputStream os)
Utility method to write a string to the stream with at least reasonable efficiency. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
---|
public HeaderedEntity()
public HeaderedEntity(boolean isCollapse)
isCollapse
- Whether to collapse headers which have the same name.Method Detail |
---|
public void marshalTo(java.io.DataOutputStream dest) throws java.io.IOException
java.io.IOException
public void unmarshalFrom(java.io.DataInputStream src, HeaderedEntity.UnmarshalModes mode) throws java.io.IOException
src
- Where to unmarshal from.mode
- The unmarshalling mode. Available modes are: none (no-op,
existing state unchanged); headers only; full (headers + body); repeat
(body is in a RepeatingSwappingBuffer.)
java.io.IOException
public void swallowPreamble(LineInputStream lis, byte[] boundary) throws java.io.IOException
lis
- The stream containing the edend.boundary
- the MIME part boundary. See readFrom
. If you call
this method with a null boundary, it will inefficiently eat the entire stream.
java.io.IOException
public void readHeadersFrom(LineInputStream lis, byte[] boundary) throws java.io.IOException
lis
- where to read from.boundary
- If lis is a MIME-style multipart stream, the part boundary.
See readFrom
.
java.io.IOException
public void readBodyFrom(LineInputStream lis, byte[] boundary) throws java.io.IOException
lis
- The stream to read from.boundary
- If lis is a MIME-style multipart stream, the part boundary.
See readFrom
.
java.io.IOException
public void readRepeatableBodyFrom(LineInputStream lis, byte[] boundary) throws java.io.IOException
lis
- The stream to read from.boundary
- If lis is a MIME-style multipart stream, the part boundary.
See readFrom
.
java.io.IOException
public void readBodyFrom(java.io.InputStream is) throws java.io.IOException
java.io.IOException
public void readRepeatableBodyFrom(java.io.InputStream is) throws java.io.IOException
readBodyFrom
, except that the body is held in a RepeatingSwappingBuffer
.
This means that the body can be written several times on the trot; however,
you must subsequently call cleanupBody
.
java.io.IOException
public void setBody(SwappingBuffer body)
public SwappingBuffer getBody()
writeTo
methods of this
class take this into account.
public void cleanupRepeatableBody() throws java.io.IOException
readRepeatableBodyFrom
, you must
call this when you're done.
java.io.IOException
public boolean getBodyHasTrailer()
public void setBodyHasTrailer(boolean hasTrailer)
public void readFrom(LineInputStream lis, byte[] boundary) throws java.io.IOException
lis
- the stream to read from. If the entity does not extend to the
end of the stream, set the dam on lis
(For example, this
technique is required if reading the entity from an HTTP persistent connection;
otherwise the read will block ad inifinitum.boundary
- If lis is a MIME-style multipart stream, the part boundary.
If encountered, the method will eat it and return. It will also cope with the
variant which is used for the final boundary marker. Null if not a multipart
MIME stream. Note that for some bizarre reason, RFC2046 stipulates that the
boundary bytestring actually used is the boundary specified in the headers
which precede the multipart, but with two US-ASCII hyphens as a prefix.
It is assumed that this prefix has been added by the caller.
java.io.IOException
public void readRepeatableFrom(LineInputStream lis, byte[] boundary) throws java.io.IOException
lis
- the stream to read from. If the entity does not extend to the
end of the stream, set the dam on lis
(For example, this
technique is required if reading the entity from an HTTP persistent connection;
otherwise the read will block ad inifinitum.boundary
- If lis is a MIME-style multipart stream, the part boundary.
If encountered, the method will eat it and return. It will also cope with the
variant which is used for the final boundary marker. Null if not a multipart
MIME stream. Note that for some bizarre reason, RFC2046 stipulates that the
boundary bytestring actually used is the boundary specified in the headers
which precede the multipart, but with two US-ASCII hyphens as a prefix.
It is assumed that this prefix has been added by the caller.
java.io.IOException
public int getHeaderIndex(java.lang.String name)
name
- The name to search for, ignoring case.
public java.lang.String getHeader(java.lang.String name)
name
- The name to search for, ignoring case.
public void setHeader(int idx, java.lang.String newValue)
idx
- The index of the header to change.newValue
- The value to set it to.public void setHeader(java.lang.String name, java.lang.String value)
name
- The name of the header. The first instance, if any, will
have its value set. If there is no such header, one such will be added.value
- the new value of the header.public int getHeaderInt(java.lang.String name, int defVal)
public void addHeader(java.lang.String name, java.lang.String value)
name
- The name for the header. Behaviour if the header exists already
depends on whether collapsing or non-collapsing behaviour has been specified.value
- The value for the header.public void addHeader(int idx, java.lang.String name, java.lang.String value)
java.util.ArrayList.add
.
public void deleteHeader(int idx)
public void deleteHeader(java.lang.String name)
public int nHeaders()
public java.lang.String getName(int idx)
public java.lang.String getValue(int idx)
public java.lang.String[] getHeaderNames()
public int getWireLength()
public void writeHeadersTo(java.io.OutputStream os) throws java.io.IOException
os
- the OutputStream to write to.
java.io.IOException
protected void writeln(java.lang.String s, java.io.OutputStream os) throws java.io.IOException
java.io.IOException
public void writeBodyTo(java.io.OutputStream os, boolean isClose) throws java.io.IOException
os
- The stream to write toisClose
- Whether os
should be closed after the write.
java.io.IOException
public byte[] getBodyBytes()
SwappingBuffer
, then this will
return null, and writeBodyTo
must be used instead. If this
happens, it is not recommended to "work around" this feature by writing
to a ByteArrayOutputStream - the body may be very large.
public int bodySize()
public boolean wasLastBoundary()
readFrom
, readHeadersFrom
,
or readBodyFrom
had non-null boundary (i.e. was reading from
an RFC2046 multipart MIME stream), this returns true if the encountered boundary
which ended the read was of the variant type (with two hyphens as a suffix) which
denotes the end of the multipart.
protected boolean isBoundary(byte[] boundary, byte[] wad, int wlen)
protected void out(java.lang.String s)
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |