matlab.net.http.io.MultipartConsumer class

Package: matlab.net.http.io
Superclasses: matlab.net.http.io.GenericConsumer

Helper for multipart content types in HTTP messages

Description

This consumer processes multipart HTTP response messages. A multipart message is one whose Content-Type header field specifies "multipart", and whose body contains one or more parts. Each part contains its own set of header fields describing the part, the most important of which is a Content-Type field.

The matlab.net.http.io.MultipartConsumer class is a handle class.

Subclass Authors

If you are writing your own ContentConsumer, it will generally work whether it is a top level consumer (specified as the 3rd argument to the RequestMessage.send method) or a part of a multipart message (when specified as a "delegate" in the MultipartConsumer constructor call). MultipartConsumer makes it appear to each delegate as if it was handling the entire response message, while actually assembling the results into an array of ResponseMessages stored in the returned response.Body.Data property.

The following describes the MultipartConsumer behavior:

Each time this MultipartConsumer receives a complete part of a message from the server, it parses any headers in the part and then invokes the appropriate delegate consumer appropriate for the Content-Type field in the part. If there is no Content-Type field in the part, it assumes the type is text/plain. If there is no delegate able to handle the type, it uses default processing for the part based on the Content-Type, as described for GenericConsumer.

MultipartConsumer does not invoke a delegate until it receives a complete part. MultipartConsumer buffers the data for a part, and at the end of receipt of the part, it copies all the visible properties of ContentConsumer from this consumer to the delegate, clears the delegate's Response.Body, sets the delegate's Header to the header of the part, and then calls the delegate's initialize and start methods, followed by one or more calls to the delegate's putData method containing the payload of the part, followed by a call to putData(uint8.empty) to indicate end-of-data. If the delegate's initialize method returns false to indicate it does not want to handle the part, the payload of the part is processed using default behavior for the Content-Type of the part, as described for GenericConsumer.

If the delegate's start method returns [] to indicate that there is no maximum desired buffer size, MultipartConsumer makes just one call to putData that provides the entire payload of the part, followed by the end-of-data call. Otherwise it calls putData enough times to supply the entire payload in units of the buffer size.

If the delegate's putData method sets the STOP return value to true to indicate that it does not want any more data, then MultipartConsumer closes the connection to end the transfer, as if the message had ended. In this way the delegate controls whether the remainder of the original message should be processed. If putData returns a SIZE of [], then the message also ends, but with an exception thrown to the caller of RequestMessage.send.

If the consumer for a part was specified as a function handle rather than a ContentConsumer instance, then the function is called only the first time the consumer is needed, and subsequently the same consumer instance is used for any appropriate parts of the same response message. For parts processed by a function handle, the corresponding ResponseMessage in Response.Body.Data contains only a header for the part, because the function does not have access to the ResponseMessage body.

A delegated consumer can access this consumer and its properties through its MyDelegator property, though that is rarely necessary.

Creation

Description

consumer = MultipartConsumer(types,consumer) constructs a MultipartConsumer to handle the specified types using the corresponding consumer. You can specify several argument pairs in any order as types1,consumer1,...,typesN,consumerN. MATLAB® searches the types in the order they appear and uses the first match. If there are no matches among the specified types, MATLAB uses the default set of consumers, depending on the type.

consumer = MultipartConsumer(puthandle) constructs a ContentConsumer that calls the function specified by puthandle for each call to this consumer's putData method.

Input Arguments

expand all

Content types, specified as a string array, character vector, or cell array of character vectors. types specifies content types using the syntax "type/subtype". For more information, see matlab.net.http.io.GenericConsumer.

Content consumer, specified as a matlab.net.http.io.ContentConsumer object that can handle the specified types, or a handle to a function returning a ContentConsumer that can handle those types.

Handle to a putData function with the following ContentConsumer.putData syntax:

[length,stop] = putData(data)

where data is a uint8 array and length is the length of that array.

Use this syntax to process all input from the server using a single function, when you know the type of data that the server returns. The function does not have access to the ResponseMessage or any information about this consumer.

Properties

expand all

Public Properties

The part of the multipart message before the first boundary delimiter, if any, specified as uint8. The consumer sets Preamble before calling the start method in a delegate. Once set, the Preamble value never changes.

Attributes:

GetAccess

public

SetAccess

private

The part of the multipart message following the last boundary delimiter, if any, specified as uint8. The consumer sets Epilogue when the message ends, after all calls to delegates. It is not set if a delegate terminates the transfer before the end of the message. You can examine this property after the transfer is complete, for example, when RequestMessage.send returns.

Attributes:

GetAccess

public

SetAccess

private

Suggested buffer size, specified as uint64. MATLAB sets AllocationLength to the anticipated size of buffers of data passed to putData. The actual size might be smaller or larger. To improve performance, the consumer can use this value to preallocate space to handle the data.

MATLAB sets this property before calling the start method for the convenience of subclasses.

Attributes:

GetAccess

public

SetAccess

public

Expected length of the payload, specified as uint64. The property normally is the Value property of the matlab.net.http.field.ContentLengthField in the Header property.

If ContentLength is empty, then the length is not known. The payload ends when putData(uint8.empty) is called.

MATLAB sets this property before calling initialize, for the convenience of subclasses that might benefit from knowing the length of the data.

If this ContentConsumer is a delegate of a top-level consumer, then the value of ContentLength might be different from the ContentLength value of the top-level consumer.

Example: numel(someData) where someData is type uint8

Attributes:

GetAccess

public

SetAccess

public

Media type of payload, specified as a matlab.net.http.MediaType object. The property normally is the Value property of the matlab.net.http.field.ContentTypeField in the Header property. If the ContentType property is empty, then the ContentTypeField is empty or nonexistent.

MATLAB sets this property before calling initialize for the convenience of subclasses that might want to examine the MediaType. Subclasses can set this property if they determine from the data that it is of a different MediaType.

At the end of the transfer, MATLAB copies this value into the Response.Body.ContentType property.

Example: 'application/octet-stream'

Attributes:

GetAccess

public

SetAccess

public

Header of the payload currently being processed, specified as a matlab.net.http.HeaderField object.

Consumers use this header to determine how to process the payload that is being sent to them. For a top-level consumer, this value is the same as Response.Header. For a delegate, the value might be different. For example, in a multipart message processed by a MultipartConsumer, it is the header of the part that this delegate is processing. The delegate can still examine Response.Header for headers of the original message.

MATLAB sets this property before calling initialize, for the convenience of subclasses.

Attributes:

GetAccess

public

SetAccess

public

The completed RequestMessage that was sent, specified as a matlab.net.http.RequestMessage object. This is the final RequestMessage after all redirections, which is the completedrequest return value from the send method.

MATLAB sets this property before calling initialize, for the convenience of subclasses.

Attributes:

GetAccess

public

SetAccess

public

The ResponseMessage being processed, specified as a matlab.net.http.ResponseMessage object.

MATLAB sets the Response property before calling initialize. The value is the ResponseMessage after headers have been received but before receiving any payload. At the start of the response message processing (or the start of a part for multipart messages), the ResponseMesssage.Body property is a MessageBody object with empty Data and Payload properties. To store received data, consumers can modify the Response and MessageBody.Data properties during data transfer. Usually, consumers that process and then store data set Response.Body.Data to their processed payload, though this is not required. At the completion of the transfer, MATLAB returns this Response to the caller of send. Consumers should not modify other Response properties, such as Header or StatusLine, as those changes are returned to the caller of send.

The Response.Body.Payload property is empty during the transfer and consumers should not attempt to modify it. If the HTTPOptions.SavePayload property is set, then MATLAB sets Payload to the received payload at the end of the transfer of the message or the part (after the call to putData(uint8.empty)) or when an exception occurs.

If an exception occurs in the consumer during message processing, then MATLAB throws an HTTPException object. The History property contains this Response value.

If the consumer is a delegate that is processing part of a multipart message, then Response.Header contains the header of the whole message, and the Payload and Data properties of Response.Body are cleared before invoking the ContentConsumer for each part. At the conclusion of each part, a new ResponseMessage is added to the end of the array of ResponseMessage objects in the original response's Body.Data containing the Header from this object and the Body from this property. The next delegate sees a fresh Response with an empty MessageBody, not the previous delegate's MessageBody.

Attributes:

GetAccess

public

SetAccess

public

Dependent

true

Destination of the request being processed, specified as a matlab.net.URI object. This value is the original destination URI as determined by send. It is not the URI of a proxy or the final URI after redirections.

MATLAB sets this property before calling initialize, for the convenience of subclasses.

Attributes:

GetAccess

public

SetAccess

public

Protected Properties

putData method of the delegate, specified as a function handle, or specified as [] if CurrentDelegate is set.

Attributes:

GetAccess

protected

SetAccess

protected

Function, specified as a function handle, called by the putData method to append additional data. The putData method in this class calls the AppendFcn function to append data it receives in its data argument to existing data in the response message. The function must have the signature:

AppendFcn(consumer,newdata)

where newdata is the data to be appended to the array at consumer.Response.Body.Data. It is the responsibility of this method to update consumer.CurrentLength to reflect the new length of Data. If newdata is empty, which indicates the end of the stream, then the function should update Response.Body.Data to its final value.

The default behavior, if this property is empty, uses an internal function that treats Data as an array of arbitrary values supporting the horzcat function. It efficiently adds newdata by preallocating space, maintaining CurrentLength to be the actual length of data stored. At the end of the message, it truncates Response.Body.Data to CurrentLength.

Subclasses can change this property if horzcat is not appropriate for the append process. For example, when a StringConsumer builds a scalar string, it would add to the string using the plus function instead of horzcat.

Subclasses that do not invoke ContentConsumer.putData to append data, or which are satisfied with horzcat behavior when appending data, can ignore this property.

Example: @customAppend where @customAppend is defined by the consumer

Attributes:

GetAccess

protected

SetAccess

protected

The ContentConsumer to which this consumer is delegating, specified as a matlab.net.http.io.ContentConsumer object. The delegateTo method of the calling consumer (the delegator) sets the CurrentDelegate property. If there is no current delegation, then the value is [].

MATLAB sets CurrentDelegate to [] before calling initialize.

Attributes:

GetAccess

protected

SetAccess

protected

Length of data currently in the Response.Body.Data property, specified as uint64.

This property is used when Response.Body.Data has been preallocated to a size larger than the actual amount of data currently stored, to indicate the length of that stored data. If this property is empty, then it means that all of Response.Body.Data contains the stored data or that a ContentConsumer subclass is disposing of the data in some way other than storing it in Response.Body.Data.

This property is used and set by the putData method in this base class when the AppendFcn property is empty. It is for the benefit of subclasses that call putData and want to examine already-stored data, and/or any implementations of AppendFcn that maintain results in Response.Body.Data.

Subclasses that use putData also can modify this property to reset the position in the buffer where the data is stored. For example, when the default AppendFcn function is used, a subclass that processes all of Response.Body.Data on each call to putData might no longer have a use for the original data, so it can reset the CurrentLength property to 1 so that the next putData call overwrites the buffer with new data. There is no need to clear elements in the buffer past the end of the new data.

Subclasses that do not call putData can use this property to track their own data, or can leave it unset (empty). MATLAB does not place any constraints on the value that can be set here and does not use it for any purpose other than to determine where the default AppendFcn should store the next buffer of data, and where to truncate the data at the end of the message. Set this property to empty before the final call to putData(uint8.empty) to prevent truncation of the data.

MATLAB sets this property to empty before each call to initialize.

Attributes:

GetAccess

protected

SetAccess

protected

The ContentConsumer that delegated to this consumer, specified as a matlab.net.http.io.ContentConsumer object. If this consumer is a delegate that was invoked by another consumer, such as a GenericConsumer or MultipartConsumer, then this is the calling consumer. It is empty in a top-level consumer specified in the call to send.

Delegates can use this property to access properties of their delegators, for example, to determine which consumer delegated to them.

Attributes:

GetAccess

protected

SetAccess

protected

Methods

expand all

More About

expand all

Introduced in R2018a