| 6322 | } |
| 6323 | |
| 6324 | inline bool ClientImpl::read_response_line(Stream &strm, const Request &req, |
| 6325 | Response &res) { |
| 6326 | std::array<char, 2048> buf{}; |
| 6327 | |
| 6328 | detail::stream_line_reader line_reader(strm, buf.data(), buf.size()); |
| 6329 | |
| 6330 | if (!line_reader.getline()) { return false; } |
| 6331 | |
| 6332 | #ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR |
| 6333 | const static std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r\n"); |
| 6334 | #else |
| 6335 | const static std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r?\n"); |
| 6336 | #endif |
| 6337 | |
| 6338 | std::cmatch m; |
| 6339 | if (!std::regex_match(line_reader.ptr(), m, re)) { |
| 6340 | return req.method == "CONNECT"; |
| 6341 | } |
| 6342 | res.version = std::string(m[1]); |
| 6343 | res.status = std::stoi(std::string(m[2])); |
| 6344 | res.reason = std::string(m[3]); |
| 6345 | |
| 6346 | // Ignore '100 Continue' |
| 6347 | while (res.status == 100) { |
| 6348 | if (!line_reader.getline()) { return false; } // CRLF |
| 6349 | if (!line_reader.getline()) { return false; } // next response line |
| 6350 | |
| 6351 | if (!std::regex_match(line_reader.ptr(), m, re)) { return false; } |
| 6352 | res.version = std::string(m[1]); |
| 6353 | res.status = std::stoi(std::string(m[2])); |
| 6354 | res.reason = std::string(m[3]); |
| 6355 | } |
| 6356 | |
| 6357 | return true; |
| 6358 | } |
| 6359 | |
| 6360 | inline bool ClientImpl::send(Request &req, Response &res, Error &error) { |
| 6361 | std::lock_guard<std::recursive_mutex> request_mutex_guard(request_mutex_); |