diff --git a/include/pistache/endpoint.h b/include/pistache/endpoint.h index f0b040e21..d938da814 100644 --- a/include/pistache/endpoint.h +++ b/include/pistache/endpoint.h @@ -127,7 +127,7 @@ namespace Pistache::Http * [2] https://en.wikipedia.org/wiki/CRIME */ void useSSL(const std::string& cert, const std::string& key, - bool use_compression = false, int (*cb_password)(char *, int, int, void *) = NULL); + bool use_compression = false, int (*cb_password)(char*, int, int, void*) = NULL); /*! * \brief Use SSL certificate authentication on this endpoint diff --git a/include/pistache/http.h b/include/pistache/http.h index 8e4313a0c..4a5bc3837 100644 --- a/include/pistache/http.h +++ b/include/pistache/http.h @@ -169,7 +169,10 @@ namespace Pistache } // namespace Uri // Remove when RequestBuilder will be out of namespace Experimental - namespace Experimental {class RequestBuilder; } + namespace Experimental + { + class RequestBuilder; + } // 5. Request class Request : public Message @@ -192,6 +195,17 @@ namespace Pistache const Uri::Query& query() const; + void putAttribute(std::string name, std::shared_ptr data); + std::shared_ptr getAttribute(const std::string& name) const; + std::shared_ptr tryGetAttribute(const std::string& name) const; + void removeAttribute(const std::string& name); + + template + std::shared_ptr getAttributeAs(const std::string& name) const + { + return std::static_pointer_cast(getAttribute(name)); + } + /* @Investigate: this is disabled because of a lock in the shared_ptr / weak_ptr implementation of libstdc++. Under contention, we experience a performance drop of 5x with that lock @@ -230,6 +244,8 @@ namespace Pistache #endif Address address_; std::chrono::milliseconds timeout_ = std::chrono::milliseconds(0); + + std::unordered_map> data_; }; class Handler; diff --git a/include/pistache/listener.h b/include/pistache/listener.h index b6a9888c5..344bb173d 100644 --- a/include/pistache/listener.h +++ b/include/pistache/listener.h @@ -87,7 +87,7 @@ namespace Pistache::Tcp void pinWorker(size_t worker, const CpuSet& set); void setupSSL(const std::string& cert_path, const std::string& key_path, - bool use_compression, int (*cb_password)(char *, int, int, void *)); + bool use_compression, int (*cb_password)(char*, int, int, void*)); void setupSSLAuth(const std::string& ca_file, const std::string& ca_path, int (*cb)(int, void*)); diff --git a/src/common/description.cc b/src/common/description.cc index e30ab7b82..c523d4eff 100644 --- a/src/common/description.cc +++ b/src/common/description.cc @@ -145,7 +145,7 @@ namespace Pistache::Rest { auto group = paths(name); auto it = std::find_if(std::begin(group), std::end(group), - [&](const Path& p) { return p.method == method; }); + [&](const Path& p) { return p.method == method; }); return it != std::end(group); } @@ -168,7 +168,7 @@ namespace Pistache::Rest { auto group = paths(name); auto it = std::find_if(std::begin(group), std::end(group), - [&](const Path& p) { return p.method == method; }); + [&](const Path& p) { return p.method == method; }); if (it != std::end(group)) { diff --git a/src/common/http.cc b/src/common/http.cc index 4e519db2e..e3f0c8609 100644 --- a/src/common/http.cc +++ b/src/common/http.cc @@ -645,6 +645,48 @@ namespace Pistache::Http const Uri::Query& Request::query() const { return query_; } + void Request::putAttribute(std::string name, std::shared_ptr data) + { + auto it = data_.find(name); + if (it != std::end(data_)) + { + throw std::runtime_error("The data already exists"); + } + + data_.insert(std::make_pair(std::move(name), std::move(data))); + } + + std::shared_ptr Request::getAttribute(const std::string& name) const + { + auto data = tryGetAttribute(name); + if (data == nullptr) + { + throw std::runtime_error("The data does not exist"); + } + + return data; + } + + std::shared_ptr Request::tryGetAttribute(const std::string& name) const + { + auto it = data_.find(name); + if (it == std::end(data_)) + return nullptr; + + return it->second; + } + + void Request::removeAttribute(const std::string& name) + { + auto it = data_.find(name); + if (it == std::end(data_)) + { + return; + } + + data_.erase(it); + } + const Address& Request::address() const { return address_; } std::chrono::milliseconds Request::timeout() const { return timeout_; } diff --git a/src/server/endpoint.cc b/src/server/endpoint.cc index 5ebedc0ed..0411b0bbf 100644 --- a/src/server/endpoint.cc +++ b/src/server/endpoint.cc @@ -248,7 +248,7 @@ namespace Pistache::Http void Endpoint::shutdown() { listener.shutdown(); } - void Endpoint::useSSL([[maybe_unused]] const std::string& cert, [[maybe_unused]] const std::string& key, [[maybe_unused]] bool use_compression, [[maybe_unused]] int (*pass_cb)(char *, int, int, void *)) + void Endpoint::useSSL([[maybe_unused]] const std::string& cert, [[maybe_unused]] const std::string& key, [[maybe_unused]] bool use_compression, [[maybe_unused]] int (*pass_cb)(char*, int, int, void*)) { #ifndef PISTACHE_USE_SSL throw std::runtime_error("Pistache is not compiled with SSL support."); diff --git a/src/server/listener.cc b/src/server/listener.cc index ca3100ef4..faaae1925 100644 --- a/src/server/listener.cc +++ b/src/server/listener.cc @@ -85,7 +85,7 @@ namespace Pistache::Tcp ssl::SSLCtxPtr ssl_create_context(const std::string& cert, const std::string& key, bool use_compression, - int (*cb)(char *, int, int, void *)) + int (*cb)(char*, int, int, void*)) { const SSL_METHOD* method = SSLv23_server_method(); @@ -587,7 +587,7 @@ namespace Pistache::Tcp void Listener::setupSSL(const std::string& cert_path, const std::string& key_path, bool use_compression, - int (*cb_password)(char *, int, int, void *)) + int (*cb_password)(char*, int, int, void*)) { SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); diff --git a/tests/https_server_test.cc b/tests/https_server_test.cc index 6c71bce1c..14c672dc6 100644 --- a/tests/https_server_test.cc +++ b/tests/https_server_test.cc @@ -375,8 +375,7 @@ TEST(https_server_test, basic_tls_request_with_password_cert) { Http::Endpoint server(Address("localhost", Pistache::Port(0))); - const auto passwordCallback = [](char* buf, int size, int /*rwflag*/, void* /*u*/) -> int - { + const auto passwordCallback = [](char* buf, int size, int /*rwflag*/, void * /*u*/) -> int { static constexpr const char* const password = "test"; std::strncpy(buf, password, size); return static_cast(std::strlen(password)); diff --git a/tests/router_test.cc b/tests/router_test.cc index f235545df..875502de6 100644 --- a/tests/router_test.cc +++ b/tests/router_test.cc @@ -293,6 +293,21 @@ TEST(router_test, test_bind_shared_ptr) endpoint->shutdown(); } +class User +{ + +public: + User() = default; + + auto& getUserName() const + { + return username; + } + +private: + std::string username { "SomeUserName" }; +}; + class HandlerWithAuthMiddleware : public MyHandler { public: @@ -307,6 +322,9 @@ class HandlerWithAuthMiddleware : public MyHandler if (auth->getMethod() == Pistache::Http::Header::Authorization::Method::Basic) { auth_succ_count++; + + auto user = std::make_shared(); + request.putAttribute("User", user); return true; } else @@ -321,6 +339,18 @@ class HandlerWithAuthMiddleware : public MyHandler } } + void handle( + const Pistache::Rest::Request& request, + Pistache::Http::ResponseWriter response) + { + ASSERT_TRUE(request.tryGetAttribute("User")); + + auto user = request.getAttributeAs("User"); + ASSERT_EQ(user->getUserName(), "SomeUserName"); + + MyHandler::handle(request, std::move(response)); + } + int getAuthCount() { return auth_count; } int getSuccAuthCount() { return auth_succ_count; } diff --git a/tests/streaming_test.cc b/tests/streaming_test.cc index 2d2cbcf04..1835e4b94 100644 --- a/tests/streaming_test.cc +++ b/tests/streaming_test.cc @@ -127,7 +127,7 @@ namespace // from // https://stackoverflow.com/questions/6624667/can-i-use-libcurls-curlopt-writefunction-with-a-c11-lambda-expression#14720398 auto curl_callback = +[](void* ptr, size_t size, size_t nmemb, - void* userdata) -> size_t { + void* userdata) -> size_t { auto* chunks = static_cast(userdata); chunks->emplace_back(static_cast(ptr), size * nmemb); return size * nmemb; @@ -266,7 +266,8 @@ TEST_F(StreamingTests, ChunkedStream) EXPECT_EQ(chunks[2], "!"); } -class ClientDisconnectHandler : public Http::Handler { +class ClientDisconnectHandler : public Http::Handler +{ public: HTTP_PROTOTYPE(ClientDisconnectHandler) @@ -303,7 +304,7 @@ TEST(StreamingTest, ClientDisconnect) curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - CURLM* curlm = curl_multi_init(); + CURLM* curlm = curl_multi_init(); int still_running = 1; curl_multi_add_handle(curlm, curl); diff --git a/version.txt b/version.txt index c9fe97ce2..187f0a503 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.0.3.20220529 +0.0.3.20220803