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

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

#1 add filter class

File size: 5.6 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
114void
115CRXHttpResponse::Parse (void)
116{
117 std::string aValue;
118
119 char aStatusCode[64] = {0x00, };
120 char aStatusName[64] = {0x00, };
121 char aHttpVersion[64] = {0x00, };
122
123 size_t aBegin = 0;
124 size_t aOffset = 0;
125
126 /*----------------------------------------------------------------*/
127 aValue = GetHeader ().substr (0, GetHeader ().find (CRLF, 0));
128
129 /*----------------------------------------------------------------
130 * 1. separate first line to <METHOD>, <URL> and <VERSION>
131 *----------------------------------------------------------------*/
132 sscanf (aValue.c_str (), "%[^ ] %[^ ] %[^ ]\r\n", aHttpVersion, aStatusCode, aStatusName);
133 mHttpVersion.assign (aHttpVersion);
134 mStatusString.assign (aStatusName);
135 mStatusCode = atoi (aStatusCode);
136
137 /*----------------------------------------------------------------
138 * 2. get Content-Length or check is chunked
139 *----------------------------------------------------------------*/
140 aBegin = GetHeader ().find (CONTENT_LENGTH);
141 if (aBegin == std::string::npos)
142 {
143 /* is really chunked encoding ? */
144 aBegin = GetHeader ().find (TRANSFER_ENCODING);
145 if (aBegin == std::string::npos)
146 return ;
147
148 aBegin += strlen (TRANSFER_ENCODING);
149 aOffset = GetHeader ().find (CRLF, aBegin) - aBegin;
150
151 aValue = GetHeader ().substr (aBegin, aOffset);
152 if (aValue == "chunked")
153 {
154 mIsChunked = true;
155 return ;
156 }
157 }
158
159 aBegin += strlen (CONTENT_LENGTH);
160 aOffset = GetHeader ().find (CRLF, aBegin) - aBegin;
161
162 aValue = GetHeader ().substr (aBegin, aOffset);
163 mContentLength = atoi (aValue.c_str ());
164 /*----------------------------------------------------------------*/
165}
166
167int
168CRXHttpResponse::ParseContent (const char * aContent,
169 const int aLength)
170{
171 int aResult = 0;
172
173 char * aReallocPtr = NULL;
174
175 /*----------------------------------------------------------------*/
176 if (!mIsChunked)
177 {
178 if (mContentLength <= mContent.mLength)
179 return aResult;
180
181 if (mContent.mBody == NULL)
182 {
183 mContent.mBody = static_cast<char *> (calloc (mContentLength, 1));
184 if (mContent.mBody == NULL)
185 {
186 return ERROR_HTTP_RESPONSE_FAILED_TO_MEMORY_ALLOCATION;
187 }
188 }
189 }
190 else
191 {
192 mContentLength += aLength;
193 aReallocPtr = static_cast<char *> (realloc (mContent.mBody, mContentLength));
194 if (aReallocPtr == NULL)
195 {
196 return ERROR_HTTP_RESPONSE_FAILED_TO_MEMORY_ALLOCATION;
197 }
198 mContent.mBody = aReallocPtr;
199 }
200
201 memcpy (mContent.mBody + mContent.mLength, aContent, aLength);
202 mContent.mLength += aLength;
203 /*----------------------------------------------------------------*/
204
205 return aResult;
206}
207
208int CRXHttpResponse::GetStatusCode (void) const { return mStatusCode; }
209int CRXHttpResponse::GetContentLength (void) const { return mContentLength; }
210const char * CRXHttpResponse::GetContentBody (void) const { return mContent.mBody; }
Note: See TracBrowser for help on using the repository browser.