if (ec) {
derr << "write_data failed: " << ec.message() << dendl;
throw rgw::io::Exception(ec.value(), std::system_category());
+ } else {
+ /* According to the documentation of boost::asio::write if there is
+ * no error (signalised by ec), then bytes == len. We don't need to
+ * take care of partial writes in such situation. */
+ return bytes;
}
- return bytes;
}
size_t RGWAsioClientIO::read_data(char* const buf, const size_t max)
#define dout_subsys ceph_subsys_rgw
-size_t RGWCivetWeb::write_data(const char *buf, size_t len)
+size_t RGWCivetWeb::write_data(const char *buf, const size_t len)
{
- const int ret = mg_write(conn, buf, len);
- if (ret == 0) {
- /* didn't send anything, error out */
- throw rgw::io::Exception(EIO, std::system_category());
- } else if (ret < 0) {
- throw rgw::io::Exception(-ret, std::system_category());
+ auto to_sent = len;
+ while (to_sent) {
+ const int ret = mg_write(conn, buf, len);
+ if (ret < 0 || ! ret) {
+ /* According to the documentation of mg_write() it always returns -1 on
+ * error. The details aren't available, so we will just throw EIO. Same
+ * goes to 0 that is associated with writing to a closed connection. */
+ throw rgw::io::Exception(EIO, std::system_category());
+ } else {
+ to_sent -= static_cast<size_t>(ret);
+ }
}
- return ret;
+ return len;
}
RGWCivetWeb::RGWCivetWeb(mg_connection* const conn, const int port)
{
const int ret = mg_read(conn, buf, len);
if (ret < 0) {
- throw rgw::io::Exception(-ret, std::system_category());
+ throw rgw::io::Exception(EIO, std::system_category());
}
return ret;
}
size_t RGWFCGX::write_data(const char* const buf, const size_t len)
{
- const auto ret = FCGX_PutStr(buf, len, fcgx->out);
+ /* According to the documentation of FCGX_PutStr if there is no error
+ * (signalised by negative return value), then always ret == len. */
+ const auto ret = FCGX_PutStr(buf, len, fcgx->out);
if (ret < 0) {
throw rgw::io::Exception(-ret, std::system_category());
}