#include "request.h"
int main() {
- auto resp1 =
- http::async::send(http::Method::GET, http::RequestOpts{.domain_name = "example.com",
- .accept = "application/json"});
- // auto resp1 = http::sendreq(http::Method::POST, {.domain_name = "example.com", .body = "Hello,
- // World!"});
-
- std::cout << "Going to sleep" << std::endl;
- sleep(1);
- std::cout << "I woke up" << std::endl;
+ auto resp1 = http::async::send(http::Method::GET,
+ http::RequestOpts{.domain_name = "google.com", .query = "/prova"});
auto resp = resp1.get();
if (!resp.has_value()) {
} // namespace http
std::ostream &operator<<(std::ostream &os, const http::Status &status) {
+ using namespace http;
+
switch (status) {
- case http::Status::PARSE_ERROR:
- return os << "parse error";
- case http::Status::OK:
- return os << "ok";
- case http::Status::NOT_FOUND:
- return os << "not found";
+ case Status::PARSE_ERROR:
+ return os << (uint16_t)status << " - Parse Error";
+ case Status::CONTINUE:
+ return os << (uint16_t)status << " - Continue";
+ case Status::SWITCHING_PROTOCOLS:
+ return os << (uint16_t)status << " - Switching Protocols";
+ case Status::PROCESSING:
+ return os << (uint16_t)status << " - Processing";
+
+ case Status::OK:
+ return os << (uint16_t)status << " - OK";
+ case Status::CREATED:
+ return os << (uint16_t)status << " - Created";
+ case Status::ACCEPTED:
+ return os << (uint16_t)status << " - Accepted";
+ case Status::NON_AUTHORITATIVE_INFORMATION:
+ return os << (uint16_t)status << " - Non-Authoritative Information";
+ case Status::NO_CONTENT:
+ return os << (uint16_t)status << " - No Content";
+ case Status::PARTIAL_CONTENT:
+ return os << (uint16_t)status << " - Partial Content";
+ case Status::ALREADY_REPORTED:
+ return os << (uint16_t)status << " - Already Reported";
+ case Status::IM_USED:
+ return os << (uint16_t)status << " - IM Used";
+
+ case Status::MULTIPLE_CHOICES:
+ return os << (uint16_t)status << " - Multiple Choices";
+ case Status::MOVED_PERMANENTLY:
+ return os << (uint16_t)status << " - Moved Permanently";
+ case Status::FOUND:
+ return os << (uint16_t)status << " - Found";
+ case Status::SEE_OTHER:
+ return os << (uint16_t)status << " - See Other";
+ case Status::NOT_MODIFIED:
+ return os << (uint16_t)status << " - Not Modified";
+ case Status::USE_PROXY:
+ return os << (uint16_t)status << " - Use Proxy";
+ case Status::UNUSED:
+ return os << (uint16_t)status << " - Unused";
+ case Status::TEMPORARY_REDIRECT:
+ return os << (uint16_t)status << " - Temporary Redirect";
+ case Status::PERMANENT_REDIRECT:
+ return os << (uint16_t)status << " - Permanent Redirect";
+
+ case Status::BAD_REQUEST:
+ return os << (uint16_t)status << " - Bad Request";
+ case Status::UNAUTHORIZED:
+ return os << (uint16_t)status << " - Unauthorized";
+ case Status::PAYMENT_REQUIRED:
+ return os << (uint16_t)status << " - Payment Required";
+ case Status::FORBIDDEN:
+ return os << (uint16_t)status << " - Forbidden";
+ case Status::NOT_FOUND:
+ return os << (uint16_t)status << " - Not Found";
+ case Status::METHOD_NOT_ALLOWED:
+ return os << (uint16_t)status << " - Method Not Allowed";
+ case Status::NOT_ACCEPTABLE:
+ return os << (uint16_t)status << " - Not Acceptable";
+ case Status::PROXY_AUTHENTICATION_REQUIRED:
+ return os << (uint16_t)status << " - Proxy Authentication Required";
+ case Status::REQUEST_TIMEOUT:
+ return os << (uint16_t)status << " - Request Timeout";
+ case Status::CONFLICT:
+ return os << (uint16_t)status << " - Conflict";
+ case Status::GONE:
+ return os << (uint16_t)status << " - Gone";
+ case Status::LENGTH_REQUIRED:
+ return os << (uint16_t)status << " - Length Required";
+ case Status::PRECONDITION_FAILED:
+ return os << (uint16_t)status << " - Precondition Failed";
+ case Status::PAYLOAD_TOO_LARGE:
+ return os << (uint16_t)status << " - Payload Too Large";
+ case Status::URI_TOO_LONG:
+ return os << (uint16_t)status << " - URI Too Long";
+ case Status::UNSUPPORTED_MEDIA_TYPE:
+ return os << (uint16_t)status << " - Unsupported Media Type";
+ case Status::RANGE_NOT_SATISFIABLE:
+ return os << (uint16_t)status << " - Range Not Satisfiable";
+ case Status::EXPECTATION_FAILED:
+ return os << (uint16_t)status << " - Expectation Failed";
+ case Status::IM_A_TEAPOT:
+ return os << (uint16_t)status << " - I'm a teapot";
+ case Status::MISDIRECTED_REQUEST:
+ return os << (uint16_t)status << " - Misdirected Request";
+ case Status::UNPROCESSABLE_CONTENT:
+ return os << (uint16_t)status << " - Unprocessable Content";
+ case Status::LOCKED:
+ return os << (uint16_t)status << " - Locked";
+ case Status::FAILED_DEPENDENCY:
+ return os << (uint16_t)status << " - Failed Dependency";
+ case Status::TOO_EARLY:
+ return os << (uint16_t)status << " - Too Early";
+ case Status::UPGRADE_REQUIRED:
+ return os << (uint16_t)status << " - Upgrade Required";
+ case Status::PRECONDITION_REQUIRED:
+ return os << (uint16_t)status << " - Precondition Required";
+ case Status::TOO_MANY_REQUESTS:
+ return os << (uint16_t)status << " - Too Many Requests";
+ case Status::REQUEST_HEADER_FIELDS_TOO_LARGE:
+ return os << (uint16_t)status << " - Request Header Fields Too Large";
+ case Status::UNAVAILABLE_FOR_LEGAL_REASONS:
+ return os << (uint16_t)status << " - Unavailable For Legal Reasons";
+
+ case Status::INTERNAL_SERVER_ERROR:
+ return os << (uint16_t)status << " - Internal Server Error";
+ case Status::NOT_IMPLEMENTED:
+ return os << (uint16_t)status << " - Not Implemented";
+ case Status::BAD_GATEWAY:
+ return os << (uint16_t)status << " - Bad Gateway";
+ case Status::SERVICE_UNAVAILABLE:
+ return os << (uint16_t)status << " - Service Unavailable";
+ case Status::GATEWAY_TIMEOUT:
+ return os << (uint16_t)status << " - Gateway Timeout";
+ case Status::HTTP_VERSION_NOT_SUPPORTED:
+ return os << (uint16_t)status << " - HTTP Version Not Supported";
+ case Status::VARIANT_ALSO_NEGOTIATES:
+ return os << (uint16_t)status << " - Variant Also Negotiates";
+ case Status::INSUFFICIENT_STORAGE:
+ return os << (uint16_t)status << " - Insufficient Storage";
+ case Status::LOOP_DETECTED:
+ return os << (uint16_t)status << " - Loop Detected";
+ case Status::NOT_EXTENDED:
+ return os << (uint16_t)status << " - Not Extended";
+ case Status::NETWORK_AUTHENTICATION_REQUIRED:
+ return os << (uint16_t)status << " - Network Authentication Required";
+
default:
- return os;
+ return os << (uint16_t)status << " - Unknown Status";
}
}
namespace http {
enum class Status {
- PARSE_ERROR,
+ PARSE_ERROR = 0,
+ CONTINUE = 100,
+ SWITCHING_PROTOCOLS = 101,
+ PROCESSING = 102,
+
OK = 200,
- NOT_FOUND = 404,
+ CREATED,
+ ACCEPTED,
+ NON_AUTHORITATIVE_INFORMATION,
+ NO_CONTENT,
+ PARTIAL_CONTENT,
+ ALREADY_REPORTED,
+ IM_USED,
+
+ MULTIPLE_CHOICES = 300,
+ MOVED_PERMANENTLY,
+ FOUND,
+ SEE_OTHER,
+ NOT_MODIFIED,
+ USE_PROXY,
+ UNUSED,
+ TEMPORARY_REDIRECT,
+ PERMANENT_REDIRECT,
+
+ BAD_REQUEST = 400,
+ UNAUTHORIZED,
+ PAYMENT_REQUIRED,
+ FORBIDDEN,
+ NOT_FOUND,
+ METHOD_NOT_ALLOWED,
+ NOT_ACCEPTABLE,
+ PROXY_AUTHENTICATION_REQUIRED,
+ REQUEST_TIMEOUT,
+ CONFLICT,
+ GONE,
+ LENGTH_REQUIRED,
+ PRECONDITION_FAILED,
+ PAYLOAD_TOO_LARGE,
+ URI_TOO_LONG,
+ UNSUPPORTED_MEDIA_TYPE,
+ RANGE_NOT_SATISFIABLE,
+ EXPECTATION_FAILED,
+ IM_A_TEAPOT,
+ MISDIRECTED_REQUEST = 421,
+ UNPROCESSABLE_CONTENT,
+ LOCKED,
+ FAILED_DEPENDENCY,
+ TOO_EARLY,
+ UPGRADE_REQUIRED,
+ PRECONDITION_REQUIRED = 428,
+ TOO_MANY_REQUESTS,
+ REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
+ UNAVAILABLE_FOR_LEGAL_REASONS = 451,
+
+ INTERNAL_SERVER_ERROR = 500,
+ NOT_IMPLEMENTED,
+ BAD_GATEWAY,
+ SERVICE_UNAVAILABLE,
+ GATEWAY_TIMEOUT,
+ HTTP_VERSION_NOT_SUPPORTED,
+ VARIANT_ALSO_NEGOTIATES,
+ INSUFFICIENT_STORAGE,
+ LOOP_DETECTED,
+ NOT_EXTENDED,
+ NETWORK_AUTHENTICATION_REQUIRED,
};
static std::unordered_map<uint16_t, Status> status_map = {
+ {100, Status::CONTINUE},
+ {101, Status::SWITCHING_PROTOCOLS},
+ {102, Status::PROCESSING},
+
{200, Status::OK},
+ {201, Status::CREATED},
+ {202, Status::ACCEPTED},
+ {203, Status::NON_AUTHORITATIVE_INFORMATION},
+ {204, Status::NO_CONTENT},
+ {205, Status::PARTIAL_CONTENT},
+ {208, Status::ALREADY_REPORTED},
+ {226, Status::IM_USED},
+
+ {300, Status::MULTIPLE_CHOICES},
+ {301, Status::MOVED_PERMANENTLY},
+ {302, Status::FOUND},
+ {303, Status::SEE_OTHER},
+ {304, Status::NOT_MODIFIED},
+ {305, Status::USE_PROXY},
+ {306, Status::UNUSED},
+ {307, Status::TEMPORARY_REDIRECT},
+ {308, Status::PERMANENT_REDIRECT},
+
+ {400, Status::BAD_REQUEST},
+ {401, Status::UNAUTHORIZED},
+ {402, Status::PAYMENT_REQUIRED},
+ {403, Status::FORBIDDEN},
{404, Status::NOT_FOUND},
+ {405, Status::METHOD_NOT_ALLOWED},
+ {406, Status::NOT_ACCEPTABLE},
+ {407, Status::PROXY_AUTHENTICATION_REQUIRED},
+ {408, Status::REQUEST_TIMEOUT},
+ {409, Status::CONFLICT},
+ {410, Status::GONE},
+ {411, Status::LENGTH_REQUIRED},
+ {412, Status::PRECONDITION_FAILED},
+ {413, Status::PAYLOAD_TOO_LARGE},
+ {414, Status::URI_TOO_LONG},
+ {415, Status::UNSUPPORTED_MEDIA_TYPE},
+ {416, Status::RANGE_NOT_SATISFIABLE},
+ {417, Status::EXPECTATION_FAILED},
+ {418, Status::IM_A_TEAPOT},
+ {421, Status::MISDIRECTED_REQUEST},
+ {422, Status::UNPROCESSABLE_CONTENT},
+ {423, Status::LOCKED},
+ {424, Status::FAILED_DEPENDENCY},
+ {425, Status::TOO_EARLY},
+ {426, Status::UPGRADE_REQUIRED},
+ {428, Status::PRECONDITION_REQUIRED},
+ {429, Status::TOO_MANY_REQUESTS},
+ {431, Status::REQUEST_HEADER_FIELDS_TOO_LARGE},
+ {451, Status::UNAVAILABLE_FOR_LEGAL_REASONS},
+
+ {500, Status::INTERNAL_SERVER_ERROR},
+ {501, Status::NOT_IMPLEMENTED},
+ {502, Status::BAD_GATEWAY},
+ {503, Status::SERVICE_UNAVAILABLE},
+ {504, Status::GATEWAY_TIMEOUT},
+ {505, Status::HTTP_VERSION_NOT_SUPPORTED},
+ {506, Status::VARIANT_ALSO_NEGOTIATES},
+ {507, Status::INSUFFICIENT_STORAGE},
+ {508, Status::LOOP_DETECTED},
+ {510, Status::NOT_EXTENDED},
+ {511, Status::NETWORK_AUTHENTICATION_REQUIRED},
};
struct Response {
+#include <netdb.h>
+#include <unistd.h>
+
#include <cstdint>
#include <expected>
#include <iostream>
#include <sstream>
#include <unordered_map>
-#include <netdb.h>
-#include <unistd.h>
-
#include "error.h"
#include "http.h"
#include "request.h"
static std::unordered_map<std::string, struct addrinfo> ip_map;
namespace http {
- std::expected<int8_t, Error> connect(const std::string_view &domain_name,
- const uint16_t port) {
+ std::expected<int8_t, Error> connect(const std::string_view &domain_name, const uint16_t port) {
struct addrinfo hints = {}, *addr_list;
hints.ai_family = AF_UNSPEC; // Either IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // TCP only
return Response::build(maybe_response.value());
}
- namespace async {
- std::future<std::expected<Response, Error>> send(Method method, const RequestOpts &req) {
- return std::async(::http::send, method, req);
- }
- }
-
std::string build_request(Method method, const RequestOpts &req) {
std::stringstream ss;
ss << method << " " << req.query << " HTTP/" << (int)req.version.major << "."
return ss.str();
}
+
+ namespace async {
+ std::future<std::expected<Response, Error>> send(Method method, const RequestOpts &req) {
+ return std::async(::http::send, method, req);
+ }
+ } // namespace async
} // namespace http