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

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

#1 add filter class

File size: 5.6 KB
RevLine 
[6]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>
[25]12#include <string.h>
[6]13
[24]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
[6]20CRXHttpResponse::CRXHttpResponse (void)
[24]21 : mStatusCode (0),
22 mIsChunked (false),
23 mContentLength (0)
[6]24{
[26]25 /*----------------------------------------------------------------*/
[24]26 memset (&mContent, 0x00, sizeof (mContent));
[26]27 /*----------------------------------------------------------------*/
[6]28}
29
[24]30CRXHttpResponse::~CRXHttpResponse (void)
31{
[26]32 /*----------------------------------------------------------------*/
33 Reset ();
34 /*----------------------------------------------------------------*/
35}
36
37void
38CRXHttpResponse::Reset (void)
39{
40 /*----------------------------------------------------------------*/
41 ResetMessage ();
[24]42 ResetContent ();
[26]43 /*----------------------------------------------------------------*/
[24]44}
45
[6]46void
[24]47CRXHttpResponse::ResetContent (void)
[6]48{
[26]49 /*----------------------------------------------------------------*/
[24]50 if (mContent.mBody)
51 free (mContent.mBody);
52
53 memset (&mContent, 0x00, sizeof (mContent));
[26]54 /*----------------------------------------------------------------*/
[6]55}
56
[24]57int
58CRXHttpResponse::SetResponse (const char * aHttpResponse,
59 const int aResponseLength)
[6]60{
[24]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;
[6]93}
94
95CRXHttpResponse &
96CRXHttpResponse::operator = (const char * aHttpMessage)
97{
[26]98 /*----------------------------------------------------------------*/
[6]99 SetMessage (aHttpMessage);
[26]100 /*----------------------------------------------------------------*/
101
[6]102 return *this;
103}
104
[24]105std::string
106CRXHttpResponse::GetHeader (void) const
107{
[26]108 /*----------------------------------------------------------------*/
109 /*----------------------------------------------------------------*/
110
[24]111 return GetMessage ();
112}
113
[6]114void
115CRXHttpResponse::Parse (void)
116{
[24]117 std::string aValue;
[6]118
119 char aStatusCode[64] = {0x00, };
[24]120 char aStatusName[64] = {0x00, };
[6]121 char aHttpVersion[64] = {0x00, };
122
[24]123 size_t aBegin = 0;
124 size_t aOffset = 0;
125
[6]126 /*----------------------------------------------------------------*/
[24]127 aValue = GetHeader ().substr (0, GetHeader ().find (CRLF, 0));
[6]128
129 /*----------------------------------------------------------------
130 * 1. separate first line to <METHOD>, <URL> and <VERSION>
131 *----------------------------------------------------------------*/
[24]132 sscanf (aValue.c_str (), "%[^ ] %[^ ] %[^ ]\r\n", aHttpVersion, aStatusCode, aStatusName);
[6]133 mHttpVersion.assign (aHttpVersion);
[24]134 mStatusString.assign (aStatusName);
[6]135 mStatusCode = atoi (aStatusCode);
[24]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 ());
[6]164 /*----------------------------------------------------------------*/
165}
166
167int
[24]168CRXHttpResponse::ParseContent (const char * aContent,
169 const int aLength)
[6]170{
[24]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;
[25]206}
[28]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.