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

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

#1 change logic more detail

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 CONTENT_LENGTH "Content-Length: "
15#define TRANSFER_ENCODING "Transfer-Encoding: "
16
[6]17CRXHttpResponse::CRXHttpResponse (void)
[24]18 : mStatusCode (0),
19 mIsChunked (false),
20 mContentLength (0)
[6]21{
[26]22 /*----------------------------------------------------------------*/
[24]23 memset (&mContent, 0x00, sizeof (mContent));
[26]24 /*----------------------------------------------------------------*/
[6]25}
26
[24]27CRXHttpResponse::~CRXHttpResponse (void)
28{
[26]29 /*----------------------------------------------------------------*/
30 Reset ();
31 /*----------------------------------------------------------------*/
32}
33
34void
35CRXHttpResponse::Reset (void)
36{
37 /*----------------------------------------------------------------*/
38 ResetMessage ();
[24]39 ResetContent ();
[26]40 /*----------------------------------------------------------------*/
[24]41}
42
[6]43void
[24]44CRXHttpResponse::ResetContent (void)
[6]45{
[26]46 /*----------------------------------------------------------------*/
[24]47 if (mContent.mBody)
48 free (mContent.mBody);
49
50 memset (&mContent, 0x00, sizeof (mContent));
[26]51 /*----------------------------------------------------------------*/
[6]52}
53
[24]54int
[44]55CRXHttpResponse::SetResponseAll (const char * aHttpResponse,
56 const int aResponseLength)
[6]57{
[24]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
[44]69 if (GetHeader ().rfind (CRLF2) == std::string::npos)
[24]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
[44]79 SetHeader (aHeader.c_str ());
[24]80 }
81
[44]82 aResult = SetContent (aHttpResponse + aHeaderLength, aResponseLength - aHeaderLength);
[24]83 if (aResult)
84 {
[44]85 aResult = ERROR_HTTP_RESPONSE_FAILED_TO_PARSE_CONTENT;
[24]86 }
87 /*----------------------------------------------------------------*/
88
89 return aResult;
[6]90}
91
[44]92void
93CRXHttpResponse::SetHeader (const char * aHttpMessage)
[6]94{
[26]95 /*----------------------------------------------------------------*/
[6]96 SetMessage (aHttpMessage);
[26]97 /*----------------------------------------------------------------*/
[6]98}
99
[24]100std::string
101CRXHttpResponse::GetHeader (void) const
102{
[26]103 /*----------------------------------------------------------------*/
104 /*----------------------------------------------------------------*/
105
[24]106 return GetMessage ();
107}
108
[6]109void
110CRXHttpResponse::Parse (void)
111{
[24]112 std::string aValue;
[6]113
114 char aStatusCode[64] = {0x00, };
[24]115 char aStatusName[64] = {0x00, };
[6]116 char aHttpVersion[64] = {0x00, };
117
[24]118 size_t aBegin = 0;
119 size_t aOffset = 0;
120
[6]121 /*----------------------------------------------------------------*/
[24]122 aValue = GetHeader ().substr (0, GetHeader ().find (CRLF, 0));
[6]123
124 /*----------------------------------------------------------------
125 * 1. separate first line to <METHOD>, <URL> and <VERSION>
126 *----------------------------------------------------------------*/
[24]127 sscanf (aValue.c_str (), "%[^ ] %[^ ] %[^ ]\r\n", aHttpVersion, aStatusCode, aStatusName);
[6]128 mHttpVersion.assign (aHttpVersion);
[24]129 mStatusString.assign (aStatusName);
[6]130 mStatusCode = atoi (aStatusCode);
[24]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 ());
[6]159 /*----------------------------------------------------------------*/
160}
161
162int
[44]163CRXHttpResponse::SetContent (const char * aContent,
[24]164 const int aLength)
[6]165{
[24]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;
[25]201}
[28]202
203int CRXHttpResponse::GetStatusCode (void) const { return mStatusCode; }
[44]204bool CRXHttpResponse::IsChunked (void) const { return mIsChunked; }
[28]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.