auto bytes = boost::asio::write(socket, boost::asio::buffer(buf, len), ec);
if (ec) {
derr << "write_data failed with " << ec.message() << dendl;
- return -ec.value();
+ throw RGWStreamIOEngine::Exception(-ec.value());
}
return bytes;
}
int complete_header() override;
int send_content_length(uint64_t len) override;
- RGWEnv& get_env() override {
+ RGWEnv& get_env() noexcept override {
return env;
}
};
int RGWCivetWeb::write_data(const char *buf, int len)
{
- int r = mg_write(conn, buf, len);
- if (r == 0) {
+ const int ret = mg_write(conn, buf, len);
+ if (ret == 0) {
/* didn't send anything, error out */
- return -EIO;
+ throw RGWStreamIOEngine::Exception(-EIO);
+ } else if (ret < 0) {
+ throw RGWStreamIOEngine::Exception(ret);
}
- return r;
+ return ret;
}
RGWCivetWeb::RGWCivetWeb(mg_connection* const conn, const int port)
int RGWCivetWeb::read_data(char *buf, int len)
{
- return mg_read(conn, buf, len);
+ const int ret = mg_read(conn, buf, len);
+ if (ret < 0) {
+ throw RGWStreamIOEngine::Exception(ret);
+ }
+ return ret;
}
void RGWCivetWeb::flush()
}
}
+template <class... Args>
+static inline std::size_t safe_mg_printf(Args&&... args)
+{
+ const int ret = mg_printf(std::forward<Args>(args)...);
+ if (ret == 0) {
+ /* didn't send anything, error out */
+ throw RGWStreamIOEngine::Exception(-EIO);
+ } else if (ret < 0) {
+ throw RGWStreamIOEngine::Exception(ret);
+ }
+ return static_cast<std::size_t>(ret);
+}
+
int RGWCivetWeb::send_status(int status, const char *status_name)
{
mg_set_http_status(conn, status);
- return mg_printf(conn, "HTTP/1.1 %d %s\r\n", status,
- status_name ? status_name : "");
+ return safe_mg_printf(conn, "HTTP/1.1 %d %s\r\n", status,
+ status_name ? status_name : "");
}
int RGWCivetWeb::send_100_continue()
int RGWCivetWeb::send_content_length(uint64_t len)
{
- return mg_printf(conn, "Content-Length: %" PRIu64 "\r\n", len);
+ return safe_mg_printf(conn, "Content-Length: %" PRIu64 "\r\n", len);
}
void flush() override;
- RGWEnv& get_env() override {
+ RGWEnv& get_env() noexcept override {
return env;
}
#ifndef CEPH_RGW_CLIENT_IO_H
#define CEPH_RGW_CLIENT_IO_H
+#include <exception>
#include <string>
#include <streambuf>
#include <istream>
virtual ~RGWClientIO() {}
void init(CephContext *cct);
- virtual RGWEnv& get_env() = 0;
+ virtual RGWEnv& get_env() noexcept = 0;
virtual int complete_request() = 0;
}; /* RGWClient IO */
virtual int write_data(const char *buf, int len) = 0;
public:
+ class Exception : public std::exception {
+ int err;
+
+ public:
+ Exception(const int err)
+ : err(err) {
+ }
+
+ int value() {
+ return err;
+ }
+ };
+
virtual int send_status(int status, const char *status_name) = 0;
virtual int send_100_continue() = 0;
virtual int complete_header() = 0;
std::string grab_aws4_sha256_hash();
- RGWEnv& get_env() override {
+ RGWEnv& get_env() noexcept override {
return env;
}
return *engine;
}
+#define EXCPT_TO_RC(code) \
+ try { \
+ return code; \
+ } catch (RGWStreamIOEngine::Exception& e) { \
+ return e.value(); \
+ }
+
+#define EXCPT_TO_VOID(code) \
+ try { \
+ return code; \
+ } catch (RGWStreamIOEngine::Exception& e) { \
+ return; \
+ }
+
protected:
void init_env(CephContext *cct) override {
- return get_decoratee().init_env(cct);
+ EXCPT_TO_VOID(get_decoratee().init_env(cct));
}
int read_data(char* const buf, const int max) override {
- return get_decoratee().read_data(buf, max);
+ EXCPT_TO_RC(get_decoratee().read_data(buf, max));
}
int write_data(const char* const buf, const int len) override {
- return get_decoratee().write_data(buf, len);
+ EXCPT_TO_RC(get_decoratee().write_data(buf, len));
}
public:
}
int send_status(const int status, const char* const status_name) override {
- return get_decoratee().send_status(status, status_name);
+ EXCPT_TO_RC(get_decoratee().send_status(status, status_name));
}
int send_100_continue() override {
- return get_decoratee().send_100_continue();
+ EXCPT_TO_RC(get_decoratee().send_100_continue());
}
int send_content_length(const uint64_t len) override {
- return get_decoratee().send_content_length(len);
+ EXCPT_TO_RC(get_decoratee().send_content_length(len));
}
int complete_header() override {
- return get_decoratee().complete_header();
+ EXCPT_TO_RC(get_decoratee().complete_header());
}
void flush() override {
- return get_decoratee().flush();
+ EXCPT_TO_VOID(get_decoratee().flush());
}
- RGWEnv& get_env() override {
+ RGWEnv& get_env() noexcept override {
return get_decoratee().get_env();
}
int complete_request() override {
- return get_decoratee().complete_request();
+ EXCPT_TO_RC(get_decoratee().complete_request());
}
};
return get_decoratee().flush();
}
- RGWEnv& get_env() override {
+ RGWEnv& get_env() noexcept override {
return get_decoratee().get_env();
}
int RGWFCGX::write_data(const char* const buf, const int len)
{
- return FCGX_PutStr(buf, len, fcgx->out);
+ const auto ret = FCGX_PutStr(buf, len, fcgx->out);
+ if (ret < 0) {
+ throw RGWStreamIOEngine::Exception(ret);
+ }
+ return ret;
}
int RGWFCGX::read_data(char* const buf, const int len)
{
- return FCGX_GetStr(buf, len, fcgx->in);
+ const auto ret = FCGX_GetStr(buf, len, fcgx->in);
+ if (ret < 0) {
+ throw RGWStreamIOEngine::Exception(ret);
+ }
+ return ret;
}
void RGWFCGX::flush()
void flush();
- RGWEnv& get_env() override {
+ RGWEnv& get_env() noexcept override {
return env;
}
int complete_header();
int send_content_length(uint64_t len);
- RGWEnv& get_env() override {
+ RGWEnv& get_env() noexcept override {
return env;
}
void flush();
- RGWEnv& get_env() override {
+ RGWEnv& get_env() noexcept override {
return env;
}