: conn(conn),
explicit_keepalive(false),
explicit_conn_close(false),
+ got_eof_on_read(false),
txbuf(*this)
{
sockaddr *lsa = mg_get_local_addr(conn);
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(EIO, std::system_category());
+ int c, ret;
+ if (got_eof_on_read) {
+ return 0;
+ }
+ for (c = 0; c < len; c += ret) {
+ ret = mg_read(conn, buf+c, len-c);
+ if (ret < 0) {
+ throw rgw::io::Exception(EIO, std::system_category());
+ }
+ if (!ret) {
+ got_eof_on_read = true;
+ break;
+ }
}
- return ret;
+ return c;
}
void RGWCivetWeb::flush()
return 0;
}
-void RGWCivetWeb::init_env(CephContext *cct)
+int RGWCivetWeb::init_env(CephContext *cct)
{
env.init(cct);
const struct mg_request_info* info = mg_get_request_info(conn);
if (! info) {
- return;
+ // request info is NULL; we have no info about the connection
+ return -EINVAL;
}
for (int i = 0; i < info->num_headers; i++) {
const struct mg_request_info::mg_header* header = &info->http_headers[i];
+
+ if (header->name == nullptr || header->value==nullptr) {
+ lderr(cct) << "client supplied malformatted headers" << dendl;
+ return -EINVAL;
+ }
+
const boost::string_ref name(header->name);
const auto& value = header->value;
env.set(buf, value);
}
+ env.set("REMOTE_ADDR", info->remote_addr);
env.set("REQUEST_METHOD", info->request_method);
- env.set("REQUEST_URI", info->uri);
+ env.set("HTTP_VERSION", info->http_version);
+ env.set("REQUEST_URI", info->request_uri); // get the full uri, we anyway handle abs uris later
env.set("SCRIPT_URI", info->uri); /* FIXME */
if (info->query_string) {
env.set("QUERY_STRING", info->query_string);
if (info->is_ssl) {
env.set("SERVER_PORT_SECURE", port_buf);
}
+ return 0;
}
size_t RGWCivetWeb::send_status(int status, const char *status_name)