source: cheroxy/trunk/src/CRXHttpResponse.cpp@ 26

Last change on this file since 26 was 26, checked in by cheese, 11 years ago

#1 add function to reset request and response

File size: 6.0 KB
Line 
1/**
2 * CRXHttpResponse.cpp
3 */
4#ifdef _WIN32
5# pragma warning (disable:4996)
6#endif
7
8#include "CRXHttpResponse.h"
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#define CRLF "\r\n"
15#define CRLF2 "\r\n\r\n"
16
17#define CONTENT_LENGTH "Content-Length: "
18#define TRANSFER_ENCODING "Transfer-Encoding: "
19
20CRXHttpResponse::CRXHttpResponse (void)
21 : mStatusCode (0),
22 mIsChunked (false),
23 mContentLength (0)
24{
25 /*----------------------------------------------------------------*/
26 memset (&mContent, 0x00, sizeof (mContent));
27 /*----------------------------------------------------------------*/
28}
29
30CRXHttpResponse::~CRXHttpResponse (void)
31{
32 /*----------------------------------------------------------------*/
33 Reset ();
34 /*----------------------------------------------------------------*/
35}
36
37void
38CRXHttpResponse::Reset (void)
39{
40 /*----------------------------------------------------------------*/
41 ResetMessage ();
42 ResetContent ();
43 /*----------------------------------------------------------------*/
44}
45
46void
47CRXHttpResponse::ResetContent (void)
48{
49 /*----------------------------------------------------------------*/
50 if (mContent.mBody)
51 free (mContent.mBody);
52
53 memset (&mContent, 0x00, sizeof (mContent));
54 /*----------------------------------------------------------------*/
55}
56
57int
58CRXHttpResponse::SetResponse (const char * aHttpResponse,
59 const int aResponseLength)
60{
61 int aResult = 0;
62
63 const char * aEndOfHeader = NULL;
64 std::string aHeader;
65
66 int aHeaderLength = 0;
67
68 /*----------------------------------------------------------------*/
69 if (aResponseLength <= 0)
70 return ERROR_HTTP_RESPONSE_INVALID_LENGTH;
71
72 if (GetHeader ().length () == 0)
73 {
74 aEndOfHeader = strstr (aHttpResponse, CRLF2);
75 if (aEndOfHeader == NULL)
76 return ERROR_HTTP_RESPONSE_INVALID_FORMAT;
77
78 aEndOfHeader += strlen (CRLF2);
79 aHeaderLength = aEndOfHeader - aHttpResponse;
80 aHeader.assign (aHttpResponse, aHeaderLength);
81
82 SetMessage (aHeader.c_str ());
83 }
84
85 aResult = ParseContent (aHttpResponse + aHeaderLength, aResponseLength - aHeaderLength);
86 if (aResult)
87 {
88 return ERROR_HTTP_RESPONSE_FAILED_TO_PARSE_CONTENT;
89 }
90 /*----------------------------------------------------------------*/
91
92 return aResult;
93}
94
95CRXHttpResponse &
96CRXHttpResponse::operator = (const char * aHttpMessage)
97{
98 /*----------------------------------------------------------------*/
99 SetMessage (aHttpMessage);
100 /*----------------------------------------------------------------*/
101
102 return *this;
103}
104
105std::string
106CRXHttpResponse::GetHeader (void) const
107{
108 /*----------------------------------------------------------------*/
109 /*----------------------------------------------------------------*/
110
111 return GetMessage ();
112}
113
114int
115CRXHttpResponse::GetStatusCode (void) const
116{
117 /*----------------------------------------------------------------*/
118 /*----------------------------------------------------------------*/
119
120 return mStatusCode;
121}
122
123int
124CRXHttpResponse::GetContentLength (void) const
125{
126 /*----------------------------------------------------------------*/
127 /*----------------------------------------------------------------*/
128
129 return mContentLength;
130}
131
132const char *
133CRXHttpResponse::GetContentBody (void) const
134{
135 /*----------------------------------------------------------------*/
136 /*----------------------------------------------------------------*/
137
138 return mContent.mBody;
139}
140
141void
142CRXHttpResponse::Parse (void)
143{
144 std::string aValue;
145
146 char aStatusCode[64] = {0x00, };
147 char aStatusName[64] = {0x00, };
148 char aHttpVersion[64] = {0x00, };
149
150 size_t aBegin = 0;
151 size_t aOffset = 0;
152
153 /*----------------------------------------------------------------*/
154 aValue = GetHeader ().substr (0, GetHeader ().find (CRLF, 0));
155
156 /*----------------------------------------------------------------
157 * 1. separate first line to <METHOD>, <URL> and <VERSION>
158 *----------------------------------------------------------------*/
159 sscanf (aValue.c_str (), "%[^ ] %[^ ] %[^ ]\r\n", aHttpVersion, aStatusCode, aStatusName);
160 mHttpVersion.assign (aHttpVersion);
161 mStatusString.assign (aStatusName);
162 mStatusCode = atoi (aStatusCode);
163
164 /*----------------------------------------------------------------
165 * 2. get Content-Length or check is chunked
166 *----------------------------------------------------------------*/
167 aBegin = GetHeader ().find (CONTENT_LENGTH);
168 if (aBegin == std::string::npos)
169 {
170 /* is really chunked encoding ? */
171 aBegin = GetHeader ().find (TRANSFER_ENCODING);
172 if (aBegin == std::string::npos)
173 return ;
174
175 aBegin += strlen (TRANSFER_ENCODING);
176 aOffset = GetHeader ().find (CRLF, aBegin) - aBegin;
177
178 aValue = GetHeader ().substr (aBegin, aOffset);
179 if (aValue == "chunked")
180 {
181 mIsChunked = true;
182 return ;
183 }
184 }
185
186 aBegin += strlen (CONTENT_LENGTH);
187 aOffset = GetHeader ().find (CRLF, aBegin) - aBegin;
188
189 aValue = GetHeader ().substr (aBegin, aOffset);
190 mContentLength = atoi (aValue.c_str ());
191 /*----------------------------------------------------------------*/
192}
193
194int
195CRXHttpResponse::ParseContent (const char * aContent,
196 const int aLength)
197{
198 int aResult = 0;
199
200 char * aReallocPtr = NULL;
201
202 /*----------------------------------------------------------------*/
203 if (!mIsChunked)
204 {
205 if (mContentLength <= mContent.mLength)
206 return aResult;
207
208 if (mContent.mBody == NULL)
209 {
210 mContent.mBody = static_cast<char *> (calloc (mContentLength, 1));
211 if (mContent.mBody == NULL)
212 {
213 return ERROR_HTTP_RESPONSE_FAILED_TO_MEMORY_ALLOCATION;
214 }
215 }
216 }
217 else
218 {
219 mContentLength += aLength;
220 aReallocPtr = static_cast<char *> (realloc (mContent.mBody, mContentLength));
221 if (aReallocPtr == NULL)
222 {
223 return ERROR_HTTP_RESPONSE_FAILED_TO_MEMORY_ALLOCATION;
224 }
225 mContent.mBody = aReallocPtr;
226 }
227
228 memcpy (mContent.mBody + mContent.mLength, aContent, aLength);
229 mContent.mLength += aLength;
230 /*----------------------------------------------------------------*/
231
232 return aResult;
233}
Note: See TracBrowser for help on using the repository browser.