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

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

#1 change access modifier of filter and http messages

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