srctree

Robin Linden parent 7606eacd f3fcb910
protocol: Rename Error to ErrorCode

This is in preparation of cleaning up the error handling.

inlinesplit
browser/gui/app.cpp added: 116, removed: 116, total 0
@@ -522,7 +522,7 @@ void App::reload() {
navigate();
}
 
void App::on_navigation_failure(protocol::Error err) {
void App::on_navigation_failure(protocol::ErrorCode err) {
update_status_line();
response_headers_str_ = maybe_page_.error().response.headers.to_string();
dom_str_.clear();
@@ -530,27 +530,27 @@ void App::on_navigation_failure(protocol::Error err) {
layout_str_.clear();
 
switch (err) {
case protocol::Error::Unresolved: {
case protocol::ErrorCode::Unresolved: {
nav_widget_extra_info_ = fmt::format("Unable to resolve endpoint for '{}'", url_buf_);
spdlog::error(nav_widget_extra_info_);
break;
}
case protocol::Error::Unhandled: {
case protocol::ErrorCode::Unhandled: {
nav_widget_extra_info_ = fmt::format("Unhandled protocol for '{}'", url_buf_);
spdlog::error(nav_widget_extra_info_);
break;
}
case protocol::Error::InvalidResponse: {
case protocol::ErrorCode::InvalidResponse: {
nav_widget_extra_info_ = fmt::format("Invalid response from '{}'", url_buf_);
spdlog::error(nav_widget_extra_info_);
break;
}
case protocol::Error::RedirectLimit: {
case protocol::ErrorCode::RedirectLimit: {
nav_widget_extra_info_ = fmt::format("Redirect limit hit while loading '{}'", url_buf_);
spdlog::error(nav_widget_extra_info_);
break;
}
case protocol::Error::Ok:
case protocol::ErrorCode::Ok:
default:
spdlog::error("This should never happen: {}", static_cast<int>(err));
break;
@@ -587,7 +587,7 @@ void App::on_page_loaded() {
 
auto icon = engine_.load(*uri).response;
sf::Image favicon;
if (icon.err != protocol::Error::Ok || !favicon.loadFromMemory(icon.body.data(), icon.body.size())) {
if (icon.err != protocol::ErrorCode::Ok || !favicon.loadFromMemory(icon.body.data(), icon.body.size())) {
spdlog::warn("Error loading favicon from '{}': {}", uri->uri, to_string(icon.err));
continue;
}
 
browser/gui/app.h added: 116, removed: 116, total 0
@@ -76,7 +76,7 @@ private:
engine::PageState &page() { return *maybe_page_.value(); }
engine::PageState const &page() const { return *maybe_page_.value(); }
 
void on_navigation_failure(protocol::Error);
void on_navigation_failure(protocol::ErrorCode);
void on_page_loaded();
void on_layout_updated();
 
 
engine/engine.cpp added: 116, removed: 116, total 0
@@ -32,7 +32,7 @@ namespace engine {
tl::expected<std::unique_ptr<PageState>, NavigationError> Engine::navigate(uri::Uri uri) {
auto result = load(std::move(uri));
 
if (result.response.err != protocol::Error::Ok) {
if (result.response.err != protocol::ErrorCode::Ok) {
return tl::unexpected{NavigationError{
.uri = std::move(result.uri_after_redirects),
.response = std::move(result.response),
@@ -80,7 +80,7 @@ tl::expected<std::unique_ptr<PageState>, NavigationError> Engine::navigate(uri::
auto &style_data = res.response;
stylesheet_url = std::move(res.uri_after_redirects);
 
if (style_data.err != protocol::Error::Ok) {
if (style_data.err != protocol::ErrorCode::Ok) {
spdlog::warn("Error {} downloading {}", static_cast<int>(style_data.err), stylesheet_url->uri);
return {};
}
@@ -147,25 +147,25 @@ Engine::LoadResult Engine::load(uri::Uri uri) {
 
int redirect_count = 0;
protocol::Response response = protocol_handler_->handle(uri);
while (response.err == protocol::Error::Ok && is_redirect(response.status_line.status_code)) {
while (response.err == protocol::ErrorCode::Ok && is_redirect(response.status_line.status_code)) {
++redirect_count;
auto location = response.headers.get("Location");
if (!location) {
response.err = protocol::Error::InvalidResponse;
response.err = protocol::ErrorCode::InvalidResponse;
return {std::move(response), std::move(uri)};
}
 
spdlog::info("Following {} redirect from {} to {}", response.status_line.status_code, uri.uri, *location);
auto new_uri = uri::Uri::parse(std::string(*location), uri);
if (!new_uri) {
response.err = protocol::Error::InvalidResponse;
response.err = protocol::ErrorCode::InvalidResponse;
return {std::move(response), std::move(uri)};
}
 
uri = *std::move(new_uri);
response = protocol_handler_->handle(uri);
if (redirect_count > kMaxRedirects) {
response.err = protocol::Error::RedirectLimit;
response.err = protocol::ErrorCode::RedirectLimit;
return {std::move(response), std::move(uri)};
}
}
 
engine/engine_test.cpp added: 116, removed: 116, total 0
@@ -28,7 +28,7 @@ using namespace std::literals;
using etest::expect;
using etest::expect_eq;
using etest::require;
using protocol::Error;
using protocol::ErrorCode;
using protocol::Response;
 
namespace {
@@ -53,7 +53,7 @@ int main() {
std::map<std::string, Response> responses{{
"hax://example.com"s,
Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><style>p { font-size: 123em; }</style></head></html>"},
},
@@ -69,7 +69,7 @@ int main() {
 
etest::test("navigation failure", [] {
engine::Engine e{std::make_unique<FakeProtocolHandler>(std::map{
std::pair{"hax://example.com"s, Response{.err = Error::Unresolved}},
std::pair{"hax://example.com"s, Response{.err = ErrorCode::Unresolved}},
})};
 
auto page = e.navigate(uri::Uri::parse("hax://example.com").value());
@@ -78,7 +78,7 @@ int main() {
 
etest::test("page load", [] {
engine::Engine e{std::make_unique<FakeProtocolHandler>(std::map{
std::pair{"hax://example.com"s, Response{.err = Error::Ok}},
std::pair{"hax://example.com"s, Response{.err = ErrorCode::Ok}},
})};
 
auto page = e.navigate(uri::Uri::parse("hax://example.com").value());
@@ -87,7 +87,7 @@ int main() {
 
etest::test("layout update", [] {
engine::Engine e{std::make_unique<FakeProtocolHandler>(std::map{
std::pair{"hax://example.com"s, Response{.err = Error::Ok}},
std::pair{"hax://example.com"s, Response{.err = ErrorCode::Ok}},
})};
e.set_layout_width(123);
 
@@ -102,7 +102,7 @@ int main() {
std::map<std::string, Response> responses{{
"hax://example.com"s,
Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html></html>"},
},
@@ -116,7 +116,7 @@ int main() {
responses = std::map<std::string, Response>{{
"hax://example.com"s,
Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><style>html { display: inline; }</style></head></html>"},
},
@@ -135,7 +135,7 @@ int main() {
std::map<std::string, Response> responses{{
"hax://example.com"s,
Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><style>"
"a { color: red; } "
@@ -158,7 +158,7 @@ int main() {
etest::test("stylesheet link, parallel download", [] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head>"
"<link rel=stylesheet href=one.css />"
@@ -166,12 +166,12 @@ int main() {
"</head></html>"},
};
responses["hax://example.com/one.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"p { font-size: 123em; }"},
};
responses["hax://example.com/two.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"p { color: green; }"},
};
@@ -185,12 +185,12 @@ int main() {
etest::test("stylesheet link, unsupported Content-Encoding", [] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><link rel=stylesheet href=lol.css /></head></html>"},
};
responses["hax://example.com/lol.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.headers{{"Content-Encoding", "really-borked-content-type"}},
.body{"p { font-size: 123em; }"},
@@ -211,12 +211,12 @@ int main() {
etest::test("stylesheet link, gzip Content-Encoding", [gzipped_css]() mutable {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><link rel=stylesheet href=lol.css /></head></html>"},
};
responses["hax://example.com/lol.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.headers{{"Content-Encoding", "gzip"}},
.body{gzipped_css},
@@ -232,7 +232,7 @@ int main() {
 
// And again, but with x-gzip instead.
responses["hax://example.com/lol.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.headers{{"Content-Encoding", "x-gzip"}},
.body{std::move(gzipped_css)},
@@ -250,14 +250,14 @@ int main() {
etest::test("stylesheet link, gzip Content-Encoding, bad header", [gzipped_css]() mutable {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><link rel=stylesheet href=lol.css /></head></html>"},
};
// Ruin the gzip header.
gzipped_css[1] += 1;
responses["hax://example.com/lol.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.headers{{"Content-Encoding", "gzip"}},
.body{std::move(gzipped_css)},
@@ -275,14 +275,14 @@ int main() {
etest::test("stylesheet link, gzip Content-Encoding, crc32 mismatch", [gzipped_css]() mutable {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><link rel=stylesheet href=lol.css /></head></html>"},
};
// Ruin the content.
gzipped_css[20] += 1;
responses["hax://example.com/lol.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.headers{{"Content-Encoding", "gzip"}},
.body{std::move(gzipped_css)},
@@ -300,12 +300,12 @@ int main() {
etest::test("stylesheet link, gzip Content-Encoding, served zlib", [zlibbed_css] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><link rel=stylesheet href=lol.css /></head></html>"},
};
responses["hax://example.com/lol.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.headers{{"Content-Encoding", "gzip"}},
.body{zlibbed_css},
@@ -323,12 +323,12 @@ int main() {
etest::test("stylesheet link, deflate Content-Encoding", [zlibbed_css] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head><link rel=stylesheet href=lol.css /></head></html>"},
};
responses["hax://example.com/lol.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.headers{{"Content-Encoding", "deflate"}},
.body{zlibbed_css},
@@ -346,18 +346,18 @@ int main() {
etest::test("redirect", [] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 301},
.headers = {{"Location", "hax://example.com/redirected"}},
};
responses["hax://example.com/redirected"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><body>hello!</body></html>"},
};
engine::Engine e{std::make_unique<FakeProtocolHandler>(std::move(responses))};
auto page = e.navigate(uri::Uri::parse("hax://example.com").value()).value();
expect_eq(page->response.err, protocol::Error::Ok);
expect_eq(page->response.err, protocol::ErrorCode::Ok);
expect_eq(page->uri.uri, "hax://example.com/redirected");
 
auto const &body = std::get<dom::Element>(page->dom.html().children.at(1));
@@ -367,60 +367,60 @@ int main() {
etest::test("redirect not providing Location header", [] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 301},
};
engine::Engine e{std::make_unique<FakeProtocolHandler>(std::move(responses))};
expect_eq(e.navigate(uri::Uri::parse("hax://example.com").value()).error().response.err,
protocol::Error::InvalidResponse);
protocol::ErrorCode::InvalidResponse);
});
 
etest::test("redirect, style", [] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><head>"
"<link rel=stylesheet href=hello.css />"
"</head></html>"},
};
responses["hax://example.com/hello.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 301},
.headers = {{"Location", "hax://example.com/redirected.css"}},
};
responses["hax://example.com/redirected.css"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"p { color: green; }"},
};
engine::Engine e{std::make_unique<FakeProtocolHandler>(std::move(responses))};
auto page = e.navigate(uri::Uri::parse("hax://example.com").value()).value();
expect_eq(page->response.err, protocol::Error::Ok);
expect_eq(page->response.err, protocol::ErrorCode::Ok);
expect(contains(page->stylesheet.rules, {.selectors{"p"}, .declarations{{css::PropertyId::Color, "green"}}}));
});
 
etest::test("redirect loop", [] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 301},
.headers = {{"Location", "hax://example.com"}},
};
engine::Engine e{std::make_unique<FakeProtocolHandler>(std::move(responses))};
expect_eq(e.navigate(uri::Uri::parse("hax://example.com").value()).error().response.err, //
protocol::Error::RedirectLimit);
protocol::ErrorCode::RedirectLimit);
});
 
etest::test("load", [] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 301},
.headers = {{"Location", "hax://example.com/redirected"}},
};
responses["hax://example.com/redirected"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{"<html><body>hello!</body></html>"},
};
@@ -440,13 +440,13 @@ int main() {
etest::test("bad uri in redirect", [] {
std::map<std::string, Response> responses;
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 301},
.headers = {{"Location", ""}},
};
engine::Engine e{std::make_unique<FakeProtocolHandler>(responses)};
auto res = e.navigate(uri::Uri::parse("hax://example.com").value());
expect_eq(res.error().response.err, protocol::Error::InvalidResponse);
expect_eq(res.error().response.err, protocol::ErrorCode::InvalidResponse);
});
 
etest::test("bad uri in style href", [] {
@@ -455,13 +455,13 @@ int main() {
body += std::string(1025, 'a');
body += " /></head></html>";
responses["hax://example.com"s] = Response{
.err = Error::Ok,
.err = ErrorCode::Ok,
.status_line = {.status_code = 200},
.body{std::move(body)},
};
engine::Engine e{std::make_unique<FakeProtocolHandler>(std::move(responses))};
auto page = e.navigate(uri::Uri::parse("hax://example.com").value()).value();
expect_eq(page->response.err, protocol::Error::Ok);
expect_eq(page->response.err, protocol::ErrorCode::Ok);
});
 
return etest::run_all_tests();
 
protocol/file_handler.cpp added: 116, removed: 116, total 0
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2022 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2024 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021 Mikael Larsson <c.mikael.larsson@gmail.com>
//
// SPDX-License-Identifier: BSD-2-Clause
@@ -20,18 +20,18 @@ namespace protocol {
Response FileHandler::handle(uri::Uri const &uri) {
auto path = std::filesystem::path(uri.path);
if (!exists(path)) {
return {Error::Unresolved};
return {ErrorCode::Unresolved};
}
 
if (!is_regular_file(path)) {
return {Error::InvalidResponse};
return {ErrorCode::InvalidResponse};
}
 
auto file = std::ifstream(path, std::ios::in | std::ios::binary);
auto size = file_size(path);
auto content = std::string(size, '\0');
file.read(content.data(), size);
return {Error::Ok, {}, {}, std::move(content)};
return {ErrorCode::Ok, {}, {}, std::move(content)};
}
 
} // namespace protocol
 
protocol/file_handler_test.cpp added: 116, removed: 116, total 0
@@ -63,7 +63,7 @@ int main() {
etest::test("uri pointing to non-existent file", [] {
protocol::FileHandler handler;
auto res = handler.handle(uri::Uri::parse("file:///this/file/does/definitely/not/exist.hastur").value());
expect_eq(res, protocol::Response{protocol::Error::Unresolved});
expect_eq(res, protocol::Response{protocol::ErrorCode::Unresolved});
});
 
etest::test("uri pointing to a folder", [] {
@@ -71,7 +71,7 @@ int main() {
 
protocol::FileHandler handler;
auto res = handler.handle(uri::Uri::parse(fmt::format("file://{}", tmp_dir.generic_string())).value());
expect_eq(res, protocol::Response{protocol::Error::InvalidResponse});
expect_eq(res, protocol::Response{protocol::ErrorCode::InvalidResponse});
});
 
etest::test("uri pointing to a regular file", [] {
@@ -84,7 +84,7 @@ int main() {
 
protocol::FileHandler handler;
auto res = handler.handle(uri::Uri::parse(fmt::format("file://{}", tmp_file->path().generic_string())).value());
expect_eq(res, protocol::Response{protocol::Error::Ok, {}, {}, "hello!"});
expect_eq(res, protocol::Response{protocol::ErrorCode::Ok, {}, {}, "hello!"});
});
 
return etest::run_all_tests();
 
protocol/http.h added: 116, removed: 116, total 0
@@ -27,35 +27,35 @@ public:
using namespace std::string_view_literals;
 
if (!socket.connect(uri.authority.host, Http::use_port(uri) ? uri.authority.port : uri.scheme)) {
return {Error::Unresolved};
return {ErrorCode::Unresolved};
}
 
socket.write(Http::create_get_request(uri, std::move(user_agent)));
auto data = socket.read_until("\r\n"sv);
if (data.empty()) {
return {Error::InvalidResponse};
return {ErrorCode::InvalidResponse};
}
 
auto status_line = Http::parse_status_line(data.substr(0, data.size() - 2));
if (!status_line) {
return {Error::InvalidResponse};
return {ErrorCode::InvalidResponse};
}
 
data = socket.read_until("\r\n\r\n"sv);
if (data.empty()) {
return {Error::InvalidResponse, std::move(*status_line)};
return {ErrorCode::InvalidResponse, std::move(*status_line)};
}
 
auto headers = Http::parse_headers(data.substr(0, data.size() - 4));
if (headers.size() == 0) {
return {Error::InvalidResponse, std::move(*status_line)};
return {ErrorCode::InvalidResponse, std::move(*status_line)};
}
 
auto encoding = headers.get("transfer-encoding"sv);
if (encoding == "chunked"sv) {
auto body = Http::get_chunked_body(socket);
if (!body) {
return {Error::InvalidResponse, std::move(*status_line)};
return {ErrorCode::InvalidResponse, std::move(*status_line)};
}
 
data = *body;
@@ -63,7 +63,7 @@ public:
data = socket.read_all();
}
 
return {Error::Ok, std::move(*status_line), std::move(headers), std::move(data)};
return {ErrorCode::Ok, std::move(*status_line), std::move(headers), std::move(data)};
}
 
private:
 
protocol/http_test.cpp added: 116, removed: 116, total 0
@@ -228,7 +228,7 @@ int main() {
 
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
 
expect_eq(response.err, protocol::Error::InvalidResponse);
expect_eq(response.err, protocol::ErrorCode::InvalidResponse);
});
 
etest::test("transfer-encoding chunked, no separator between chunk", [] {
@@ -238,7 +238,7 @@ int main() {
 
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
 
expect_eq(response.err, protocol::Error::InvalidResponse);
expect_eq(response.err, protocol::ErrorCode::InvalidResponse);
});
 
etest::test("transfer-encoding chunked, chunk too short", [] {
@@ -248,7 +248,7 @@ int main() {
 
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
 
expect_eq(response.err, protocol::Error::InvalidResponse);
expect_eq(response.err, protocol::ErrorCode::InvalidResponse);
});
 
etest::test("transfer-encoding chunked, chunk too long", [] {
@@ -258,7 +258,7 @@ int main() {
 
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
 
expect_eq(response.err, protocol::Error::InvalidResponse);
expect_eq(response.err, protocol::ErrorCode::InvalidResponse);
});
 
etest::test("404 no headers no body", [] {
@@ -275,26 +275,26 @@ int main() {
etest::test("connect failure", [] {
FakeSocket socket{.connect_result = false};
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
expect_eq(response, protocol::Response{.err = protocol::Error::Unresolved});
expect_eq(response, protocol::Response{.err = protocol::ErrorCode::Unresolved});
});
 
etest::test("empty response", [] {
FakeSocket socket{};
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
expect_eq(response, protocol::Response{.err = protocol::Error::InvalidResponse});
expect_eq(response, protocol::Response{.err = protocol::ErrorCode::InvalidResponse});
});
 
etest::test("empty status line", [] {
FakeSocket socket{.read_data = "\r\n"};
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
expect_eq(response, protocol::Response{.err = protocol::Error::InvalidResponse});
expect_eq(response, protocol::Response{.err = protocol::ErrorCode::InvalidResponse});
});
 
etest::test("no headers", [] {
FakeSocket socket{.read_data = "HTTP/1.1 200 OK\r\n \r\n\r\n"};
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
expect_eq(response,
protocol::Response{.err = protocol::Error::InvalidResponse, .status_line{"HTTP/1.1", 200, "OK"}});
protocol::Response{.err = protocol::ErrorCode::InvalidResponse, .status_line{"HTTP/1.1", 200, "OK"}});
});
 
etest::test("mixed valid and invalid headers", [] {
@@ -302,7 +302,7 @@ int main() {
auto response = protocol::Http::get(socket, create_uri(), std::nullopt);
expect_eq(response,
protocol::Response{
.err = protocol::Error::Ok,
.err = protocol::ErrorCode::Ok,
.status_line{"HTTP/1.1", 200, "OK"},
.headers{{"one", "1"}, {"two", "2"}},
});
 
protocol/multi_protocol_handler.h added: 116, removed: 116, total 0
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -27,7 +27,7 @@ public:
return it->second->handle(uri);
}
 
return {Error::Unhandled};
return {ErrorCode::Unhandled};
}
 
private:
 
protocol/multi_protocol_handler_test.cpp added: 116, removed: 116, total 0
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2022-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -32,10 +32,10 @@ private:
int main() {
etest::test("added protocols are handled", [] {
MultiProtocolHandler handler;
expect_eq(handler.handle(uri::Uri{.scheme = "hax"}).err, protocol::Error::Unhandled);
expect_eq(handler.handle(uri::Uri{.scheme = "hax"}).err, protocol::ErrorCode::Unhandled);
 
handler.add("hax", std::make_unique<FakeProtocolHandler>(protocol::Response{protocol::Error::Ok}));
expect_eq(handler.handle(uri::Uri{.scheme = "hax"}).err, protocol::Error::Ok);
handler.add("hax", std::make_unique<FakeProtocolHandler>(protocol::Response{protocol::ErrorCode::Ok}));
expect_eq(handler.handle(uri::Uri{.scheme = "hax"}).err, protocol::ErrorCode::Ok);
});
 
return etest::run_all_tests();
 
protocol/response.cpp added: 116, removed: 116, total 0
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2024 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2021-2022 Mikael Larsson <c.mikael.larsson@gmail.com>
//
// SPDX-License-Identifier: BSD-2-Clause
@@ -17,17 +17,17 @@
 
namespace protocol {
 
std::string_view to_string(Error e) {
std::string_view to_string(ErrorCode e) {
switch (e) {
case Error::Ok:
case ErrorCode::Ok:
return "Ok";
case Error::Unresolved:
case ErrorCode::Unresolved:
return "Unresolved";
case Error::Unhandled:
case ErrorCode::Unhandled:
return "Unhandled";
case Error::InvalidResponse:
case ErrorCode::InvalidResponse:
return "InvalidResponse";
case Error::RedirectLimit:
case ErrorCode::RedirectLimit:
return "RedirectLimit";
}
return "Unknown";
 
protocol/response.h added: 116, removed: 116, total 0
@@ -17,7 +17,7 @@
 
namespace protocol {
 
enum class Error : std::uint8_t {
enum class ErrorCode : std::uint8_t {
Ok,
Unresolved,
Unhandled,
@@ -25,7 +25,7 @@ enum class Error : std::uint8_t {
RedirectLimit,
};
 
std::string_view to_string(Error);
std::string_view to_string(ErrorCode);
 
struct StatusLine {
std::string version;
@@ -56,7 +56,7 @@ private:
};
 
struct Response {
Error err{};
ErrorCode err{};
StatusLine status_line;
Headers headers;
std::string body;
 
protocol/response_test.cpp added: 116, removed: 116, total 0
@@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: 2021-2022 Mikael Larsson <c.mikael.larsson@gmail.com>
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -37,15 +37,15 @@ int main() {
expect_eq(headers.get("cOnTeNt-TyPe"sv).value(), "text/html");
});
 
etest::test("error, to_string", [] {
using protocol::Error;
expect_eq(to_string(Error::Ok), "Ok"sv);
expect_eq(to_string(Error::Unresolved), "Unresolved"sv);
expect_eq(to_string(Error::Unhandled), "Unhandled"sv);
expect_eq(to_string(Error::InvalidResponse), "InvalidResponse"sv);
expect_eq(to_string(Error::RedirectLimit), "RedirectLimit"sv);
etest::test("ErrorCode, to_string", [] {
using protocol::ErrorCode;
expect_eq(to_string(ErrorCode::Ok), "Ok"sv);
expect_eq(to_string(ErrorCode::Unresolved), "Unresolved"sv);
expect_eq(to_string(ErrorCode::Unhandled), "Unhandled"sv);
expect_eq(to_string(ErrorCode::InvalidResponse), "InvalidResponse"sv);
expect_eq(to_string(ErrorCode::RedirectLimit), "RedirectLimit"sv);
// NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
expect_eq(to_string(static_cast<Error>(std::underlying_type_t<Error>{20})), "Unknown"sv);
expect_eq(to_string(static_cast<ErrorCode>(std::underlying_type_t<ErrorCode>{20})), "Unknown"sv);
});
 
return etest::run_all_tests();