--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/httpmessage/chttpmessagecomposer.h Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,329 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef __CHTTPMESSAGECOMPOSER_H__
+#define __CHTTPMESSAGECOMPOSER_H__
+
+#include <e32base.h>
+#include <http/mhttpdatasupplier.h>
+
+#include "timerlogger.h"
+#include "mhttpbuffersupplier.h"
+#include "thttpdatacomposer.h"
+
+
+class MHttpMessageComposerObserver;
+
+class CHttpMessageComposer : public CActive,
+ public MHttpBufferSupplier
+/**
+ The CHttpMessageComposer class provides functionality for creating HTTP/1.1
+ messages as defined in RFC2616. The HTTP/1.1 protocol specifies that the CR
+ LF sequence is the end of line (eol) marker for all protocol elements except
+ the entity-body.
+
+ The composer does not process any header fields or start-line tokens.
+ Therefore it needs to be told if headers and/or an entity body is expected.
+ If the message does contain an entity body and the size of the body data is
+ not known then the composer will apply the chunked transfer encoding to the
+ entity body.
+
+ The composer needs an observer (MHttpMessageComposerObserver). The observer
+ supplies the message info such as the start-line tokens, header field tokens
+ and other message info. An MHTTPDataSupplier object is used to supply the
+ entity body data if there is one. The observer must ensure that the
+ descriptors containing the tokens it supplies remain valid until the composer
+ notifies it that the message is complete.
+
+ The composer is initially in the Idle state waiting to be notified of
+ available message info. When it is notified, the composer moves into the
+ CreatingStartLine state.
+
+ In the CreatingStartLine state the composer obtains the start-line tokens
+ from the observer. These are added to the current data buffer. The composer
+ moves to the CreatingHeaders state.
+
+ In the CreatingHeaders state the composer adds header fields to the current
+ data buffer. The observer provides the header field tokens for the field
+ name and field value. The composer will not fold header field values onto
+ multiple lines unless the provided field token already contains folded field
+ values. The observer also informs the composer if there is no more header
+ field data. The composer remains in the CreatingHeaders state until there
+ are no more header field values.
+
+ In this case the composer adds an empty line to the current data buffer to
+ mark the end of the header fields section. The current data buffer is ready
+ to be sent and the composer informs its observer of this. The composer moves
+ into the PendingEntityBody and waits for the observer to notify it that it
+ has finished with the current data buffer.
+
+ In the PendingEntityBody state the composer releases the current data buffer.
+ It then asks its observer if the message has an entity body. If there is no
+ entity body or if it is zero length then the composer moves to PendingIdle
+ state. If there is an entity body and the size is known the composer moves
+ to the SendEntityData state. If the entity body size is unknown the composer
+ moves to the CreatingChunkSize state.
+
+ In the SendEntityBody state the composer gets the next entity body data part
+ from the data supplier for the entity body. It sets this data as the current
+ send buffer and notifies the observer that message data is ready. A check is
+ made to see that if the data supplier claims that this is the last data part
+ that all the specified amount of entity body data has been sent. If this is
+ not true the observer will receive an error code of KErrCorrupt. The composer
+ moves to PendingReleaseData state and waits for the observer to notify it
+ that it has finished with the current data buffer.
+
+ In the PendingReleaseData state the composer notifies the entity body data
+ supplier that it has finished with the current data part. If all the
+ specified entity body data has been sent the composer moves to the
+ PendingIdle state. If there is more entity body data to send the composer
+ moves to the SendEntityData and waits for the observer to notify it that
+ there is more message info available.
+
+ In the CreatingChunkSize state the composer adds the size of the following
+ chunk-data component to the current send buffer as defined in RFC2616
+ section 3.6.1. The send buffer wil contain the empty line delimiting the
+ previous chunk-data component if this is not the first chunk-size component
+ to be sent. The composer notifies its observer that message data is ready.
+ The composer moves into the SendChunkData state and waits for the observer
+ to notify it that it has finished with the current data buffer.
+
+ If the chunk-data is zero-length then the chunk-size component is not added
+ to the send buffer.
+
+ In the SendChunkData state the composer releases the current data buffer. It
+ then gets the chunk-data from the data supplier for the entity body. It sets
+ this data as the current buffer. The observer is only notified that message
+ data is ready if the chunk-data is not zer-length. The composer moves into
+ the PendingReleaseChunk state and waits for the observer to notify it that
+ it has finished with the current data buffer.
+
+ In the PendingReleaseChunk state the composer notifies the entity body data
+ supplier that it has finished with the current data part. If that was the
+ last part of the entity body data the composer adds the last-chunk component
+ to the current data buffer. It then asks the observer if the message has any
+ trailer headers. If there are trailer headers then the composer moves to the
+ CreatingTrailers state. Otherwise the composer moves to the
+ CreatingEndOfTrailers state.
+
+ If there is more entity body data to follow the composer moves to the
+ CreatingChunkSize state and waits for the observer to notify it that there is
+ more message info available.
+
+ In the CreatingTrailers state the composer adds trailer header fields to the
+ current data buffer. The observer provides the trailer header field tokens
+ for the field name and field value. The composer will not fold header field
+ values onto multiple lines unless the provided field token already contains
+ folded field values. The observer also informs the composer if the provided
+ field info is for the last trailer header field. The composer remains in the
+ CreatingTrailers state until there are no more trailer header field values.
+
+ In this case the composer adds an empty line to the current data buffer to
+ mark the end of the trailer header fields section. The current data buffer
+ is ready to be sent and the composer informs its observer of this. The
+ composer moves into the PendingEndOfChunkedBody and waits for the observer
+ to notify it that it has finished with the current data buffer.
+
+ In the PendingEndOfChunkedBody the composer releases the current data buffer
+ and moves into the PendingIdle state.
+
+ In the PendingIdle state the composer informs its observer that the message
+ is complete. The composer moves to the Idle state.
+ @internalComponent
+ @see MHttpMessageComposerObserver
+*/
+ {
+public: // methods
+
+ static CHttpMessageComposer* NewL(MHttpMessageComposerObserver& aObserver);
+ virtual ~CHttpMessageComposer();
+
+ void MessageInfoAvailable();
+ void GetMessageData(TPtrC8& aData);
+ void ReleaseMessageData();
+ void Reset();
+ TBool CheckMessagePendingComplete();
+
+private: // enums
+
+ enum TComposerState
+/**
+ The TComposerState enumeration defines the state machine for the http message
+ state machine.
+*/
+ {
+ /** The composer is idle.
+ */
+ EIdle = 0,
+
+ /** The start-line is being created. The next state depends on whether
+ there are headers or not.
+ */
+ ECreatingStartLine,
+
+ /** The message has header fields. The next header field is added to the
+ http message. The composer remains in this state until all the header
+ fields have been added. If there is no more header field info an
+ empty line is added. The composer has prepared the first part of the
+ http message and can notify its observer that message data is ready.
+ */
+ ECreatingHeaders,
+
+ /** The composer needs to decide whether there is entity body and if so
+ does it need to be chunk encoded or not.
+ */
+ EPendingEntityBody,
+
+ /** The message has a non-encoded entity body. It notifies its observer
+ that message data is ready.
+ */
+ ESendEntityData,
+
+ /** The composer releases the current entity body data. If all the body
+ data has been sent then the message is complete. Otherwise the
+ composer waits to be notified that more entity body data is available.
+ */
+ EPendingReleaseData,
+
+ /** There is entity body to sent as in chunk-encoded format. The chunk-
+ size component specifying the size of the subsequent chunk-data is
+ added to the send buffer. The composer notifies its observer that it
+ has message ready. Note the send buffer will contain the empty line
+ marking the end of the previous chunk-data if this is not the first
+ chunk-size.
+ */
+ ECreatingChunkSize,
+
+ /** The chunk-data is ready to be sent. The observer is notified that
+ there is message data ready.
+ */
+ ESendChunkData,
+
+ /** The composer releases the current chunk-data. If this was the last
+ chunk-data then the composer checks for trailer headers. If there
+ are no trailer then the message is complete, otherwise the trailers
+ are added.
+ */
+ EPendingReleaseChunk,
+
+ /** The message has trailer header fields. The next trailer header field
+ is added to the http message. The composer remains in this state
+ until all the trailer header fields have been added. If there is no
+ more trailer header field info an empty line is added. The composer
+ has prepared the final part of the http message and can notify its
+ observer that message data is ready.
+ */
+ ECreatingTrailers,
+
+ /** The composer releases the current data buffer. The observer needs
+ to be informed that message is complete.
+ */
+ EPendingEndOfChunkedBody,
+
+ /** The message is complete and the composer is waiting to go idle. The
+ observer is notified.
+ */
+ EPendingIdle
+ };
+
+ enum TDataState
+/**
+ The TDataState enumeration defines the state of the message parser as
+ regards to the current data packet.
+*/
+ {
+ /** The composer is waiting for more message info to be available to be
+ able to continue composing.
+ */
+ EWaitingForInfo = 0,
+
+ /** The composer is creating the message from the available info.
+ */
+ EGotInfo,
+
+ /** The composer is waiting for the observer to release the current data
+ buffer before continuing to compose the message.
+ */
+ EWaitingForRelease,
+
+ /** The composer has been reset.
+ */
+ EReset
+ };
+
+ enum TComposingStatus
+/**
+ The TComposingStatus enumeration defines the status of composing for the
+ current state of the composer.
+*/
+ {
+ /** The current state has been completed.
+ */
+ ESectionDone = 0,
+
+ /** The current state has not been completed.
+ */
+ ESectionNotDone,
+
+ /** The current data packet should be sent.
+ */
+ ESendData,
+
+ /** The composer should not continue. Either the message is complete or
+ more message info is required to continue.
+ */
+ EStop
+ };
+
+private: // methods from CActive
+
+ virtual void RunL();
+ virtual void DoCancel();
+ virtual TInt RunError(TInt aError);
+
+private: // methods from MHttpBufferSupplier
+
+ virtual void ReAllocBufferL(TInt aRequiredSize, TPtr8& aBuffer);
+ virtual void DeleteBuffer();
+
+private: // methods
+
+ CHttpMessageComposer(MHttpMessageComposerObserver& aObserver);
+
+ TComposingStatus ComposeStartLineL();
+ TComposingStatus ComposeHeadersL();
+ TComposingStatus ComposeSingleHeaderL();
+ TComposingStatus ComposeChunkSizeL();
+ TComposingStatus ComposeLastChunkL();
+ TComposingStatus ComposeTrailerL();
+
+ void CompleteSelf();
+ void DoReset();
+
+private: // attributes
+
+ MHttpMessageComposerObserver& iObserver;
+ THttpDataComposer iDataComposer;
+ TComposerState iState;
+ TDataState iDataState;
+ HBufC8* iDataBuffer;
+ TPtrC8 iSendBuffer;
+ MHTTPDataSupplier* iBodyData;
+ TInt iDataSizeLeft;
+ TBool iLastChunk;
+ __DECLARE_PERFORMANCE_LOG
+ };
+
+#endif // __CHTTPMESSAGECOMPOSER_H__