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

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

#1 fix warnings on compilation

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