@@ -1038,7 +1038,6 @@ class ClientImpl {
10381038 ContentProviderWithoutLength content_provider_without_length,
10391039 const char *content_type);
10401040
1041- // socket is const because this function is called when socket_mutex_ is not locked
10421041 virtual bool process_socket (const Socket &socket,
10431042 std::function<bool (Stream &strm)> callback);
10441043 virtual bool is_ssl () const ;
@@ -2065,7 +2064,8 @@ inline socket_t create_client_socket(const char *host, int port,
20652064 bool tcp_nodelay,
20662065 SocketOptions socket_options,
20672066 time_t timeout_sec, time_t timeout_usec,
2068- const std::string &intf, std::atomic<Error> &error) {
2067+ const std::string &intf,
2068+ std::atomic<Error> &error) {
20692069 auto sock = create_socket (
20702070 host, port, 0 , tcp_nodelay, std::move (socket_options),
20712071 [&](socket_t sock, struct addrinfo &ai) -> bool {
@@ -2812,7 +2812,7 @@ inline bool write_data(Stream &strm, const char *d, size_t l) {
28122812template <typename T>
28132813inline bool write_content (Stream &strm, const ContentProvider &content_provider,
28142814 size_t offset, size_t length, T is_shutting_down,
2815- Error &error) {
2815+ std::atomic< Error> &error) {
28162816 size_t end_offset = offset + length;
28172817 auto ok = true ;
28182818 DataSink data_sink;
@@ -2848,7 +2848,7 @@ template <typename T>
28482848inline bool write_content (Stream &strm, const ContentProvider &content_provider,
28492849 size_t offset, size_t length,
28502850 const T &is_shutting_down) {
2851- Error error;
2851+ std::atomic< Error> error;
28522852 return write_content (strm, content_provider, offset, length, is_shutting_down,
28532853 error);
28542854}
@@ -2882,9 +2882,10 @@ write_content_without_length(Stream &strm,
28822882}
28832883
28842884template <typename T, typename U>
2885- inline bool
2886- write_content_chunked (Stream &strm, const ContentProvider &content_provider,
2887- const T &is_shutting_down, U &compressor, Error &error) {
2885+ inline bool write_content_chunked (Stream &strm,
2886+ const ContentProvider &content_provider,
2887+ const T &is_shutting_down, U &compressor,
2888+ std::atomic<Error> &error) {
28882889 size_t offset = 0 ;
28892890 auto data_available = true ;
28902891 auto ok = true ;
@@ -2967,15 +2968,14 @@ template <typename T, typename U>
29672968inline bool write_content_chunked (Stream &strm,
29682969 const ContentProvider &content_provider,
29692970 const T &is_shutting_down, U &compressor) {
2970- Error error;
2971+ std::atomic< Error> error;
29712972 return write_content_chunked (strm, content_provider, is_shutting_down,
29722973 compressor, error);
29732974}
29742975
29752976template <typename T>
29762977inline bool redirect (T &cli, const Request &req, Response &res,
2977- const std::string &path,
2978- const std::string &location) {
2978+ const std::string &path, const std::string &location) {
29792979 Request new_req = req;
29802980 new_req.path = path;
29812981 new_req.redirect_count_ -= 1 ;
@@ -4877,21 +4877,19 @@ inline bool ClientImpl::create_and_connect_socket(Socket &socket) {
48774877 return true ;
48784878}
48794879
4880- inline void ClientImpl::shutdown_ssl (Socket &socket, bool shutdown_gracefully) {
4881- (void )socket;
4882- (void )shutdown_gracefully;
4883- // If there are any requests in flight from threads other than us, then it's
4884- // a thread-unsafe race because individual ssl* objects are not thread-safe.
4880+ inline void ClientImpl::shutdown_ssl (Socket & /* socket*/ ,
4881+ bool /* shutdown_gracefully*/ ) {
4882+ // If there are any requests in flight from threads other than us, then it's
4883+ // a thread-unsafe race because individual ssl* objects are not thread-safe.
48854884 assert (socket_requests_in_flight_ == 0 ||
48864885 socket_requests_are_from_thread_ == std::this_thread::get_id ());
48874886}
48884887
48894888inline void ClientImpl::shutdown_socket (Socket &socket) {
4890- if (socket.sock == INVALID_SOCKET)
4891- return ;
4889+ if (socket.sock == INVALID_SOCKET) { return ; }
48924890 detail::shutdown_socket (socket.sock );
48934891}
4894-
4892+
48954893inline void ClientImpl::close_socket (Socket &socket) {
48964894 // If there are requests in flight in another thread, usually closing
48974895 // the socket will be fine and they will simply receive an error when
@@ -4905,8 +4903,7 @@ inline void ClientImpl::close_socket(Socket &socket) {
49054903#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
49064904 assert (socket.ssl == nullptr );
49074905#endif
4908- if (socket.sock == INVALID_SOCKET)
4909- return ;
4906+ if (socket.sock == INVALID_SOCKET) { return ; }
49104907 detail::close_socket (socket.sock );
49114908 socket.sock = INVALID_SOCKET;
49124909}
@@ -4917,7 +4914,7 @@ inline void ClientImpl::lock_socket_and_shutdown_and_close() {
49174914 shutdown_socket (socket_);
49184915 close_socket (socket_);
49194916}
4920-
4917+
49214918inline bool ClientImpl::read_response_line (Stream &strm, Response &res) {
49224919 std::array<char , 2048 > buf;
49234920
@@ -4952,17 +4949,17 @@ inline bool ClientImpl::send(const Request &req, Response &res) {
49524949
49534950 {
49544951 std::lock_guard<std::mutex> guard (socket_mutex_);
4955- // Set this to false immediately - if it ever gets set to true by the end of the
4956- // request, we know another thread instructed us to close the socket.
4952+ // Set this to false immediately - if it ever gets set to true by the end of
4953+ // the request, we know another thread instructed us to close the socket.
49574954 socket_should_be_closed_when_request_is_done_ = false ;
49584955
49594956 auto is_alive = false ;
49604957 if (socket_.is_open ()) {
49614958 is_alive = detail::select_write (socket_.sock , 0 , 0 ) > 0 ;
49624959 if (!is_alive) {
4963- // Attempt to avoid sigpipe by shutting down nongracefully if it seems like
4964- // the other side has already closed the connection
4965- // Also, there cannot be any requests in flight from other threads since we locked
4960+ // Attempt to avoid sigpipe by shutting down nongracefully if it seems
4961+ // like the other side has already closed the connection Also, there
4962+ // cannot be any requests in flight from other threads since we locked
49664963 // request_mutex_, so safe to close everything immediately
49674964 const bool shutdown_gracefully = false ;
49684965 shutdown_ssl (socket_, shutdown_gracefully);
@@ -4990,8 +4987,9 @@ inline bool ClientImpl::send(const Request &req, Response &res) {
49904987#endif
49914988 }
49924989
4993- // Mark the current socket as being in use so that it cannot be closed by anyone
4994- // else while this request is ongoing, even though we will be releasing the mutex.
4990+ // Mark the current socket as being in use so that it cannot be closed by
4991+ // anyone else while this request is ongoing, even though we will be
4992+ // releasing the mutex.
49954993 if (socket_requests_in_flight_ > 1 ) {
49964994 assert (socket_requests_are_from_thread_ == std::this_thread::get_id ());
49974995 }
@@ -5004,7 +5002,7 @@ inline bool ClientImpl::send(const Request &req, Response &res) {
50045002 return handle_request (strm, req, res, close_connection);
50055003 });
50065004
5007- // Briefly lock mutex in order to mark that a request is no longer ongoing
5005+ // Briefly lock mutex in order to mark that a request is no longer ongoing
50085006 {
50095007 std::lock_guard<std::mutex> guard (socket_mutex_);
50105008 socket_requests_in_flight_ -= 1 ;
@@ -5013,9 +5011,8 @@ inline bool ClientImpl::send(const Request &req, Response &res) {
50135011 socket_requests_are_from_thread_ = std::thread::id ();
50145012 }
50155013
5016- if (socket_should_be_closed_when_request_is_done_ ||
5017- close_connection ||
5018- !ret ) {
5014+ if (socket_should_be_closed_when_request_is_done_ || close_connection ||
5015+ !ret) {
50195016 shutdown_ssl (socket_, true );
50205017 shutdown_socket (socket_);
50215018 close_socket (socket_);
@@ -5410,11 +5407,12 @@ inline bool ClientImpl::process_request(Stream &strm, const Request &req,
54105407 // for this to be safe. Maybe a code refactor (such as moving this out to
54115408 // the send function and getting rid of the recursiveness of the mutex)
54125409 // could make this more obvious.
5413-
5414- // This is safe to call because process_request is only called by handle_request
5415- // which is only called by send, which locks the request mutex during the process.
5416- // It would be a bug to call it from a different thread since it's a thread-safety
5417- // issue to do these things to the socket if another thread is using the socket.
5410+
5411+ // This is safe to call because process_request is only called by
5412+ // handle_request which is only called by send, which locks the request
5413+ // mutex during the process. It would be a bug to call it from a different
5414+ // thread since it's a thread-safety issue to do these things to the socket
5415+ // if another thread is using the socket.
54185416 lock_socket_and_shutdown_and_close ();
54195417 }
54205418
@@ -5802,23 +5800,25 @@ inline size_t ClientImpl::is_socket_open() const {
58025800
58035801inline void ClientImpl::stop () {
58045802 std::lock_guard<std::mutex> guard (socket_mutex_);
5805- // There is no guarantee that this doesn't get overwritten later, but set it so that
5806- // there is a good chance that any threads stopping as a result pick up this error.
5803+ // There is no guarantee that this doesn't get overwritten later, but set it
5804+ // so that there is a good chance that any threads stopping as a result pick
5805+ // up this error.
58075806 error_ = Error::Canceled;
5808-
5809- // If there is anything ongoing right now, the ONLY thread-safe thing we can do
5810- // is to shutdown_socket, so that threads using this socket suddenly discover
5811- // they can't read/write any more and error out.
5812- // Everything else (closing the socket, shutting ssl down) is unsafe because these
5813- // actions are not thread-safe.
5807+
5808+ // If there is anything ongoing right now, the ONLY thread-safe thing we can
5809+ // do is to shutdown_socket, so that threads using this socket suddenly
5810+ // discover they can't read/write any more and error out. Everything else
5811+ // (closing the socket, shutting ssl down) is unsafe because these actions are
5812+ // not thread-safe.
58145813 if (socket_requests_in_flight_ > 0 ) {
58155814 shutdown_socket (socket_);
5816- // Aside from that, we set a flag for the socket to be closed when we're done.
5815+ // Aside from that, we set a flag for the socket to be closed when we're
5816+ // done.
58175817 socket_should_be_closed_when_request_is_done_ = true ;
58185818 return ;
58195819 }
58205820
5821- // Otherwise, sitll holding the mutex, we can shut everything down ourselves
5821+ // Otherwise, sitll holding the mutex, we can shut everything down ourselves
58225822 shutdown_ssl (socket_, true );
58235823 shutdown_socket (socket_);
58245824 close_socket (socket_);
@@ -5951,10 +5951,9 @@ inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl,
59515951 bool shutdown_gracefully) {
59525952 // sometimes we may want to skip this to try to avoid SIGPIPE if we know
59535953 // the remote has closed the network connection
5954- // Note that it is not always possible to avoid SIGPIPE, this is merely a best-efforts.
5955- if (shutdown_gracefully) {
5956- SSL_shutdown (ssl);
5957- }
5954+ // Note that it is not always possible to avoid SIGPIPE, this is merely a
5955+ // best-efforts.
5956+ if (shutdown_gracefully) { SSL_shutdown (ssl); }
59585957
59595958 std::lock_guard<std::mutex> guard (ctx_mutex);
59605959 SSL_free (ssl);
@@ -6215,8 +6214,8 @@ inline bool SSLServer::process_and_close_socket(socket_t sock) {
62156214 [&](Request &req) { req.ssl = ssl; });
62166215 });
62176216
6218- // Shutdown gracefully if the result seemed successful, non-gracefully if the
6219- // connection appeared to be closed.
6217+ // Shutdown gracefully if the result seemed successful, non-gracefully if
6218+ // the connection appeared to be closed.
62206219 const bool shutdown_gracefully = ret;
62216220 detail::ssl_delete (ctx_mutex_, ssl, shutdown_gracefully);
62226221 return ret;
@@ -6325,7 +6324,8 @@ inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res,
63256324 req2.path = host_and_port_;
63266325 return process_request (strm, req2, res2, false );
63276326 })) {
6328- // Thread-safe to close everything because we are assuming there are no requests in flight
6327+ // Thread-safe to close everything because we are assuming there are no
6328+ // requests in flight
63296329 shutdown_ssl (socket, true );
63306330 shutdown_socket (socket);
63316331 close_socket (socket);
@@ -6351,7 +6351,8 @@ inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res,
63516351 true ));
63526352 return process_request (strm, req3, res3, false );
63536353 })) {
6354- // Thread-safe to close everything because we are assuming there are no requests in flight
6354+ // Thread-safe to close everything because we are assuming there are
6355+ // no requests in flight
63556356 shutdown_ssl (socket, true );
63566357 shutdown_socket (socket);
63576358 close_socket (socket);
0 commit comments