Merge pull request #53 from yhirose/issue-52

Issue 52
This commit is contained in:
yhirose 2018-04-17 00:06:39 -04:00 committed by GitHub
commit c6a6530716
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 0 deletions

View File

@ -52,6 +52,7 @@ typedef int socket_t;
#include <functional> #include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <mutex>
#include <regex> #include <regex>
#include <string> #include <string>
#include <thread> #include <thread>
@ -204,6 +205,8 @@ public:
bool is_running() const; bool is_running() const;
void stop(); void stop();
bool is_handling_requests() const;
protected: protected:
bool process_request(Stream& strm, bool last_connection); bool process_request(Stream& strm, bool last_connection);
@ -231,6 +234,10 @@ private:
Handlers post_handlers_; Handlers post_handlers_;
Handler error_handler_; Handler error_handler_;
Logger logger_; Logger logger_;
// TODO: Use thread pool...
std::mutex running_threads_mutex_;
int running_threads_;
}; };
class Client { class Client {
@ -1407,6 +1414,7 @@ inline std::string SocketStream::get_remote_addr() {
inline Server::Server(HttpVersion http_version) inline Server::Server(HttpVersion http_version)
: http_version_(http_version) : http_version_(http_version)
, svr_sock_(-1) , svr_sock_(-1)
, running_threads_(0)
{ {
#ifndef _WIN32 #ifndef _WIN32
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
@ -1476,6 +1484,11 @@ inline void Server::stop()
svr_sock_ = -1; svr_sock_ = -1;
} }
inline bool Server::is_handling_requests() const
{
return running_threads_ > 0;
}
inline bool Server::parse_request_line(const char* s, Request& req) inline bool Server::parse_request_line(const char* s, Request& req)
{ {
static std::regex re("(GET|HEAD|POST) ([^?]+)(?:\\?(.+?))? (HTTP/1\\.[01])\r\n"); static std::regex re("(GET|HEAD|POST) ([^?]+)(?:\\?(.+?))? (HTTP/1\\.[01])\r\n");
@ -1632,10 +1645,29 @@ inline bool Server::listen_internal()
// TODO: Use thread pool... // TODO: Use thread pool...
std::thread([=]() { std::thread([=]() {
{
std::lock_guard<std::mutex> guard(running_threads_mutex_);
running_threads_++;
}
read_and_close_socket(sock); read_and_close_socket(sock);
{
std::lock_guard<std::mutex> guard(running_threads_mutex_);
running_threads_--;
}
}).detach(); }).detach();
} }
// TODO: Use thread pool...
for (;;) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::lock_guard<std::mutex> guard(running_threads_mutex_);
if (!running_threads_) {
break;
}
}
return ret; return ret;
} }

View File

@ -262,6 +262,10 @@ protected:
svr_.get("/hi", [&](const Request& /*req*/, Response& res) { svr_.get("/hi", [&](const Request& /*req*/, Response& res) {
res.set_content("Hello World!", "text/plain"); res.set_content("Hello World!", "text/plain");
}) })
.get("/slow", [&](const Request& /*req*/, Response& res) {
msleep(3000);
res.set_content("slow", "text/plain");
})
.get("/remote_addr", [&](const Request& req, Response& res) { .get("/remote_addr", [&](const Request& req, Response& res) {
auto remote_addr = req.headers.find("REMOTE_ADDR")->second; auto remote_addr = req.headers.find("REMOTE_ADDR")->second;
res.set_content(remote_addr.c_str(), "text/plain"); res.set_content(remote_addr.c_str(), "text/plain");
@ -358,6 +362,7 @@ protected:
virtual void TearDown() { virtual void TearDown() {
svr_.stop(); svr_.stop();
t_.join(); t_.join();
EXPECT_EQ(false, svr_.is_handling_requests());
} }
map<string, string> persons_; map<string, string> persons_;
@ -664,6 +669,14 @@ TEST_F(ServerTest, GetMethodRemoteAddr)
EXPECT_TRUE(res->body == "::1" || res->body == "127.0.0.1"); EXPECT_TRUE(res->body == "::1" || res->body == "127.0.0.1");
} }
TEST_F(ServerTest, SlowRequest)
{
std::thread([=]() { auto res = cli_.get("/slow"); }).detach();
std::thread([=]() { auto res = cli_.get("/slow"); }).detach();
std::thread([=]() { auto res = cli_.get("/slow"); }).detach();
msleep(1000);
}
#ifdef CPPHTTPLIB_ZLIB_SUPPORT #ifdef CPPHTTPLIB_ZLIB_SUPPORT
TEST_F(ServerTest, Gzip) TEST_F(ServerTest, Gzip)
{ {