@@ -2098,6 +2098,16 @@ inline ssize_t write_headers(Stream &strm, const T &info,
20982098 return write_len;
20992099}
21002100
2101+ inline bool write_data (Stream &strm, const char *d, size_t l) {
2102+ size_t offset = 0 ;
2103+ while (offset < l) {
2104+ auto length = strm.write (d + offset, l - offset);
2105+ if (length < 0 ) { return false ; }
2106+ offset += static_cast <size_t >(length);
2107+ }
2108+ return true ;
2109+ }
2110+
21012111inline ssize_t write_content (Stream &strm, ContentProvider content_provider,
21022112 size_t offset, size_t length) {
21032113 size_t begin_offset = offset;
@@ -2107,12 +2117,14 @@ inline ssize_t write_content(Stream &strm, ContentProvider content_provider,
21072117
21082118 DataSink data_sink;
21092119 data_sink.write = [&](const char *d, size_t l) {
2110- offset += l;
2111- if (strm.write (d, l) < 0 ) { ok = false ; }
2120+ if (ok) {
2121+ offset += l;
2122+ if (!write_data (strm, d, l)) { ok = false ; }
2123+ }
21122124 };
2113- data_sink.is_writable = [&](void ) { return strm.is_writable () && ok ; };
2125+ data_sink.is_writable = [&](void ) { return ok && strm.is_writable (); };
21142126
2115- while (offset < end_offset) {
2127+ while (ok && offset < end_offset) {
21162128 if (!content_provider (offset, end_offset - offset, data_sink)) {
21172129 return -1 ;
21182130 }
@@ -2130,29 +2142,41 @@ inline ssize_t write_content_chunked(Stream &strm,
21302142 auto data_available = true ;
21312143 ssize_t total_written_length = 0 ;
21322144
2133- ssize_t written_length = 0 ;
2145+ auto ok = true ;
21342146
21352147 DataSink data_sink;
21362148 data_sink.write = [&](const char *d, size_t l) {
2137- data_available = l > 0 ;
2138- offset += l;
2139-
2140- // Emit chunked response header and footer for each chunk
2141- auto chunk = from_i_to_hex (l) + " \r\n " + std::string (d, l) + " \r\n " ;
2142- written_length = strm.write (chunk);
2149+ if (ok) {
2150+ data_available = l > 0 ;
2151+ offset += l;
2152+
2153+ // Emit chunked response header and footer for each chunk
2154+ auto chunk = from_i_to_hex (l) + " \r\n " + std::string (d, l) + " \r\n " ;
2155+ if (write_data (strm, chunk.data (), chunk.size ())) {
2156+ total_written_length += chunk.size ();
2157+ } else {
2158+ ok = false ;
2159+ }
2160+ }
21432161 };
21442162 data_sink.done = [&](void ) {
21452163 data_available = false ;
2146- written_length = strm.write (" 0\r\n\r\n " );
2164+ if (ok) {
2165+ static const std::string done_marker (" 0\r\n\r\n " );
2166+ if (write_data (strm, done_marker.data (), done_marker.size ())) {
2167+ total_written_length += done_marker.size ();
2168+ } else {
2169+ ok = false ;
2170+ }
2171+ }
21472172 };
21482173 data_sink.is_writable = [&](void ) {
2149- return strm.is_writable () && written_length >= 0 ;
2174+ return ok && strm.is_writable ();
21502175 };
21512176
21522177 while (data_available && !is_shutting_down ()) {
21532178 if (!content_provider (offset, 0 , data_sink)) { return -1 ; }
2154- if (written_length < 0 ) { return written_length; }
2155- total_written_length += written_length;
2179+ if (!ok) { return -1 ; }
21562180 }
21572181
21582182 return total_written_length;
@@ -4132,34 +4156,41 @@ inline bool Client::write_request(Stream &strm, const Request &req,
41324156
41334157 // Flush buffer
41344158 auto &data = bstrm.get_buffer ();
4135- strm.write (data.data (), data.size ());
4159+ if (!detail::write_data (strm, data.data (), data.size ())) {
4160+ return false ;
4161+ }
41364162
41374163 // Body
41384164 if (req.body .empty ()) {
41394165 if (req.content_provider ) {
41404166 size_t offset = 0 ;
41414167 size_t end_offset = req.content_length ;
41424168
4143- ssize_t written_length = 0 ;
4169+ bool ok = true ;
41444170
41454171 DataSink data_sink;
41464172 data_sink.write = [&](const char *d, size_t l) {
4147- written_length = strm.write (d, l);
4148- offset += static_cast <size_t >(written_length);
4173+ if (ok) {
4174+ if (detail::write_data (strm, d, l)) {
4175+ offset += l;
4176+ } else {
4177+ ok = false ;
4178+ }
4179+ }
41494180 };
41504181 data_sink.is_writable = [&](void ) {
4151- return strm.is_writable () && written_length >= 0 ;
4182+ return ok && strm.is_writable ();
41524183 };
41534184
41544185 while (offset < end_offset) {
41554186 if (!req.content_provider (offset, end_offset - offset, data_sink)) {
41564187 return false ;
41574188 }
4158- if (written_length < 0 ) { return false ; }
4189+ if (!ok ) { return false ; }
41594190 }
41604191 }
41614192 } else {
4162- strm. write ( req.body );
4193+ return detail::write_data ( strm, req. body . data (), req.body . size () );
41634194 }
41644195
41654196 return true ;
0 commit comments