|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #ifndef __RHTTPMESSAGECOMPOSER_H__ |
|
17 #define __RHTTPMESSAGECOMPOSER_H__ |
|
18 |
|
19 #include <e32std.h> |
|
20 |
|
21 class CHttpMessageComposer; |
|
22 class MHttpMessageComposerObserver; |
|
23 |
|
24 class RHttpMessageComposer |
|
25 /** |
|
26 The RHttpMessageComposer class provides functionality for creating HTTP/1.1 |
|
27 messages as defined in RFC2616. The HTTP/1.1 protocol specifies that the CR |
|
28 LF sequence is the end of line (eol) marker for all protocol elements except |
|
29 the entity-body. |
|
30 |
|
31 The composer does not process any header fields or start-line tokens. |
|
32 Therefore it needs to be told if headers and/or an entity body is expected. |
|
33 If the message does contain an entity body and the body data is streamed the |
|
34 composer will apply the chunked transfer encoding to the entity body. |
|
35 |
|
36 The composer needs an observer (MHttpMessageComposerObserver). The observer |
|
37 supplies the message info such as the start-line tokens, header field tokens |
|
38 and other message info. An MHTTPDataSupplier object is used to supply the |
|
39 entity body data if there is one. The observer must ensure that the |
|
40 descriptors containing the tokens it supplies remain valid until the composer |
|
41 notifies it that the message is complete. |
|
42 |
|
43 The composer is initially in the Idle state waiting to be notified of |
|
44 available message info. When it is notified, the composer moves into the |
|
45 CreatingStartLine state. |
|
46 |
|
47 In the CreatingStartLine state the composer obtains the start-line tokens |
|
48 from the observer. These are added to the current data buffer. The composer |
|
49 asks its observer if the message has any headers. If there are headers the |
|
50 composer moves to the CreatingHeaders state otherwise it moves to the |
|
51 CreatingEndOfHeaders state. |
|
52 |
|
53 In the CreatingHeaders state the composer adds header fields to the current |
|
54 data buffer. The observer provides the header field tokens for the field name |
|
55 and field value. The composer will not fold header field values onto multiple |
|
56 lines unless the provided field token already contains folded field values. |
|
57 The observer also informs the composer if the provided field info is for the |
|
58 last header field. If this is the case the composer moves into the |
|
59 CreatingEndOfHeaders state, otherwise it remains in the CreatingHeaders state. |
|
60 |
|
61 In the CreatingEndOfHeaders state the composer adds an empty line to the |
|
62 current data buffer to mark the end of the header fields section. The current |
|
63 data buffer is ready to be sent and the composer informs its observer of this. |
|
64 The composer moves into the PendingEntityBody and waits for the observer to |
|
65 notify it that it has finished with the current data buffer. |
|
66 |
|
67 In the PendingEntityBody state the releases the current data buffer. It then |
|
68 asks its observer if the message has an entity body. If there is no entity |
|
69 body or if it is zero length then the composer moves to PendingIdle state. |
|
70 If there is an entity body and the size is known the composer moves to the |
|
71 SendEntityData state. If the entity body size is unknown, implying streamed |
|
72 entity body data, the composer moves to the CreatingChunkSize state. |
|
73 |
|
74 In the SendEntityBody state the composer gets the next entity body data part |
|
75 from the data supplier for the entity body. It sets this data as the current |
|
76 send buffer and notifies the observer that message data is ready. A check is |
|
77 made to see that if the data supplier claims that this is the last data part |
|
78 that all the specified amount of entity body data has been sent. If this is |
|
79 not true the observer will receive an error code of KErrCorrupt. The composer |
|
80 moves to PendingReleaseData state and waits for the observer to notify it |
|
81 that it has finished with the current data buffer. |
|
82 |
|
83 In the PendingReleaseData state the composer notifies the entity body data |
|
84 supplier that it has finished with the current data part. If all the |
|
85 specified entity body data has been sent the composer moves to the |
|
86 PendingIdle state. If there is more entity body data to send the composer |
|
87 moves to the SendEntityData and waits for the observer to notify it that |
|
88 there is more message info available. |
|
89 |
|
90 In the CreatingChunkSize state the composer adds the size of the following |
|
91 chunk-data component to the current send buffer as defined in RFC2616 |
|
92 section 3.6.1. The send buffer wil contain the empty line delimiting the |
|
93 previous chunk-data component if this is not the first chunk-size component |
|
94 to be sent. The composer notifies its observer that message data is ready. |
|
95 The composer moves into the SendChunkData state and waits for the observer |
|
96 to notify it that it has finished with the current data buffer. |
|
97 |
|
98 If the chunk-data is zero-length then the chunk-size component is not added |
|
99 to the send buffer. |
|
100 |
|
101 In the SendChunkData state the composer releases the current data buffer. It |
|
102 then gets the chunk-data from the data supplier for the entity body. It sets |
|
103 this data as the current buffer. The observer is only notified that message |
|
104 data is ready if the chunk-data is not zer-length. The composer moves into |
|
105 the PendingReleaseChunk state and waits for the observer to notify it that |
|
106 it has finished with the current data buffer. |
|
107 |
|
108 In the PendingReleaseChunk state the composer notifies the entity body data |
|
109 supplier that it has finished with the current data part. If that was the |
|
110 last part of the entity body data the composer adds the last-chunk component |
|
111 to the current data buffer. It then asks the observer if the message has any |
|
112 trailer headers. If there are trailer headers then the composer moves to the |
|
113 CreatingTrailers state. Otherwise the composer moves to the |
|
114 CreatingEndOfTrailers state. |
|
115 |
|
116 If there is more entity body data to follow the composer moves to the |
|
117 CreatingChunkSize state and waits for the observer to notify it that there is |
|
118 more message info available. |
|
119 |
|
120 In the CreatingTrailers state the composer adds trailer header fields to the |
|
121 current data buffer. The observer provides the trailer header field tokens |
|
122 for the field name and field value. The composer will not fold header field |
|
123 values onto multiple lines unless the provided field token already contains |
|
124 folded field values. The observer also informs the composer if the provided |
|
125 field info is for the last trailer header field. If this is the case the |
|
126 composer moves into the CreatingEndOfTrailers state, otherwise it remains in |
|
127 the CreatingTrailers state. |
|
128 |
|
129 In the CreatingEndOfTrailers state the composer adds an empty line to the |
|
130 current data buffer to mark the end of the trailer header fields section. |
|
131 The current data buffer is ready to be sent and the composer informs its |
|
132 bserver of this. The composer moves into the PendingEndOfChunkedBody and |
|
133 waits for the observer to notify it that it has finished with the current |
|
134 data buffer. |
|
135 |
|
136 In the PendingEndOfChunkedBody the composer releases the current data buffer |
|
137 and moves into the PendingIdle state. |
|
138 |
|
139 In the PendingIdle state the composer informs its observer that the message |
|
140 is complete. The composer moves to the Idle state. |
|
141 @see MHttpMessageComposerObserver |
|
142 */ |
|
143 { |
|
144 public: // methods |
|
145 |
|
146 inline RHttpMessageComposer(); |
|
147 |
|
148 IMPORT_C void OpenL(MHttpMessageComposerObserver& aObserver); |
|
149 IMPORT_C void Close(); |
|
150 IMPORT_C void MessageInfoAvailable(); |
|
151 IMPORT_C void GetMessageData(TPtrC8& aData); |
|
152 IMPORT_C void ReleaseMessageData(); |
|
153 IMPORT_C void Reset(); |
|
154 IMPORT_C TBool CheckMessagePendingComplete(); |
|
155 |
|
156 private: // methods |
|
157 |
|
158 IMPORT_C void Reserved_RHttpMessageComposer(); |
|
159 |
|
160 private: // attributes |
|
161 |
|
162 CHttpMessageComposer* iImplementation; |
|
163 |
|
164 }; |
|
165 |
|
166 inline RHttpMessageComposer::RHttpMessageComposer() |
|
167 : iImplementation(NULL) |
|
168 { |
|
169 } |
|
170 |
|
171 #endif // __RHTTPMESSAGECOMPOSER_H__ |
|
172 |