diff --git a/include/opendht/http.h b/include/opendht/http.h index 92527fb7..98ebb0bf 100644 --- a/include/opendht/http.h +++ b/include/opendht/http.h @@ -25,8 +25,8 @@ // some libraries may try to redefine snprintf // but restinio will use it in std namespace #ifdef _MSC_VER -# undef snprintf -# define snprintf snprintf +#undef snprintf +#define snprintf snprintf #endif #include @@ -47,7 +47,7 @@ namespace restinio { namespace impl { class tls_socket_t; } -} +} // namespace restinio namespace dht { namespace log { @@ -62,8 +62,7 @@ namespace http { using HandlerCb = std::function; using BytesHandlerCb = std::function; -using ConnectHandlerCb = std::function; +using ConnectHandlerCb = std::function; using ssl_socket_t = restinio::impl::tls_socket_t; using socket_t = asio::ip::tcp::socket; @@ -75,13 +74,13 @@ public: Url(std::string_view url); std::string url; std::string protocol {"http"}; - std::string user; - std::string password; - std::string host; - std::string service; + std::string_view user; + std::string_view password; + std::string_view host; + std::string_view service; std::string target; - std::string query; - std::string fragment; + std::string_view query; + std::string_view fragment; std::string toString() const; }; @@ -90,11 +89,13 @@ class OPENDHT_PUBLIC Connection : public std::enable_shared_from_this l = {}); - Connection(asio::io_context& ctx, std::shared_ptr server_ca, - const dht::crypto::Identity& identity, std::shared_ptr l = {}); + Connection(asio::io_context& ctx, + std::shared_ptr server_ca, + const dht::crypto::Identity& identity, + std::shared_ptr l = {}); ~Connection(); - inline unsigned int id() const { return id_; }; + inline unsigned int id() const { return id_; }; bool is_open() const; bool is_ssl() const; void checkOcsp(bool check = true) { checkOcsp_ = check; } @@ -124,10 +125,10 @@ public: void close(); private: - template - T wrapCallback(T cb) const { - return [t=shared_from_this(),cb=std::move(cb)](auto ...params) { + T wrapCallback(T cb) const + { + return [t = shared_from_this(), cb = std::move(cb)](auto... params) { cb(params...); }; } @@ -161,35 +162,38 @@ private: class OPENDHT_PUBLIC Resolver { public: - using ResolverCb = std::function& endpoints)>; + using ResolverCb + = std::function& endpoints)>; Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr logger = {}); - Resolver(asio::io_context& ctx, const std::string& host, const std::string& service, - const bool ssl = false, std::shared_ptr logger = {}); + Resolver(asio::io_context& ctx, + std::string_view host, + std::string_view service, + const bool ssl = false, + std::shared_ptr logger = {}); // use already resolved endpoints with classes using this resolver - Resolver(asio::io_context& ctx, std::vector endpoints, - const bool ssl = false, std::shared_ptr logger = {}); - Resolver(asio::io_context& ctx, const std::string& url, std::vector endpoints, - std::shared_ptr logger = {}); + Resolver(asio::io_context& ctx, + std::vector endpoints, + const bool ssl = false, + std::shared_ptr logger = {}); + Resolver(asio::io_context& ctx, + const std::string& url, + std::vector endpoints, + std::shared_ptr logger = {}); ~Resolver(); - inline const Url& get_url() const { - return url_; - } + inline const Url& get_url() const { return url_; } void add_callback(ResolverCb cb, sa_family_t family = AF_UNSPEC); - std::shared_ptr getLogger() const { - return logger_; - } + std::shared_ptr getLogger() const { return logger_; } void cancel(); private: - void resolve(const std::string& host, const std::string& service); + void resolve(std::string_view host, std::string_view service); mutable std::mutex mutex_; @@ -219,13 +223,7 @@ struct Response class OPENDHT_PUBLIC Request : public std::enable_shared_from_this { public: - enum class State { - CREATED, - SENDING, - HEADER_RECEIVED, - RECEIVING, - DONE - }; + enum class State { CREATED, SENDING, HEADER_RECEIVED, RECEIVING, DONE }; using OnStatusCb = std::function; using OnDataCb = std::function; using OnStateChangeCb = std::function; @@ -233,46 +231,51 @@ public: using OnDoneCb = std::function; // resolves implicitly - Request(asio::io_context& ctx, const std::string& url, const Json::Value& json, OnJsonCb jsoncb, - std::shared_ptr logger = {}); - Request(asio::io_context& ctx, const std::string& url, OnJsonCb jsoncb, + Request(asio::io_context& ctx, + const std::string& url, + const Json::Value& json, + OnJsonCb jsoncb, std::shared_ptr logger = {}); + Request(asio::io_context& ctx, const std::string& url, OnJsonCb jsoncb, std::shared_ptr logger = {}); Request(asio::io_context& ctx, const std::string& url, std::shared_ptr logger = {}); - Request(asio::io_context& ctx, const std::string& host, const std::string& service, - const bool ssl = false, std::shared_ptr logger = {}); + Request(asio::io_context& ctx, + std::string_view host, + std::string_view service, + const bool ssl = false, + std::shared_ptr logger = {}); Request(asio::io_context& ctx, const std::string& url, OnDoneCb onDone, std::shared_ptr logger = {}); // user defined resolver Request(asio::io_context& ctx, std::shared_ptr resolver, sa_family_t family = AF_UNSPEC); - Request(asio::io_context& ctx, std::shared_ptr resolver, const std::string& target, sa_family_t family = AF_UNSPEC); + Request(asio::io_context& ctx, + std::shared_ptr resolver, + const std::string& target, + sa_family_t family = AF_UNSPEC); // user defined resolved endpoints - Request(asio::io_context& ctx, std::vector&& endpoints, - const bool ssl = false, std::shared_ptr logger = {}); + Request(asio::io_context& ctx, + std::vector&& endpoints, + const bool ssl = false, + std::shared_ptr logger = {}); ~Request(); - inline unsigned int id() const { return id_; }; + inline unsigned int id() const { return id_; }; void set_connection(std::shared_ptr connection); std::shared_ptr get_connection() const; - inline const Url& get_url() const { - return resolver_->get_url(); - }; + inline const Url& get_url() const { return resolver_->get_url(); }; - void timeout(const std::chrono::seconds& timeout, HandlerCb cb = {}) { + void timeout(const std::chrono::seconds& timeout, HandlerCb cb = {}) + { timeout_ = timeout; timeoutCb_ = cb; } /** The previous request in case of redirect following */ - std::shared_ptr getPrevious() const { - return prev_.lock(); - } + std::shared_ptr getPrevious() const { return prev_.lock(); } - inline std::string& to_string() { - return request_; - } + inline std::string& to_string() { return request_; } void set_certificate_authority(std::shared_ptr certificate); void set_identity(const dht::crypto::Identity& identity); @@ -287,6 +290,7 @@ public: void set_header_field(restinio::http_field_t field, std::string value); void set_connection_type(restinio::http_connection_header_t connection); void set_body(std::string body); + void set_body(const uint8_t* data, size_t length); void set_auth(const std::string& username, const std::string& password); void add_on_status_callback(OnStatusCb cb); @@ -308,7 +312,8 @@ public: private: using OnCompleteCb = std::function; - struct Callbacks { + struct Callbacks + { OnStatusCb on_status; OnDataCb on_header_field; OnDataCb on_header_value; @@ -383,4 +388,3 @@ private: } // namespace http } // namespace dht - diff --git a/include/opendht/network_utils.h b/include/opendht/network_utils.h index c8d840f9..573a58c9 100644 --- a/include/opendht/network_utils.h +++ b/include/opendht/network_utils.h @@ -52,14 +52,16 @@ bool setNonblocking(int fd, bool nonblocking = true); #ifdef _WIN32 void udpPipe(int fds[2]); #endif -struct ReceivedPacket { +struct ReceivedPacket +{ Blob data; SockAddr from; time_point received; }; using PacketList = std::list; -class OPENDHT_PUBLIC DatagramSocket { +class OPENDHT_PUBLIC DatagramSocket +{ public: /** A function that takes a list of new received packets and * optionally returns consumed packets for recycling. @@ -69,7 +71,8 @@ public: virtual int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) = 0; - inline void setOnReceive(OnReceive&& cb) { + inline void setOnReceive(OnReceive&& cb) + { std::lock_guard lk(lock); rx_callback = std::move(cb); } @@ -77,11 +80,13 @@ public: virtual bool hasIPv4() const = 0; virtual bool hasIPv6() const = 0; - SockAddr getBound(sa_family_t family = AF_UNSPEC) const { + SockAddr getBound(sa_family_t family = AF_UNSPEC) const + { std::lock_guard lk(lock); return getBoundRef(family); } - in_port_t getPort(sa_family_t family = AF_UNSPEC) const { + in_port_t getPort(sa_family_t family = AF_UNSPEC) const + { std::lock_guard lk(lock); return getBoundRef(family).getPort(); } @@ -89,14 +94,16 @@ public: virtual const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const = 0; /** Virtual resolver mothod allows to implement custom resolver */ - virtual std::vector resolve(const std::string& host, const std::string& service = {}) { + virtual std::vector resolve(const std::string& host, const std::string& service = {}) + { return SockAddr::resolve(host, service); } virtual void stop() = 0; -protected: - PacketList getNewPacket() { +protected: + PacketList getNewPacket() + { PacketList pkts; if (toRecycle_.empty()) { pkts.emplace_back(); @@ -108,7 +115,8 @@ protected: return pkts; } - inline void onReceived(PacketList&& packets) { + inline void onReceived(PacketList&& packets) + { std::lock_guard lk(lock); if (rx_callback) { auto r = rx_callback(std::move(packets)); @@ -116,14 +124,17 @@ protected: toRecycle_.splice(toRecycle_.end(), std::move(r)); } } + protected: mutable std::mutex lock; + private: OnReceive rx_callback; PacketList toRecycle_; }; -class OPENDHT_PUBLIC UdpSocket : public DatagramSocket { +class OPENDHT_PUBLIC UdpSocket : public DatagramSocket +{ public: UdpSocket(in_port_t port, const std::shared_ptr& l = {}); UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const std::shared_ptr& l = {}); @@ -131,20 +142,24 @@ public: int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) override; - const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const override { + const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const override + { return (family == AF_INET6) ? bound6 : bound4; } - bool hasIPv4() const override { + bool hasIPv4() const override + { std::lock_guard lk(lock); return s4 != -1; } - bool hasIPv6() const override { + bool hasIPv6() const override + { std::lock_guard lk(lock); return s6 != -1; } void stop() override; + private: std::shared_ptr logger; int s4 {-1}; @@ -157,5 +172,5 @@ private: void openSockets(const SockAddr& bind4, const SockAddr& bind6); }; -} -} +} // namespace net +} // namespace dht diff --git a/include/opendht/utils.h b/include/opendht/utils.h index a593cf88..ce67a9f9 100644 --- a/include/opendht/utils.h +++ b/include/opendht/utils.h @@ -76,7 +76,7 @@ concat(Args&&... args) /** * Split "[host]:port" or "host:port" to pair<"host", "port">. */ -OPENDHT_PUBLIC std::pair splitPort(std::string_view s); +OPENDHT_PUBLIC std::pair splitPort(std::string_view s); class OPENDHT_PUBLIC DhtException : public std::runtime_error { diff --git a/src/base64.cpp b/src/base64.cpp index aa963561..76bb9601 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -16,31 +16,38 @@ */ #include "base64.h" +#include "utils.h" #include #include #include #include +#include + +namespace dht { + +using namespace std::literals; std::string base64_encode(const std::vector& str) { std::string buffer(simdutf::base64_length_from_binary(str.size()), '\0'); - simdutf::binary_to_base64((const char*)str.data(), str.size(), buffer.data()); + simdutf::binary_to_base64((const char*) str.data(), str.size(), buffer.data()); return buffer; } std::vector -base64_decode(const std::string& str) +base64_decode(std::string_view str) { std::vector buffer(simdutf::maximal_binary_length_from_base64(str.data(), str.size())); - simdutf::result r = simdutf::base64_to_binary(str.data(), str.size(), (char *)buffer.data()); - if(r.error) { - // Decoding error, return an empty vector - return std::vector(); + simdutf::result r = simdutf::base64_to_binary(str.data(), str.size(), (char*) buffer.data()); + if (r.error) { + throw std::invalid_argument(concat("Invalid base64 input: "sv, simdutf::error_to_string(r.error))); } else { - buffer.resize(r.count); // resize the buffer according to actual number of bytes + buffer.resize(r.count); } return buffer; } + +} // namespace dht diff --git a/src/base64.h b/src/base64.h index 80d04364..948f62a5 100644 --- a/src/base64.h +++ b/src/base64.h @@ -20,6 +20,8 @@ #include #include +namespace dht { + /** * Encode a buffer in base64. * @@ -33,4 +35,6 @@ std::string base64_encode(const std::vector& str); * @param str the input buffer * @return a base64-decoded buffer */ -std::vector base64_decode(const std::string& str); +std::vector base64_decode(std::string_view str); + +} // namespace dht \ No newline at end of file diff --git a/src/http.cpp b/src/http.cpp index 0ec36bea..f2817a88 100644 --- a/src/http.cpp +++ b/src/http.cpp @@ -48,17 +48,19 @@ namespace dht { namespace http { -constexpr const char HTTP_HEADER_CONTENT_TYPE_JSON[] = "application/json"; +using namespace std::string_view_literals; + +constexpr std::string_view HTTP_HEADER_CONTENT_TYPE_JSON {"application/json"sv}; +constexpr std::string_view HTTP_PROTOCOL {"http://"sv}; +constexpr std::string_view HTTPS_PROTOCOL {"https://"sv}; +constexpr std::string_view ORIGIN_PROTOCOL {"//"sv}; constexpr const char HTTP_HEADER_DELIM[] = "\r\n\r\n"; -constexpr const char HTTP_PROTOCOL[] = "http://"; -constexpr const char HTTPS_PROTOCOL[] = "https://"; -constexpr const char ORIGIN_PROTOCOL[] = "//"; constexpr unsigned MAX_REDIRECTS {5}; Url::Url(std::string_view url_str) : url(url_str) { - std::string_view u = url_str; + std::string_view u = url; if (u.empty()) return; @@ -73,30 +75,33 @@ Url::Url(std::string_view url_str) // Fragment auto frag_pos = u.find('#'); if (frag_pos != std::string_view::npos) { - fragment = std::string(u.substr(frag_pos)); + fragment = u.substr(frag_pos); u.remove_suffix(u.size() - frag_pos); } // Query auto query_pos = u.find('?'); if (query_pos != std::string_view::npos) { - query = std::string(u.substr(query_pos + 1)); + query = u.substr(query_pos + 1); u.remove_suffix(u.size() - query_pos); } // Path + std::string_view target_view; auto path_pos = u.find('/'); if (path_pos != std::string_view::npos) { - target = std::string(u.substr(path_pos)); + target_view = u.substr(path_pos); u.remove_suffix(u.size() - path_pos); } - if (target.empty()) { - if (!query.empty()) - target = "/?" + query; + if (!query.empty()) { + if (target_view.empty()) { + target = concat("/?"sv, query); + } else { + target = concat(target_view, "?"sv, query); + } } else { - if (!query.empty()) - target += "?" + query; + target = std::string(target_view); } // Authority @@ -106,10 +111,10 @@ Url::Url(std::string_view url_str) u.remove_prefix(at_pos + 1); auto colon_pos = userinfo.find(':'); if (colon_pos != std::string_view::npos) { - user = std::string(userinfo.substr(0, colon_pos)); - password = std::string(userinfo.substr(colon_pos + 1)); + user = userinfo.substr(0, colon_pos); + password = userinfo.substr(colon_pos + 1); } else { - user = std::string(userinfo); + user = userinfo; } } @@ -845,8 +850,8 @@ Resolver::Resolver(asio::io_context& ctx, const std::string& url, std::shared_pt } Resolver::Resolver(asio::io_context& ctx, - const std::string& host, - const std::string& service, + std::string_view host, + std::string_view service, const bool ssl, std::shared_ptr logger) : resolver_(ctx) @@ -927,48 +932,44 @@ Resolver::add_callback(ResolverCb cb, sa_family_t family) } void -Resolver::resolve(const std::string& host, const std::string& serviceName) +Resolver::resolve(std::string_view host, std::string_view service) { - auto service = serviceName; // The async_resolve function used below typically relies on the contents of the // /etc/services (Linux/POSIX) or c:\windows\system32\drivers\etc\services (Windows) // file in order to resolve a descriptive service name into a port number. A // resolution attempt that would otherwise succeed can therefore fail if the file // is inaccessible or corrupted (which is rare but can happen in practice). We // hardcode the port numbers for http and https to prevent this failure mode. - if (service == "http") { - service = "80"; - } else if (service == "https") { - service = "443"; + if (service == "http"sv) { + service = "80"sv; + } else if (service == "https"sv) { + service = "443"sv; } - resolver_ - .async_resolve(host, - service, - [this, host, service, destroyed = destroyed_](const asio::error_code& ec, - asio::ip::tcp::resolver::results_type endpoints) { - if (ec == asio::error::operation_aborted or *destroyed) - return; - if (logger_) { - logger_->debug("[http:client] [resolver] result for {:s}:{:s}: {:s}", - host, - service, - ec.message()); - } - decltype(cbs_) cbs; - { - std::lock_guard lock(mutex_); - ec_ = ec; - endpoints_ = std::vector {endpoints.begin(), endpoints.end()}; - completed_ = true; - cbs = std::move(cbs_); - } - while (not cbs.empty()) { - auto cb = cbs.front(); - if (cb) - cb(ec, endpoints_); - cbs.pop(); - } - }); + resolver_.async_resolve(host, + service, + [this, destroyed = destroyed_](const asio::error_code& ec, + asio::ip::tcp::resolver::results_type endpoints) { + if (ec == asio::error::operation_aborted or *destroyed) + return; + if (logger_) { + logger_->debug("[http:client] [resolver] got result: {:s}", ec.message()); + } + decltype(cbs_) cbs; + { + std::lock_guard lock(mutex_); + ec_ = ec; + endpoints_ = std::vector {endpoints.begin(), + endpoints.end()}; + completed_ = true; + cbs = std::move(cbs_); + } + while (not cbs.empty()) { + auto cb = cbs.front(); + if (cb) + cb(ec, endpoints_); + cbs.pop(); + } + }); } // Request @@ -986,8 +987,8 @@ Request::Request(asio::io_context& ctx, , resolver_(std::make_shared(ctx, url, logger)) { init_default_headers(); - set_header_field(restinio::http_field_t::content_type, HTTP_HEADER_CONTENT_TYPE_JSON); - set_header_field(restinio::http_field_t::accept, HTTP_HEADER_CONTENT_TYPE_JSON); + set_header_field(restinio::http_field_t::content_type, std::string(HTTP_HEADER_CONTENT_TYPE_JSON)); + set_header_field(restinio::http_field_t::accept, std::string(HTTP_HEADER_CONTENT_TYPE_JSON)); Json::StreamWriterBuilder wbuilder; set_method(restinio::http_method_post()); set_body(Json::writeString(wbuilder, json)); @@ -1013,7 +1014,7 @@ Request::Request(asio::io_context& ctx, const std::string& url, OnJsonCb jsoncb, , resolver_(std::make_shared(ctx, url, logger)) { init_default_headers(); - set_header_field(restinio::http_field_t::accept, HTTP_HEADER_CONTENT_TYPE_JSON); + set_header_field(restinio::http_field_t::accept, std::string(HTTP_HEADER_CONTENT_TYPE_JSON)); Json::StreamWriterBuilder wbuilder; set_method(restinio::http_method_get()); add_on_done_callback([this, jsoncb](const Response& response) { @@ -1051,8 +1052,8 @@ Request::Request(asio::io_context& ctx, const std::string& url, OnDoneCb onDone, } Request::Request(asio::io_context& ctx, - const std::string& host, - const std::string& service, + std::string_view host, + std::string_view service, const bool ssl, std::shared_ptr logger) : logger_(logger) @@ -1095,7 +1096,7 @@ Request::Request(asio::io_context& ctx, , family_(family) , resolver_(resolver) { - set_header_field(restinio::http_field_t::host, get_url().host + ":" + get_url().service); + set_header_field(restinio::http_field_t::host, concat(get_url().host, ":", get_url().service)); set_target(Url(target).target); } @@ -1189,6 +1190,12 @@ Request::set_body(std::string body) body_ = std::move(body); } +void +Request::set_body(const uint8_t* data, size_t length) +{ + body_.assign(reinterpret_cast(data), length); +} + void Request::set_auth(const std::string& username, const std::string& password) { @@ -1377,7 +1384,8 @@ Request::connect(std::vector&& endpoints, HandlerCb cb) conn_ = std::make_shared(ctx_, server_ca_, client_identity_, logger_); else conn_ = std::make_shared(ctx_, true /*ssl*/, logger_); - conn_->set_ssl_verification(get_url().host, asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert); + conn_->set_ssl_verification(std::string(get_url().host), + asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert); } else conn_ = std::make_shared(ctx_, false /*ssl*/, logger_); @@ -1405,10 +1413,10 @@ Request::connect(std::vector&& endpoints, HandlerCb cb) const auto& url = this_.get_url(); auto port = endpoint.port(); if ((!isHttps && port == (in_port_t) 80) || (isHttps && port == (in_port_t) 443)) - this_.set_header_field(restinio::http_field_t::host, url.host); + this_.set_header_field(restinio::http_field_t::host, std::string(url.host)); else this_.set_header_field(restinio::http_field_t::host, - url.host + ":" + std::to_string(port)); + fmt::format("{}:{}", url.host, port)); if (isHttps) { if (this_.conn_ and this_.conn_->is_open() and this_.conn_->is_ssl()) { @@ -1635,7 +1643,7 @@ Request::onHeadersComplete() } bool -startsWith(const std::string& haystack, const std::string& needle) +startsWith(const std::string_view haystack, const std::string_view needle) { return needle.length() <= haystack.length() && std::equal(needle.begin(), needle.end(), haystack.begin()); } diff --git a/src/utils.cpp b/src/utils.cpp index 2bce68d2..83a627e5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -20,7 +20,7 @@ #include "config.h" #endif -#if defined(_WIN32) && (_WIN32_WINNT < 0x0502) && (NTDDI_VERSION >= NTDDI_VISTA) +#if defined(_WIN32) && (_WIN32_WINNT < 0x0502) && (NTDDI_VERSION >= NTDDI_VISTA) #define _WIN32_WINNT _WIN32_WINNT_WIN10 #include #include @@ -42,30 +42,35 @@ namespace dht { -const char* version() { +const char* +version() +{ return PACKAGE_VERSION; } -static constexpr std::array MAPPED_IPV4_PREFIX {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}}; +static constexpr std::array MAPPED_IPV4_PREFIX { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff} +}; -std::pair -splitPort(std::string_view s) { +std::pair +splitPort(std::string_view s) +{ if (s.empty()) return {}; if (s[0] == '[') { std::size_t closure = s.find_first_of(']'); std::size_t found = s.find_last_of(':'); if (closure == std::string_view::npos) - return {std::string(s), ""}; + return {s, ""}; if (found == std::string_view::npos or found < closure) - return {std::string(s.substr(1,closure-1)), ""}; - return {std::string(s.substr(1,closure-1)), std::string(s.substr(found+1))}; + return {s.substr(1, closure - 1), ""}; + return {s.substr(1, closure - 1), s.substr(found + 1)}; } std::size_t found = s.find_last_of(':'); std::size_t first = s.find_first_of(':'); if (found == std::string_view::npos or found != first) - return {std::string(s), ""}; - return {std::string(s.substr(0,found)), std::string(s.substr(found+1))}; + return {s, ""}; + return {s.substr(0, found), s.substr(found + 1)}; } std::vector @@ -80,7 +85,7 @@ SockAddr::resolve(const std::string& host, const std::string& service) hints.ai_socktype = SOCK_DGRAM; addrinfo* info = nullptr; int rc = getaddrinfo(host.c_str(), service.empty() ? nullptr : service.c_str(), &hints, &info); - if(rc != 0) + if (rc != 0) throw std::invalid_argument(std::string("Error: `") + host + ":" + service + "`: " + gai_strerror(rc)); for (addrinfo* infop = info; infop; infop = infop->ai_next) @@ -108,11 +113,13 @@ SockAddr::setAddress(const char* address) throw std::runtime_error(std::string("Can't parse IP address: ") + strerror(errno)); } -void print_addr(std::ostream& out, const sockaddr* sa, socklen_t slen) +void +print_addr(std::ostream& out, const sockaddr* sa, socklen_t slen) { char hbuf[NI_MAXHOST]; char sbuf[NI_MAXSERV]; - if (sa and slen and !getnameinfo(sa, slen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { + if (sa and slen + and !getnameinfo(sa, slen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { if (sa->sa_family == AF_INET6) out << '[' << hbuf << ']'; else @@ -134,7 +141,7 @@ print_addr(const sockaddr* sa, socklen_t slen) std::string print_addr(const sockaddr_storage& ss, socklen_t sslen) { - return print_addr((const sockaddr*)&ss, sslen); + return print_addr((const sockaddr*) &ss, sslen); } bool @@ -156,7 +163,7 @@ SockAddr::isLoopback() const switch (getFamily()) { case AF_INET: { auto addr_host = ntohl(getIPv4().sin_addr.s_addr); - uint8_t b1 = (uint8_t)(addr_host >> 24); + uint8_t b1 = (uint8_t) (addr_host >> 24); return b1 == 127; } case AF_INET6: @@ -176,8 +183,8 @@ SockAddr::isPrivate() const case AF_INET: { auto addr_host = ntohl(getIPv4().sin_addr.s_addr); uint8_t b1, b2; - b1 = (uint8_t)(addr_host >> 24); - b2 = (uint8_t)((addr_host >> 16) & 0x0ff); + b1 = (uint8_t) (addr_host >> 24); + b2 = (uint8_t) ((addr_host >> 16) & 0x0ff); // 10.x.y.z if (b1 == 10) return true; @@ -240,11 +247,15 @@ SockAddr::getMappedIPv6() return ret; } -bool operator==(const SockAddr& a, const SockAddr& b) { +bool +operator==(const SockAddr& a, const SockAddr& b) +{ return a.equals(b); } -time_point from_time_t(std::time_t t) { +time_point +from_time_t(std::time_t t) +{ auto dt = system_clock::from_time_t(t) - system_clock::now(); auto now = clock::now(); if (dt > system_clock::duration(0) and now > time_point::max() - dt) @@ -254,7 +265,9 @@ time_point from_time_t(std::time_t t) { return now + dt; } -std::time_t to_time_t(time_point t) { +std::time_t +to_time_t(time_point t) +{ auto dt = t - clock::now(); auto now = system_clock::now(); if (dt > duration(0) and now >= system_clock::time_point::max() - dt) @@ -265,15 +278,16 @@ std::time_t to_time_t(time_point t) { } Blob -unpackBlob(const msgpack::object& o) { +unpackBlob(const msgpack::object& o) +{ switch (o.type) { case msgpack::type::BIN: - return {o.via.bin.ptr, o.via.bin.ptr+o.via.bin.size}; + return {o.via.bin.ptr, o.via.bin.ptr + o.via.bin.size}; case msgpack::type::STR: - return {o.via.str.ptr, o.via.str.ptr+o.via.str.size}; + return {o.via.str.ptr, o.via.str.ptr + o.via.str.size}; case msgpack::type::ARRAY: { Blob ret(o.via.array.size); - std::transform(o.via.array.ptr, o.via.array.ptr+o.via.array.size, ret.begin(), [](const msgpack::object& b) { + std::transform(o.via.array.ptr, o.via.array.ptr + o.via.array.size, ret.begin(), [](const msgpack::object& b) { return b.as(); }); return ret; @@ -284,21 +298,23 @@ unpackBlob(const msgpack::object& o) { } msgpack::unpacked -unpackMsg(Blob b) { - return msgpack::unpack((const char*)b.data(), b.size()); +unpackMsg(Blob b) +{ + return msgpack::unpack((const char*) b.data(), b.size()); } msgpack::object* -findMapValue(const msgpack::object& map, const char* key, size_t key_length) { - if (map.type != msgpack::type::MAP) throw msgpack::type_error(); +findMapValue(const msgpack::object& map, const char* key, size_t key_length) +{ + if (map.type != msgpack::type::MAP) + throw msgpack::type_error(); for (unsigned i = 0; i < map.via.map.size; i++) { auto& o = map.via.map.ptr[i]; - if (o.key.type == msgpack::type::STR - && key_length == o.key.via.str.size + if (o.key.type == msgpack::type::STR && key_length == o.key.via.str.size && std::strncmp(o.key.via.str.ptr, key, o.key.via.str.size) == 0) return &o.val; } return nullptr; } -} +} // namespace dht diff --git a/tests/httptester.cpp b/tests/httptester.cpp index 0d05a8a2..47bc65d3 100644 --- a/tests/httptester.cpp +++ b/tests/httptester.cpp @@ -241,9 +241,9 @@ HttpTester::test_parse_url_user_pass() // Assert CPPUNIT_ASSERT_EQUAL(url, parsed.toString()); CPPUNIT_ASSERT_EQUAL(std::string("http"), parsed.protocol); - CPPUNIT_ASSERT_EQUAL(std::string("user"), parsed.user); - CPPUNIT_ASSERT_EQUAL(std::string("pass"), parsed.password); - CPPUNIT_ASSERT_EQUAL(std::string("example.com"), parsed.host); + CPPUNIT_ASSERT_EQUAL(std::string_view("user"), parsed.user); + CPPUNIT_ASSERT_EQUAL(std::string_view("pass"), parsed.password); + CPPUNIT_ASSERT_EQUAL(std::string_view("example.com"), parsed.host); CPPUNIT_ASSERT_EQUAL(std::string("/"), parsed.target); } @@ -257,9 +257,9 @@ HttpTester::test_parse_url_user_only() // Assert CPPUNIT_ASSERT_EQUAL(url, parsed.toString()); CPPUNIT_ASSERT_EQUAL(std::string("http"), parsed.protocol); - CPPUNIT_ASSERT_EQUAL(std::string("user"), parsed.user); + CPPUNIT_ASSERT_EQUAL(std::string_view("user"), parsed.user); CPPUNIT_ASSERT(parsed.password.empty()); - CPPUNIT_ASSERT_EQUAL(std::string("example.com"), parsed.host); + CPPUNIT_ASSERT_EQUAL(std::string_view("example.com"), parsed.host); CPPUNIT_ASSERT_EQUAL(std::string("/"), parsed.target); } @@ -273,7 +273,7 @@ HttpTester::test_parse_url_ipv6_brackets() // Assert CPPUNIT_ASSERT_EQUAL(url, parsed.toString()); CPPUNIT_ASSERT_EQUAL(std::string("http"), parsed.protocol); - CPPUNIT_ASSERT_EQUAL(std::string("2001:db8::1"), parsed.host); + CPPUNIT_ASSERT_EQUAL(std::string_view("2001:db8::1"), parsed.host); CPPUNIT_ASSERT_EQUAL(std::string("/"), parsed.target); } @@ -287,8 +287,8 @@ HttpTester::test_parse_url_ipv6_brackets_port() // Assert CPPUNIT_ASSERT_EQUAL(url, parsed.toString()); CPPUNIT_ASSERT_EQUAL(std::string("http"), parsed.protocol); - CPPUNIT_ASSERT_EQUAL(std::string("2001:db8::1"), parsed.host); - CPPUNIT_ASSERT_EQUAL(std::string("8080"), parsed.service); + CPPUNIT_ASSERT_EQUAL(std::string_view("2001:db8::1"), parsed.host); + CPPUNIT_ASSERT_EQUAL(std::string_view("8080"), parsed.service); CPPUNIT_ASSERT_EQUAL(std::string("/"), parsed.target); } @@ -302,7 +302,7 @@ HttpTester::test_parse_url_mixed_case_protocol() // Assert CPPUNIT_ASSERT_EQUAL(std::string("http://example.com/"), parsed.toString()); CPPUNIT_ASSERT_EQUAL(std::string("http"), parsed.protocol); - CPPUNIT_ASSERT_EQUAL(std::string("example.com"), parsed.host); + CPPUNIT_ASSERT_EQUAL(std::string_view("example.com"), parsed.host); } void @@ -315,10 +315,10 @@ HttpTester::test_parse_url_complex_path_query_fragment() // Assert CPPUNIT_ASSERT_EQUAL(url, parsed.toString()); CPPUNIT_ASSERT_EQUAL(std::string("https"), parsed.protocol); - CPPUNIT_ASSERT_EQUAL(std::string("example.com"), parsed.host); + CPPUNIT_ASSERT_EQUAL(std::string_view("example.com"), parsed.host); CPPUNIT_ASSERT_EQUAL(std::string("/path/to/resource?query=param&q2=v2"), parsed.target); - CPPUNIT_ASSERT_EQUAL(std::string("query=param&q2=v2"), parsed.query); - CPPUNIT_ASSERT_EQUAL(std::string("#fragment"), parsed.fragment); + CPPUNIT_ASSERT_EQUAL(std::string_view("query=param&q2=v2"), parsed.query); + CPPUNIT_ASSERT_EQUAL(std::string_view("#fragment"), parsed.fragment); } void