srctree

Robin Linden parent acc79680 13b72594
http: Use the util::Uri class for URIs

inlinesplit
browser/BUILD added: 38, removed: 27, total 11
@@ -18,6 +18,7 @@ cc_binary(
"//layout",
"//style",
"//tui",
"//util",
"@spdlog",
],
)
@@ -31,6 +32,7 @@ cc_binary(
"//http",
"//layout",
"//style",
"//util",
"@imgui",
"@imgui-sfml",
"@sfml//:graphics",
 
browser/gui.cpp added: 38, removed: 27, total 11
@@ -18,7 +18,7 @@ int main() {
window.setFramerateLimit(60);
ImGui::SFML::Init(window);
 
char url_buf[255]{"example.com"};
char url_buf[255]{"http://example.com"};
sf::Clock clock;
http::Response response{};
dom::Document dom{};
@@ -53,7 +53,12 @@ int main() {
ImGui::Begin("Navigation");
if (ImGui::InputText(
"Url", url_buf, sizeof(url_buf), ImGuiInputTextFlags_EnterReturnsTrue)) {
response = http::get(url_buf);
auto uri = util::Uri::parse(url_buf);
if (!uri) {
continue;
}
 
response = http::get(*uri);
dom_str.clear();
 
switch (response.err) {
 
browser/tui.cpp added: 38, removed: 27, total 11
@@ -10,15 +10,23 @@
 
#include <iostream>
 
namespace {
char const *const kDefaultUri = "http://www.example.com";
} // namespace
 
int main(int argc, char **argv) {
spdlog::cfg::load_env_levels();
 
const char *endpoint = argc > 1 ? argv[1] : "www.example.com";
auto uri = argc > 1 ? util::Uri::parse(argv[1]) : util::Uri::parse(kDefaultUri);
if (!uri) {
spdlog::error("Unable to parse uri from {}", argc > 1 ? argv[1] : kDefaultUri);
return 1;
}
 
spdlog::info("Fetching HTML from {}", endpoint);
auto response = http::get(endpoint);
spdlog::info("Fetching HTML from {}", uri->uri);
auto response = http::get(*uri);
if (response.err != http::Error::Ok) {
spdlog::error("Got error {} from {}", response.err, endpoint);
spdlog::error("Got error {} from {}", response.err, uri->uri);
return 1;
}
 
 
http/BUILD added: 38, removed: 27, total 11
@@ -6,6 +6,7 @@ cc_library(
hdrs = ["get.h"],
visibility = ["//visibility:public"],
deps = [
"//util",
"@asio",
"@fmt",
],
 
http/get.cpp added: 38, removed: 27, total 11
@@ -23,18 +23,11 @@ std::pair<std::string_view, std::string_view> split(std::string_view str, std::s
 
} // namespace
 
Response get(std::string_view url) {
auto [protocol, endpoint] = split(url, "://"sv);
if (endpoint.empty()) {
// No protocol included, so let's assume http for now.
endpoint = protocol;
protocol = "http"sv;
}
 
if (protocol == "http"sv) {
asio::ip::tcp::iostream stream(endpoint, protocol);
Response get(util::Uri const &uri) {
if (uri.scheme == "http"sv) {
asio::ip::tcp::iostream stream(uri.authority.host, "http"sv);
stream << "GET / HTTP/1.1\r\n";
stream << fmt::format("Host: {}\r\n", endpoint);
stream << fmt::format("Host: {}\r\n", uri.authority.host);
stream << "Accept: text/html\r\n";
stream << "Connection: close\r\n\r\n";
stream.flush();
@@ -47,14 +40,14 @@ Response get(std::string_view url) {
return {Error::Ok, std::string{header}, std::string{body}};
}
 
if (protocol == "https"sv) {
if (uri.scheme == "https"sv) {
asio::io_service svc;
asio::ssl::context ctx{asio::ssl::context::method::sslv23_client};
asio::ssl::stream<asio::ip::tcp::socket> ssock(svc, ctx);
asio::error_code ec;
 
asio::ip::tcp::resolver resolver{svc};
auto endpoints = resolver.resolve(endpoint, "https"sv, ec);
auto endpoints = resolver.resolve(uri.authority.host, "https"sv, ec);
if (ec) {
return {Error::Unresolved};
}
@@ -64,7 +57,7 @@ Response get(std::string_view url) {
 
std::stringstream ss;
ss << "GET / HTTP/1.1\r\n";
ss << fmt::format("Host: {}\r\n", endpoint);
ss << fmt::format("Host: {}\r\n", uri.authority.host);
ss << "Accept: text/html\r\n";
ss << "Connection: close\r\n\r\n";
asio::write(ssock, asio::buffer(ss.str()), ec);
 
http/get.h added: 38, removed: 27, total 11
@@ -1,6 +1,8 @@
#ifndef HTTP_GET_H_
#define HTTP_GET_H_
 
#include "util/uri.h"
 
#include <string>
#include <string_view>
 
@@ -18,7 +20,7 @@ struct Response {
std::string body;
};
 
Response get(std::string_view endpoint);
Response get(util::Uri const &uri);
 
} // namespace http