aboutsummaryrefslogtreecommitdiff
path: root/bbot
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2024-02-23 21:15:51 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2024-02-23 21:15:51 +0300
commit87953be10ff92b98b63e9d478dbd8da91bd3ea5e (patch)
tree455f61b8c1449803ccbf0b95b96761812b3c5bee /bbot
parent030316099c85db768c8d2488823b33532bf44efd (diff)
Make use of new functions in curl API
Diffstat (limited to 'bbot')
-rw-r--r--bbot/agent/http-service.cxx121
1 files changed, 10 insertions, 111 deletions
diff --git a/bbot/agent/http-service.cxx b/bbot/agent/http-service.cxx
index 28b4d94..1921edc 100644
--- a/bbot/agent/http-service.cxx
+++ b/bbot/agent/http-service.cxx
@@ -3,7 +3,7 @@
#include <bbot/agent/http-service.hxx>
-#include <cstdlib> // strtoul()
+#include <libbutl/curl.hxx>
#include <bbot/diagnostics.hxx>
@@ -166,119 +166,18 @@ namespace bbot
file_text = nullptr;
}
- // Parse and return the HTTP status code. Return 0 if the argument is
- // invalid.
- //
- auto status_code = [] (const string& s)
- {
- char* e (nullptr);
- unsigned long c (strtoul (s.c_str (), &e, 10)); // Can't throw.
- assert (e != nullptr);
-
- return *e == '\0' && c >= 100 && c < 600
- ? static_cast<uint16_t> (c)
- : 0;
- };
-
- // Read the CRLF-terminated line from the stream stripping the
- // trailing CRLF.
- //
- auto read_line = [&is] ()
- {
- string l;
- getline (is, l); // Strips the trailing LF (0xA).
-
- // Note that on POSIX CRLF is not automatically translated into
- // LF, so we need to strip CR (0xD) manually.
- //
- if (!l.empty () && l.back () == '\r')
- l.pop_back ();
-
- return l;
- };
-
auto bad_response = [] (const string& d) {throw runtime_error (d);};
- // Read and parse the HTTP response status line, return the status
- // code and the reason phrase.
- //
- struct http_status
- {
- uint16_t code;
- string reason;
- };
+ curl::http_status rs;
- auto read_status = [&read_line, &status_code, &bad_response] ()
+ try
{
- string l (read_line ());
-
- for (;;) // Breakout loop.
- {
- if (l.compare (0, 5, "HTTP/") != 0)
- break;
-
- size_t p (l.find (' ', 5)); // The protocol end.
- if (p == string::npos)
- break;
-
- p = l.find_first_not_of (' ', p + 1); // The code start.
- if (p == string::npos)
- break;
-
- size_t e (l.find (' ', p + 1)); // The code end.
- if (e == string::npos)
- break;
-
- uint16_t c (status_code (string (l, p, e - p)));
- if (c == 0)
- break;
-
- string r;
- p = l.find_first_not_of (' ', e + 1); // The reason start.
- if (p != string::npos)
- {
- e = l.find_last_not_of (' '); // The reason end.
- assert (e != string::npos && e >= p);
-
- r = string (l, p, e - p + 1);
- }
-
- return http_status {c, move (r)};
- }
-
- bad_response ("invalid HTTP response status line '" + l + '\'');
-
- assert (false); // Can't be here.
- return http_status {};
- };
-
- // The curl output for a successfull request looks like this:
- //
- // HTTP/1.1 100 Continue
- //
- // HTTP/1.1 200 OK
- // Content-Length: 83
- // Content-Type: text/manifest;charset=utf-8
- //
- // : 1
- // status: 200
- // message: submission is queued
- // reference: 256910ca46d5
- //
- // curl normally sends the 'Expect: 100-continue' header for uploads,
- // so we need to handle the interim HTTP server response with the
- // continue (100) status code.
- //
- // Interestingly, Apache can respond with the continue (100) code and
- // with the not found (404) code afterwords. Can it be configured to
- // just respond with 404?
- //
- http_status rs (read_status ());
-
- if (rs.code == 100)
+ rs = curl::read_http_status (is, false /* skip_headers */);
+ }
+ catch (const invalid_argument& e)
{
- while (!read_line ().empty ()) ; // Skips the interim response.
- rs = read_status (); // Reads the final status code.
+ bad_response (
+ string ("unable to read HTTP response status line: ") + e.what ());
}
// Read through the response headers until the empty line is
@@ -313,7 +212,7 @@ namespace bbot
return optional<string> (move (r));
};
- while (!(l = read_line ()).empty ())
+ while (!(l = curl::read_http_response_line (is)).empty ())
{
if (optional<string> v = header ("Content-Type"))
ctype = move (v);
@@ -363,7 +262,7 @@ namespace bbot
if (n != "status")
bad_value ("no status specified");
- uint16_t c (status_code (v));
+ uint16_t c (curl::parse_http_status_code (v));
if (c == 0)
bad_value ("invalid HTTP status '" + v + '\'');