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