Skip to content

Commit f086bf5

Browse files
committed
Fix #738
1 parent 6613d7b commit f086bf5

File tree

2 files changed

+69
-34
lines changed

2 files changed

+69
-34
lines changed

httplib.h

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ class Server {
692692
const Request &req, Response &res);
693693
bool write_response_core(Stream &strm, bool close_connection,
694694
const Request &req, Response &res,
695-
std::string &content_type, std::string &boundary);
695+
bool need_apply_ranges);
696696
bool write_content_with_provider(Stream &strm, const Request &req,
697697
Response &res, const std::string &boundary,
698698
const std::string &content_type);
@@ -3769,7 +3769,8 @@ inline ssize_t SocketStream::read(char *ptr, size_t size) {
37693769
}
37703770
return recv(sock_, ptr, static_cast<int>(size), CPPHTTPLIB_RECV_FLAGS);
37713771
#else
3772-
return handle_EINTR([&]() { return recv(sock_, ptr, size, CPPHTTPLIB_RECV_FLAGS); });
3772+
return handle_EINTR(
3773+
[&]() { return recv(sock_, ptr, size, CPPHTTPLIB_RECV_FLAGS); });
37733774
#endif
37743775
}
37753776

@@ -3782,7 +3783,8 @@ inline ssize_t SocketStream::write(const char *ptr, size_t size) {
37823783
}
37833784
return send(sock_, ptr, static_cast<int>(size), CPPHTTPLIB_SEND_FLAGS);
37843785
#else
3785-
return handle_EINTR([&]() { return send(sock_, ptr, size, CPPHTTPLIB_SEND_FLAGS); });
3786+
return handle_EINTR(
3787+
[&]() { return send(sock_, ptr, size, CPPHTTPLIB_SEND_FLAGS); });
37863788
#endif
37873789
}
37883790

@@ -4022,32 +4024,27 @@ inline bool Server::parse_request_line(const char *s, Request &req) {
40224024

40234025
inline bool Server::write_response(Stream &strm, bool close_connection,
40244026
const Request &req, Response &res) {
4025-
std::string content_type;
4026-
std::string boundary;
4027-
return write_response_core(strm, close_connection, req, res, content_type,
4028-
boundary);
4027+
return write_response_core(strm, close_connection, req, res, false);
40294028
}
40304029

40314030
inline bool Server::write_response_with_content(Stream &strm,
40324031
bool close_connection,
40334032
const Request &req,
40344033
Response &res) {
4035-
std::string content_type;
4036-
std::string boundary;
4037-
apply_ranges(req, res, content_type, boundary);
4038-
4039-
return write_response_core(strm, close_connection, req, res, content_type,
4040-
boundary);
4034+
return write_response_core(strm, close_connection, req, res, true);
40414035
}
40424036

40434037
inline bool Server::write_response_core(Stream &strm, bool close_connection,
40444038
const Request &req, Response &res,
4045-
std::string &content_type,
4046-
std::string &boundary) {
4039+
bool need_apply_ranges) {
40474040
assert(res.status != -1);
40484041

40494042
if (400 <= res.status && error_handler_) { error_handler_(req, res); }
40504043

4044+
std::string content_type;
4045+
std::string boundary;
4046+
if (need_apply_ranges) { apply_ranges(req, res, content_type, boundary); }
4047+
40514048
// Headers
40524049
if (close_connection || req.get_header_value("Connection") == "close") {
40534050
res.set_header("Connection", "close");

test/test.cc

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ TEST(UrlWithSpace, Redirect) {
841841
}
842842
#endif
843843

844-
TEST(Server, BindDualStack) {
844+
TEST(BindServerTest, BindDualStack) {
845845
Server svr;
846846

847847
svr.Get("/1", [&](const Request & /*req*/, Response &res) {
@@ -874,7 +874,7 @@ TEST(Server, BindDualStack) {
874874
ASSERT_FALSE(svr.is_running());
875875
}
876876

877-
TEST(Server, BindAndListenSeparately) {
877+
TEST(BindServerTest, BindAndListenSeparately) {
878878
Server svr;
879879
int port = svr.bind_to_any_port("0.0.0.0");
880880
ASSERT_TRUE(svr.is_valid());
@@ -883,7 +883,7 @@ TEST(Server, BindAndListenSeparately) {
883883
}
884884

885885
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
886-
TEST(SSLServer, BindAndListenSeparately) {
886+
TEST(BindServerTest, BindAndListenSeparatelySSL) {
887887
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, CLIENT_CA_CERT_FILE,
888888
CLIENT_CA_CERT_DIR);
889889
int port = svr.bind_to_any_port("0.0.0.0");
@@ -893,6 +893,41 @@ TEST(SSLServer, BindAndListenSeparately) {
893893
}
894894
#endif
895895

896+
TEST(ErrorHandlerTest, ContentLength) {
897+
Server svr;
898+
899+
svr.set_error_handler([](const Request & /*req*/, Response &res) {
900+
res.status = 200;
901+
res.set_content("abcdefghijklmnopqrstuvwxyz",
902+
"text/html"); // <= Content-Length still 13
903+
});
904+
905+
svr.Get("/hi", [](const Request & /*req*/, Response &res) {
906+
res.set_content("Hello World!\n", "text/plain");
907+
res.status = 524;
908+
});
909+
910+
auto thread = std::thread([&]() { svr.listen(HOST, PORT); });
911+
912+
// Give GET time to get a few messages.
913+
std::this_thread::sleep_for(std::chrono::seconds(1));
914+
915+
{
916+
Client cli(HOST, PORT);
917+
918+
auto res = cli.Get("/hi");
919+
ASSERT_TRUE(res);
920+
EXPECT_EQ(200, res->status);
921+
EXPECT_EQ("text/html", res->get_header_value("Content-Type"));
922+
EXPECT_EQ("26", res->get_header_value("Content-Length"));
923+
EXPECT_EQ("abcdefghijklmnopqrstuvwxyz", res->body);
924+
}
925+
926+
svr.stop();
927+
thread.join();
928+
ASSERT_FALSE(svr.is_running());
929+
}
930+
896931
class ServerTest : public ::testing::Test {
897932
protected:
898933
ServerTest()
@@ -3473,24 +3508,27 @@ TEST(SSLClientServerTest, TrustDirOptional) {
34733508

34743509
TEST(SSLClientServerTest, SSLConnectTimeout) {
34753510
class NoListenSSLServer : public SSLServer {
3476-
public:
3477-
NoListenSSLServer(const char *cert_path, const char *private_key_path, const char *client_ca_cert_file_path,
3478-
const char *client_ca_cert_dir_path = nullptr)
3479-
: SSLServer(cert_path, private_key_path, client_ca_cert_file_path, client_ca_cert_dir_path)
3480-
, stop_(false)
3481-
{}
3482-
3483-
bool stop_;
3484-
private:
3485-
bool process_and_close_socket(socket_t /*sock*/) override {
3486-
// Don't create SSL context
3487-
while (!stop_) {
3488-
std::this_thread::sleep_for(std::chrono::milliseconds(100));
3489-
}
3490-
return true;
3511+
public:
3512+
NoListenSSLServer(const char *cert_path, const char *private_key_path,
3513+
const char *client_ca_cert_file_path,
3514+
const char *client_ca_cert_dir_path = nullptr)
3515+
: SSLServer(cert_path, private_key_path, client_ca_cert_file_path,
3516+
client_ca_cert_dir_path),
3517+
stop_(false) {}
3518+
3519+
bool stop_;
3520+
3521+
private:
3522+
bool process_and_close_socket(socket_t /*sock*/) override {
3523+
// Don't create SSL context
3524+
while (!stop_) {
3525+
std::this_thread::sleep_for(std::chrono::milliseconds(100));
34913526
}
3527+
return true;
3528+
}
34923529
};
3493-
NoListenSSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, CLIENT_CA_CERT_FILE);
3530+
NoListenSSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE,
3531+
CLIENT_CA_CERT_FILE);
34943532
ASSERT_TRUE(svr.is_valid());
34953533

34963534
svr.Get("/test", [&](const Request &, Response &res) {

0 commit comments

Comments
 (0)