Cross-Platform C++

ot::web
class MultipartFormEmulator

#include "ot/web/MultipartFormEmulator.h"

ot::web::FormEmulator ot::ManagedObject Class to construct a form entity encoded according to the multipart/form-data scheme. The multipart/form-data encoding separates the data for individual form fields by a boundary, which is a randomly-generated sequence of bytes. The boundary string is of sufficient length and randomness that the chance of it appearing accidentally within the field data is vanishingly small.

The use of a random separator makes the multipart/form-data encoding suitable for the transmission of binary data such as data files. Indeed, many Web sites provide a file upload facility via HTML forms using the multipart/form-data encoding.

Please see the FormEmulator class for a code example.

Streaming and buffering

The OpenTop HTTP framework provides the capability to stream entities directly to the underlying socket rather than having to buffer the whole entity in memory prior to transmission. This class enables application developers to take full advantage of this feature, by providing an entity InputStream which can be copied to the HTTP OutputStream while only using a small memory buffer on the client.

When instances of this class return an InputStream entity containing filename fields, what is actually returned is a SequenceInputStream combining byte streams that contain the field header and boundary sequences with InputStreams for the files' data. When the returned SequenceInputStream is read, the result is the headers and file data combined into a contiguous stream of bytes.

Entity Length

In most cases, the length (in bytes) of the entity produced by instances of this class can be calculated and used to construct an Entity-Length MIME header. However, it is possible to construct a form with a filename field comprising an InputStream of unknown length. In this case, the form's entity length cannot be determined and the entity will need to be transported using either the HTTP/1.1 chunked encoding or a non-persistent HTTP connection (where the end of the entity is signalled by closing the stream). See the HttpRequest class for further information about sending entities.

See also:
FormEmulator , HttpClient , HttpResponse
Since:
OpenTop 1.5



Constructor/Destructor Summary
MultipartFormEmulator()
         Default constructor.
MultipartFormEmulator(const String& encoding)
         Constructs a new MultipartFormEmulator with the name of the encoding to be used for field values.

Method Summary
 virtual void addField(const String& name, const String& value)
         Inserts a name/value pair field to the end of the sequence of fields contained by this form.
 virtual void addFilenameField(const String& fieldName, const File& file, const String& filename, const String& encoding, const String& mimeType)
         Inserts a filename field to the end of the sequence of fields contained by this form.
 virtual void addFilenameField(const String& fieldName, InputStream* pStream, const String& filename, const String& encoding, Int64Type fileLength, const String& mimeType)
         Inserts a filename field to the end of the sequence of fields contained by this form.
 virtual void clear()
         Clears all the fields, returning the form to its newly constructed state.
static ByteString GenerateRandomSeparator(const ByteString& prefix, size_t length)
         Static function to generates a new random byte string intended to mark the boundary between individual parts of a multipart form.
 virtual String getContentTypeHeader() const
         Returns a Content-Type header value describing the MIME type of the form entity.
 virtual RefPtr< InputStream > getEntity() const
         Returns an InputStream which provides a contiguous stream of bytes constituting the form entity.
 virtual Int64Type getEntityLength() const
         Returns the length of the form entity.
 const ByteString& getSeparator() const
         Returns the ByteString used to separate parts of the multipart form data.
 void regenerateSeparator()
         Sets the ByteString used to separate individual parts of the multipart form data to a new randomly generated string.
 void setSeparator(const ByteString& sep)
         Sets the ByteString used to separate individual parts of the multipart form data.
 void writeEntity(OutputStream* pOutputStream) const
         Writes the form entity to the supplied OutputStream.

Methods inherited from class ot::ManagedObject
addRef(), getRefCount(), onFinalRelease(), operator=(const ManagedObject&), release()

Constructor/Destructor Detail

MultipartFormEmulator

 MultipartFormEmulator()
Default constructor. MultipartFormEmulators constructed using the default constructor will make use of the ISO-8859-1 (Latin1) character encoding when formatting MIME headers and field values.

Field and header values containing Unicode characters that cannot be mappped into the form's encoding will have those characters silently replaced with an alternative character. If your form may contain field values whose characters cannot be represented by ISO-8859-1 then you should use the alternative constructor which allows an encoding name to be specified.


MultipartFormEmulator

 MultipartFormEmulator(const String& encoding)
Constructs a new MultipartFormEmulator with the name of the encoding to be used for field values. Regardless of the encoding chosen for field values, MIME headers are formatted using the ISO-8859-1 (Latin1) encoding.

The encoding parameter specifies the character encoding used when formatting field values. The encoding parameter is used internally to request a CodeConverter from the system's CodeConverterFactory. If the specified encoding is not recognized by the factory an UnsupportedEncodingException is thrown.

Exceptions:
UnsupportedEncodingException - if encoding is not a supported character encoding.

Method Detail

addField

virtual void addField(const String& name,
                      const String& value)
Inserts a name/value pair field to the end of the sequence of fields contained by this form. The fieldName and value parameters are converted from Unicode strings into byte strings using the configured transport encoding.

Parameters:
fieldName - the name of the field.
value - a Unicode string containing the value of the field.

addFilenameField

virtual void addFilenameField(const String& fieldName,
                              const File& file,
                              const String& filename,
                              const String& encoding,
                              const String& mimeType)
Inserts a filename field to the end of the sequence of fields contained by this form. Filename fields differ from other fields in that they cause the contents of the specified file to be transmitted as part of the form entity. The file is not opened until an entity is requested via getEntity() or writeEntity().

Parameters:
fieldName - the name of the field.
file - the abstract filename of the local file to transmit as part of the form entity.
filename - an optional name for the file. If this is not specified, the filename will be taken from the file parameter.
encoding - the name of the byte encoding of the file (if any). The encoding name is not used locally to decipher the file but is passed as a hint to the receiving host.
mimeType - the MIME type of the file. If not specified, a MIME type of application/octet-stream is assumed.
Exceptions:
UnsupportedOperationException - if the implementation does not support file transfer operations. The MultipartFormEmulator class is one known implementation of this interface which does offer file transfer support.

addFilenameField

virtual void addFilenameField(const String& fieldName,
                              InputStream* pStream,
                              const String& filename,
                              const String& encoding,
                              Int64Type fileLength,
                              const String& mimeType)
Inserts a filename field to the end of the sequence of fields contained by this form. Filename fields differ from other fields in that they cause the contents of the specified file to be transmitted as part of the form entity. In this function the file's contents are represented by an InputStream. The provided stream will not be read until the form entity is transmitted, but it should be noted that this can only be performed once; forms containing InputStream filename fields can only be transmitted once, whereas those containing filename fields constructed from a File object can be transmitted multiple times because a fresh InputStream is opened on each occasion.

Parameters:
fieldName - the name of the field.
pStream - the contents of the file represented as an InputStream.
filename - the name for the file. If this is not specified an IllegalArgumentException is thrown.
encoding - the name of the byte encoding of the file (if any). The encoding name is not used locally to decipher the file but is passed as a hint to the receiving host.
mimeType - the MIME type of the file. If not specified, a MIME type of application/octet-stream is assumed.
Exceptions:
UnsupportedOperationException - if the implementation does not support file transfer operations. The MultipartFormEmulator class is one known implementation of this interface which does offer file transfer support.
IllegalArgumentException - if filename is an empty String.

clear

virtual void clear()
Clears all the fields, returning the form to its newly constructed state.


GenerateRandomSeparator

static ByteString GenerateRandomSeparator(const ByteString& prefix,
                                          size_t length)
Static function to generates a new random byte string intended to mark the boundary between individual parts of a multipart form.

Parameters:
prefix - a constant prefix value to place at the start of the generated string.
length - the desired length of the random part of the generated string.
Exceptions:
IllegalArgumentException - if length is zero.

getContentTypeHeader

virtual String getContentTypeHeader() const
Returns a Content-Type header value describing the MIME type of the form entity. The returned header value will depend on the encoding provided by the implementation class.

It is advisable to use this method when constructing a HTTP request rather than assuming a constant value for the Content-Type header. One important reason for this is that the Content-Type header contains a variable separator parameter when describing the multipart/form-data encoding.

Returns:
a String value such as application/x-www-form-urlencoded or multipart/form-data; separator=xxxx.

getEntity

virtual RefPtr< InputStreamgetEntity() const
Returns an InputStream which provides a contiguous stream of bytes constituting the form entity. This entity is formatted for transmission as the POST data of a HTTP request.

This function can be called repeatedly, with each invocation returning a RefPtr to a new InputStream. In most cases the returned InputStream can be read without affecting the internal state of this form because it is generated from the form's field without altering their state. The notable exception to this case is when a filename field has been added using the overloaded method which takes an InputStream parameter. In this case the filename field's InputStream is returned as part of a SequenceInputStream, and this stream can be read only once. In this case, subsequent calls to this function will result in an IOException.

Returns:
a RefPtr to an InputStream representing the form entity.
Exceptions:
IOException - if an error occurs while creating the InputStream or if this function is called more than once on a form containing an InputStream filename field.

getEntityLength

virtual Int64Type getEntityLength() const
Returns the length of the form entity. In cases where the length of the entity cannot be determined (i.e. when a filename field of unknown length has been inserted), a value of -1 is returned.

Returns:
the length of the form entity or -1 if the length cannot be determined.

getSeparator

const ByteStringgetSeparator() const
Returns the ByteString used to separate parts of the multipart form data. A random separator string is generated when instances of this class are constructed. The generated string is statistically extremely unlikely to occur within any data fields added to the form.

See also:
setSeparator() , regenerateSeparator()

regenerateSeparator

void regenerateSeparator()
Sets the ByteString used to separate individual parts of the multipart form data to a new randomly generated string.

See also:
getSeparator() , setSeparator()

setSeparator

void setSeparator(const ByteString& sep)
Sets the ByteString used to separate individual parts of the multipart form data.

See also:
getSeparator()

writeEntity

void writeEntity(OutputStream* pOutputStream) const
Writes the form entity to the supplied OutputStream. This function can normally be called repeatedly, with each invocation writing the form entity to the supplied stream. The notable exception to this case is when a filename field has been added using the InputStream overloaded method. In this case the filename field's InputStream is copied to the OutputStream before being closed. Further attempts to read the closed stream will result in an IOException.

Parameters:
pStream - the OutputStream to write to.
Exceptions:
IOException - if an error occurs writing to the OutputStream or reading from a filename field's InputStream.
NullPointerException - if pStream is null.


Cross-Platform C++

Found a bug or missing feature? Please email us at support@elcel.com

Copyright © 2000-2005 ElCel Technology   Trademark Acknowledgements