Skip to content

Commit

Permalink
rgw: fix interface compliance of RGWCivetWeb::write_data().
Browse files Browse the repository at this point in the history
This is a potential fix for partial writes and handling of error
codes that might come from mg_write() of the CivetWeb front-end.
None of the potential issues has been observed in testing.

The commit also documents the same aspects regarding the ASIO
and FastCGI front-ends.

Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
  • Loading branch information
rzarzynski committed Oct 14, 2016
1 parent a4dd8ad commit baf393c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
6 changes: 5 additions & 1 deletion src/rgw/rgw_asio_client.cc
Expand Up @@ -86,8 +86,12 @@ size_t RGWAsioClientIO::write_data(const char* const buf,
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)
Expand Down
20 changes: 12 additions & 8 deletions src/rgw/rgw_civetweb.cc
Expand Up @@ -14,14 +14,18 @@

size_t RGWCivetWeb::write_data(const char *buf, 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());
while (len) {
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 {
len -= static_cast<size_t>(ret);
}
}
return ret;
return len;
}

RGWCivetWeb::RGWCivetWeb(mg_connection* const conn, const int port)
Expand All @@ -36,7 +40,7 @@ size_t RGWCivetWeb::read_data(char *buf, size_t len)
{
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;
}
Expand Down
4 changes: 3 additions & 1 deletion src/rgw/rgw_fcgi.cc
Expand Up @@ -6,7 +6,9 @@

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());
}
Expand Down

0 comments on commit baf393c

Please sign in to comment.