From 49c82c9c508b7caa076de956caa075942421c6a4 Mon Sep 17 00:00:00 2001 From: yhirose Date: Sun, 28 Oct 2018 16:15:22 +0900 Subject: [PATCH] Fix #97. (Thanks to DJm00n.) --- httplib.h | 74 ++++++++++++++++++++++++++++++++++++++++++++------- test/Makefile | 2 +- 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/httplib.h b/httplib.h index 5515292..73267f4 100644 --- a/httplib.h +++ b/httplib.h @@ -166,7 +166,7 @@ public: virtual int read(char* ptr, size_t size) = 0; virtual int write(const char* ptr, size_t size1) = 0; virtual int write(const char* ptr) = 0; - virtual std::string get_remote_addr() = 0; + virtual std::string get_remote_addr() const = 0; template void write_format(const char* fmt, const Args& ...args); @@ -180,12 +180,28 @@ public: virtual int read(char* ptr, size_t size); virtual int write(const char* ptr, size_t size); virtual int write(const char* ptr); - virtual std::string get_remote_addr(); + virtual std::string get_remote_addr() const; private: socket_t sock_; }; +class BufferStream : public Stream { +public: + BufferStream() {} + virtual ~BufferStream() {} + + virtual int read(char* ptr, size_t size); + virtual int write(const char* ptr, size_t size); + virtual int write(const char* ptr); + virtual std::string get_remote_addr() const; + + const std::string& get_buffer() const; + +private: + std::string buffer; +}; + class Server { public: typedef std::function Handler; @@ -315,7 +331,7 @@ public: virtual int read(char* ptr, size_t size); virtual int write(const char* ptr, size_t size); virtual int write(const char* ptr); - virtual std::string get_remote_addr(); + virtual std::string get_remote_addr() const; private: socket_t sock_; @@ -1441,10 +1457,42 @@ inline int SocketStream::write(const char* ptr) return write(ptr, strlen(ptr)); } -inline std::string SocketStream::get_remote_addr() { +inline std::string SocketStream::get_remote_addr() const { return detail::get_remote_addr(sock_); } +// Buffer stream implementation +inline int BufferStream::read(char* ptr, size_t size) +{ +#ifdef _WIN32 + return static_cast(buffer._Copy_s(ptr, size, size)); +#else + return static_cast(buffer.copy(ptr, size)); +#endif +} + +inline int BufferStream::write(const char* ptr, size_t size) +{ + buffer.append(ptr, size); + return static_cast(size); +} + +inline int BufferStream::write(const char* ptr) +{ + size_t size = strlen(ptr); + buffer.append(ptr, size); + return static_cast(size); +} + +inline std::string BufferStream::get_remote_addr() const { + return ""; +} + +inline const std::string& BufferStream::get_buffer() const { + return buffer; +} + + // HTTP server implementation inline Server::Server() : keep_alive_max_count_(5) @@ -1973,10 +2021,12 @@ inline bool Client::send(Request& req, Response& res) inline void Client::write_request(Stream& strm, Request& req) { - auto path = detail::encode_url(req.path); + BufferStream bstrm; // Request line - strm.write_format("%s %s HTTP/1.1\r\n", + auto path = detail::encode_url(req.path); + + bstrm.write_format("%s %s HTTP/1.1\r\n", req.method.c_str(), path.c_str()); @@ -2009,17 +2059,21 @@ inline void Client::write_request(Stream& strm, Request& req) req.set_header("Content-Length", length.c_str()); } - detail::write_headers(strm, req); + detail::write_headers(bstrm, req); // Body if (!req.body.empty()) { if (req.get_header_value("Content-Type") == "application/x-www-form-urlencoded") { auto str = detail::encode_url(req.body); - strm.write(str.c_str(), str.size()); + bstrm.write(str.c_str(), str.size()); } else { - strm.write(req.body.c_str(), req.body.size()); + bstrm.write(req.body.c_str(), req.body.size()); } } + + // Flush buffer + auto& data = bstrm.get_buffer(); + strm.write(data.data(), data.size()); } inline bool Client::process_request(Stream& strm, Request& req, Response& res, bool& connection_close) @@ -2303,7 +2357,7 @@ inline int SSLSocketStream::write(const char* ptr) return write(ptr, strlen(ptr)); } -inline std::string SSLSocketStream::get_remote_addr() { +inline std::string SSLSocketStream::get_remote_addr() const { return detail::get_remote_addr(sock_); } diff --git a/test/Makefile b/test/Makefile index 2034063..0a72252 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,7 @@ CC = clang++ #CC = g++ -CFLAGS = -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra +CFLAGS = -ggdb -O0 -std=c++11 -DGTEST_USE_OWN_TR1_TUPLE -I.. -I. -Wall -Wextra -Wtype-limits OPENSSL_SUPPORT = -DCPPHTTPLIB_OPENSSL_SUPPORT -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -lssl -lcrypto ZLIB_SUPPORT = -DCPPHTTPLIB_ZLIB_SUPPORT -lz