]> granicus.if.org Git - icinga2/commitdiff
Rewrite error handling in HttpServerConnection#EnsureValidHeaders() 7486/head
authorMichael Friedrich <michael.friedrich@icinga.com>
Fri, 6 Sep 2019 12:19:53 +0000 (14:19 +0200)
committerMichael Friedrich <michael.friedrich@icinga.com>
Mon, 9 Sep 2019 09:03:21 +0000 (11:03 +0200)
Throwing local exceptions unnecessarily pollutes the exception
stack with immediate unwinding. Avoid this pattern at all cost within
Boost.Coroutines. MSVC may handle exceptions differently and cause
problems with stack unwinding.

refs #7431
refs #7351

lib/remote/httpserverconnection.cpp

index 01b32f403b36370d5e402313d1138144915c37fc..cca0ff79949e19477e392130aa6dd6a00628ce10 100644 (file)
@@ -146,43 +146,37 @@ bool EnsureValidHeaders(
 {
        namespace http = boost::beast::http;
 
-       bool httpError = true;
+       bool httpError = false;
+       String errorMsg;
 
-       try {
-               boost::system::error_code ec;
+       boost::system::error_code ec;
 
-               http::async_read_header(stream, buf, parser, yc[ec]);
+       http::async_read_header(stream, buf, parser, yc[ec]);
 
-               if (ec) {
-                       /**
-                        * Unfortunately there's no way to tell an HTTP protocol error
-                        * from an error on a lower layer:
-                        *
-                        * <https://github.com/boostorg/beast/issues/643>
-                        */
-                       throw std::invalid_argument(ec.message());
-               }
+       if (ec) {
+               errorMsg = ec.message();
+               httpError = true;
+       }
 
-               httpError = false;
+       switch (parser.get().version()) {
+       case 10:
+       case 11:
+               break;
+       default:
+               errorMsg = "Unsupported HTTP version";
+       }
 
-               switch (parser.get().version()) {
-               case 10:
-               case 11:
-                       break;
-               default:
-                       throw std::invalid_argument("Unsupported HTTP version");
-               }
-       } catch (const std::invalid_argument& ex) {
+       if (!errorMsg.IsEmpty() || httpError) {
                response.result(http::status::bad_request);
 
                if (!httpError && parser.get()[http::field::accept] == "application/json") {
                        HttpUtility::SendJsonBody(response, nullptr, new Dictionary({
                                { "error", 400 },
-                               { "status", String("Bad Request: ") + ex.what() }
+                               { "status", String("Bad Request: ") + errorMsg }
                        }));
                } else {
                        response.set(http::field::content_type, "text/html");
-                       response.body() = String("<h1>Bad Request</h1><p><pre>") + ex.what() + "</pre></p>";
+                       response.body() = String("<h1>Bad Request</h1><p><pre>") + errorMsg + "</pre></p>";
                        response.set(http::field::content_length, response.body().size());
                }