diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2024-07-16 17:37:25 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2024-07-16 22:39:00 +0300 |
commit | 7bf121b0e49418db270f62b2796c788c97a482f3 (patch) | |
tree | 74b6a0ab1992da4d5a63423a1b1c28180d045e36 | |
parent | e51291ddbd20646332919bd8294bff3150beecdb (diff) |
Fix http_service::post() to skip potential CONNECT response
-rw-r--r-- | bbot/agent/http-service.cxx | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/bbot/agent/http-service.cxx b/bbot/agent/http-service.cxx index 1921edc..a56c259 100644 --- a/bbot/agent/http-service.cxx +++ b/bbot/agent/http-service.cxx @@ -212,7 +212,7 @@ namespace bbot return optional<string> (move (r)); }; - while (!(l = curl::read_http_response_line (is)).empty ()) + auto parse_header = [&ctype, &location, &rs, &header] () { if (optional<string> v = header ("Content-Type")) ctype = move (v); @@ -221,6 +221,36 @@ namespace bbot if ((rs.code >= 301 && rs.code <= 303) || rs.code == 307) location = move (v); } + }; + + // Note that the curl's output may include the CONNECT response (see + // curl::read_http_status() for details). If that's the case, then + // skip it, similar to curl::read_http_status(). + // + bool content_expected (false); + while (!(l = curl::read_http_response_line (is)).empty ()) + { + if (curl::http_content_aspect (l)) + content_expected = true; + + parse_header (); + } + + if (rs.code == 200 && !content_expected) + { + try + { + rs = curl::read_http_status (is, false /* skip_headers */); + } + catch (const invalid_argument& e) + { + bad_response ( + string ("unable to read proxied HTTP response status line: ") + + e.what ()); + } + + while (!(l = curl::read_http_response_line (is)).empty ()) + parse_header (); } assert (!eof (is)); // Would have already failed otherwise. |