///////////////////////////////////////////////////////
| 189 | |
| 190 | //////////////////////////////////////////////////////////// |
| 191 | void Http::Response::parse(const std::string& data) |
| 192 | { |
| 193 | std::istringstream in(data); |
| 194 | |
| 195 | // Extract the HTTP version from the first line |
| 196 | std::string version; |
| 197 | if (in >> version) |
| 198 | { |
| 199 | if ((version.size() >= 8) && (version[6] == '.') && (toLower(version.substr(0, 5)) == "http/") && |
| 200 | std::isdigit(version[5]) && std::isdigit(version[7])) |
| 201 | { |
| 202 | m_majorVersion = static_cast<unsigned int>(version[5] - '0'); |
| 203 | m_minorVersion = static_cast<unsigned int>(version[7] - '0'); |
| 204 | } |
| 205 | else |
| 206 | { |
| 207 | // Invalid HTTP version |
| 208 | m_status = Status::InvalidResponse; |
| 209 | return; |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | // Extract the status code from the first line |
| 214 | int status = 0; |
| 215 | if (in >> status) |
| 216 | { |
| 217 | m_status = static_cast<Status>(status); |
| 218 | } |
| 219 | else |
| 220 | { |
| 221 | // Invalid status code |
| 222 | m_status = Status::InvalidResponse; |
| 223 | return; |
| 224 | } |
| 225 | |
| 226 | // Ignore the end of the first line |
| 227 | in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); |
| 228 | |
| 229 | // Parse the other lines, which contain fields, one by one |
| 230 | parseFields(in); |
| 231 | |
| 232 | m_body.clear(); |
| 233 | |
| 234 | // Determine whether the transfer is chunked |
| 235 | if (toLower(getField("transfer-encoding")) != "chunked") |
| 236 | { |
| 237 | // Not chunked - just read everything at once |
| 238 | std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::back_inserter(m_body)); |
| 239 | } |
| 240 | else |
| 241 | { |
| 242 | // Chunked - have to read chunk by chunk |
| 243 | std::size_t length = 0; |
| 244 | |
| 245 | // Read all chunks, identified by a chunk-size not being 0 |
| 246 | while (in >> std::hex >> length) |
| 247 | { |
| 248 | // Drop the rest of the line (chunk-extension) |
no test coverage detected