* Sends the request via REST API and returns the parsed response. * * @param tlsStream Caller must prepare TLS stream/handshake. * @param url Fully prepared Url object. * @return A dictionary decoded from JSON. */
| 569 | * @return A dictionary decoded from JSON. |
| 570 | */ |
| 571 | Dictionary::Ptr ConsoleCommand::SendRequest() |
| 572 | { |
| 573 | namespace beast = boost::beast; |
| 574 | namespace http = beast::http; |
| 575 | |
| 576 | l_TlsStream = ConsoleCommand::Connect(); |
| 577 | |
| 578 | Defer s ([&]() { |
| 579 | l_TlsStream->next_layer().shutdown(); |
| 580 | }); |
| 581 | |
| 582 | http::request<http::string_body> request(http::verb::post, std::string(l_Url->Format(false)), 10); |
| 583 | |
| 584 | request.set(http::field::user_agent, "Icinga/DebugConsole/" + Application::GetAppVersion()); |
| 585 | request.set(http::field::host, l_Url->GetHost() + ":" + l_Url->GetPort()); |
| 586 | |
| 587 | request.set(http::field::accept, "application/json"); |
| 588 | request.set(http::field::authorization, "Basic " + Base64::Encode(l_Url->GetUsername() + ":" + l_Url->GetPassword())); |
| 589 | |
| 590 | try { |
| 591 | http::write(*l_TlsStream, request); |
| 592 | l_TlsStream->flush(); |
| 593 | } catch (const std::exception &ex) { |
| 594 | Log(LogWarning, "DebugConsole") |
| 595 | << "Cannot write HTTP request to REST API at URL '" << l_Url->Format(true) << "': " << ex.what(); |
| 596 | throw; |
| 597 | } |
| 598 | |
| 599 | http::parser<false, http::string_body> parser; |
| 600 | beast::flat_buffer buf; |
| 601 | |
| 602 | try { |
| 603 | http::read(*l_TlsStream, buf, parser); |
| 604 | } catch (const std::exception &ex) { |
| 605 | Log(LogWarning, "DebugConsole") |
| 606 | << "Failed to parse HTTP response from REST API at URL '" << l_Url->Format(true) << "': " << ex.what(); |
| 607 | throw; |
| 608 | } |
| 609 | |
| 610 | auto &response(parser.get()); |
| 611 | |
| 612 | /* Handle HTTP errors first. */ |
| 613 | if (response.result() != http::status::ok) { |
| 614 | String message = "HTTP request failed; Code: " + Convert::ToString(response.result()) |
| 615 | + "; Body: " + response.body(); |
| 616 | BOOST_THROW_EXCEPTION(ScriptError(message)); |
| 617 | } |
| 618 | |
| 619 | Dictionary::Ptr jsonResponse; |
| 620 | auto &body(response.body()); |
| 621 | |
| 622 | //Log(LogWarning, "Console") |
| 623 | // << "Got response: " << response.body(); |
| 624 | |
| 625 | try { |
| 626 | jsonResponse = JsonDecode(body); |
| 627 | } catch (...) { |
| 628 | String message = "Cannot parse JSON response body: " + response.body(); |
nothing calls this directly
no test coverage detected