Merge branch 'whitespace-and-libcxx-compat' of https://github.com/matvore/cpp-httplib

This commit is contained in:
yhirose 2019-12-06 09:51:21 -05:00
commit 379905bd34
2 changed files with 125 additions and 19 deletions

View file

@ -1357,6 +1357,26 @@ inline bool is_connection_error() {
#endif
}
inline socket_t create_client_socket(
const char *host, int port, time_t timeout_sec) {
return create_socket(
host, port, [=](socket_t sock, struct addrinfo &ai) -> bool {
set_nonblocking(sock, true);
auto ret = ::connect(sock, ai.ai_addr, static_cast<int>(ai.ai_addrlen));
if (ret < 0) {
if (is_connection_error() ||
!wait_until_socket_is_ready(sock, timeout_sec, 0)) {
close_socket(sock);
return false;
}
}
set_nonblocking(sock, false);
return true;
});
}
inline std::string get_remote_addr(socket_t sock) {
struct sockaddr_storage addr;
socklen_t len = sizeof(addr);
@ -1542,7 +1562,11 @@ inline uint64_t get_header_value_uint64(const Headers &headers, const char *key,
}
inline bool read_headers(Stream &strm, Headers &headers) {
static std::regex re(R"((.+?):\s*(.+?)\s*\r\n)");
// Horizontal tab and ' ' are considered whitespace and are ignored when on
// the left or right side of the header value:
// - https://stackoverflow.com/questions/50179659/
// - https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
static std::regex re(R"((.+?):[\t ]*(.+))");
const auto bufsiz = 2048;
char buf[bufsiz];
@ -1551,9 +1575,23 @@ inline bool read_headers(Stream &strm, Headers &headers) {
for (;;) {
if (!line_reader.getline()) { return false; }
if (!strcmp(line_reader.ptr(), "\r\n")) { break; }
const char *end = line_reader.ptr() + line_reader.size();
auto erase_last_char = [&](char c) {
if (line_reader.ptr() == end || end[-1] != c) {
return false;
}
end--;
return true;
};
if (!erase_last_char('\n')) { continue; }
if (!erase_last_char('\r')) { continue; }
// Blank line indicates end of headers.
if (line_reader.ptr() == end) { break; }
while (erase_last_char(' ') || erase_last_char('\t')) {}
std::cmatch m;
if (std::regex_match(line_reader.ptr(), m, re)) {
if (std::regex_match(line_reader.ptr(), end, m, re)) {
auto key = std::string(m[1]);
auto val = std::string(m[2]);
headers.emplace(key, val);
@ -3167,22 +3205,7 @@ inline Client::~Client() {}
inline bool Client::is_valid() const { return true; }
inline socket_t Client::create_client_socket() const {
return detail::create_socket(
host_.c_str(), port_, [=](socket_t sock, struct addrinfo &ai) -> bool {
detail::set_nonblocking(sock, true);
auto ret = connect(sock, ai.ai_addr, static_cast<int>(ai.ai_addrlen));
if (ret < 0) {
if (detail::is_connection_error() ||
!detail::wait_until_socket_is_ready(sock, timeout_sec_, 0)) {
detail::close_socket(sock);
return false;
}
}
detail::set_nonblocking(sock, false);
return true;
});
return detail::create_client_socket(host_.c_str(), port_, timeout_sec_);
}
inline bool Client::read_response_line(Stream &strm, Response &res) {