Commit b1cfeede authored by Felix Morgner's avatar Felix Morgner
Browse files

week10: add simple error handling to SyncJuliaClient

parent 769a716e
......@@ -21,7 +21,7 @@ namespace http {
template<typename ValueType>
auto parameter(std::string name, ValueType value) -> request & {
if constexpr(std::is_same_v<std::string, ValueType>) {
if constexpr(std::is_same_v<std::string, ValueType> || std::is_same_v<char const *, ValueType>) {
m_parameters[name] = value;
} else {
m_parameters[name] = std::to_string(value);
......
......@@ -12,6 +12,8 @@ namespace http {
explicit response(status_code code) noexcept;
explicit response(std::istream & stream);
auto status() const noexcept -> status_code;
auto friend operator<<(std::ostream & out, response const & request) -> std::ostream &;
private:
......
......@@ -37,6 +37,10 @@ namespace http {
read_headers(input);
}
auto response::status() const noexcept -> status_code {
return m_code;
}
auto operator<<(std::ostream &out, response const &request) -> std::ostream &
{
//@formatter:off
......
......@@ -2,41 +2,78 @@
#include "asio.hpp"
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <istream>
#include <iterator>
#include <sstream>
int main()
{
auto context = asio::io_context{};
int main() {
auto context = asio::io_context { };
auto resolver = asio::ip::tcp::resolver{context};
auto resolved = resolver.resolve("127.0.0.1", "8080");
auto error = asio::error_code { };
auto socket = asio::ip::tcp::socket{context};
asio::connect(socket, resolved);
auto resolver = asio::ip::tcp::resolver { context };
auto resolved = resolver.resolve("127.0.0.1", "8080", error);
auto request = std::ostringstream{};
request << http::request{http::method::get};
if (error) {
std::cerr << "Failed to resolve server address: " << error.message() << '\n';
return EXIT_FAILURE;
}
auto socket = asio::ip::tcp::socket { context };
asio::connect(socket, resolved, error);
if (error) {
std::cerr << "Failed to connect to server: " << error.message() << '\n';
return EXIT_FAILURE;
}
auto request = std::ostringstream { };
request << http::request { http::method::get };
auto request_data = request.str();
asio::write(socket, asio::buffer(request_data));
asio::write(socket, asio::buffer(request_data), error);
if (error) {
std::cerr << "Failed to send request: " << error.message() << '\n';
return EXIT_FAILURE;
}
auto response_buffer = asio::streambuf { };
auto response_stream = std::istream { &response_buffer };
asio::read_until(socket, response_buffer, "\r\n\r\n", error);
auto response_buffer = asio::streambuf{};
auto response_stream = std::istream{&response_buffer};
asio::read_until(socket, response_buffer, "\r\n\r\n");
if (error) {
std::cerr << "Failed to read response headers: " << error.message() << '\n';
return EXIT_FAILURE;
}
auto response = http::response{response_stream};
auto response = http::response { response_stream };
if(!response.complete()) {
if (!response.complete()) {
auto content_length = response.get<http::header::content_length>();
auto buffered = response_buffer.size();
asio::read(socket, response_buffer, asio::transfer_exactly(content_length - buffered));
asio::read(socket, response_buffer, asio::transfer_exactly(content_length - buffered), error);
if (error) {
std::cerr << "Failed to read response body: " << error.message() << '\n';
return EXIT_FAILURE;
}
response.body(response_stream);
}
auto file = std::ofstream{"julia.bmp", std::ios::trunc | std::ios::binary};
if(response.status() != http::status_code::ok) {
std::cerr << "Server did not accept the request: " << to_string(response.status()) << '\n';
return EXIT_FAILURE;
}
auto file = std::ofstream { "julia.bmp", std::ios::trunc | std::ios::binary };
auto image_data = response.body();
copy(cbegin(image_data), cend(image_data), std::ostream_iterator<char>{file, ""});
copy(cbegin(image_data), cend(image_data), std::ostream_iterator<char> { file, "" });
file.close();
std::cout << "Successfully received Julia fractal from the server. Result is in julia.bmp\n";
}
......@@ -2,14 +2,24 @@
#include "worker_pool.h"
#include "asio/io_context.hpp"
#include "asio/signal_set.hpp"
#include <csignal>
int main()
{
auto run_loop = asio::io_context{};
auto context = asio::io_context{};
auto workers = worker_pool{4};
auto server = julia::server{run_loop, workers, 8080};
auto server = julia::server{context, workers, 8080};
server.start_accepting();
run_loop.run();
auto signals = asio::signal_set{context, SIGINT, SIGTERM};
signals.async_wait([&](auto error, auto){
if(!error) {
server.stop_accepting();
}
});
context.run();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment