yield[ec]);
if (ec) {
ldout(cct, 4) << "write_data failed: " << ec.message() << dendl;
+ if (ec==boost::asio::error::broken_pipe) {
+ boost::system::error_code ec_ignored;
+ stream.lowest_layer().shutdown(tcp::socket::shutdown_both, ec_ignored);
+ }
throw rgw::io::Exception(ec.value(), std::system_category());
}
return bytes;
}
};
+// output the http version as a string, ie 'HTTP/1.1'
+struct http_version {
+ unsigned major_ver;
+ unsigned minor_ver;
+ explicit http_version(unsigned version)
+ : major_ver(version / 10), minor_ver(version % 10) {}
+};
+std::ostream& operator<<(std::ostream& out, const http_version& v) {
+ return out << "HTTP/" << v.major_ver << '.' << v.minor_ver;
+}
+
+// log an http header value or '-' if it's missing
+struct log_header {
+ const http::fields& fields;
+ http::field field;
+ std::string_view quote;
+ log_header(const http::fields& fields, http::field field,
+ std::string_view quote = "")
+ : fields(fields), field(field), quote(quote) {}
+};
+std::ostream& operator<<(std::ostream& out, const log_header& h) {
+ auto p = h.fields.find(h.field);
+ if (p == h.fields.end()) {
+ return out << '-';
+ }
+ return out << h.quote << p->value() << h.quote;
+}
+
using SharedMutex = ceph::async::SharedMutex<boost::asio::io_context::executor_type>;
template <typename Stream>
ldout(cct, 20) << "failed to read header: " << ec.message() << dendl;
return;
}
+ auto& message = parser.get();
if (ec) {
ldout(cct, 1) << "failed to read header: " << ec.message() << dendl;
- auto& message = parser.get();
http::response<http::empty_body> response;
response.result(http::status::bad_request);
response.version(message.version() == 10 ? 10 : 11);
&real_client))));
RGWRestfulIO client(cct, &real_client_io);
auto y = optional_yield{context, yield};
+ int http_ret = 0;
process_request(env.store, env.rest, &req, env.uri_prefix,
- *env.auth_registry, &client, env.olog, y, scheduler);
+ *env.auth_registry, &client, env.olog, y,
+ scheduler, &http_ret);
+
+ if (cct->_conf->subsys.should_gather(dout_subsys, 1)) {
+ // access log line elements begin per Apache Combined Log Format with additions following
+ const auto now = ceph::coarse_real_clock::now();
+ using ceph::operator<<; // for coarse_real_time
+ ldout(cct, 1) << "beast: " << hex << &req << dec << ": "
+ << remote_endpoint.address() << " - - [" << now << "] \""
+ << message.method_string() << ' ' << message.target() << ' '
+ << http_version{message.version()} << "\" " << http_ret << ' '
+ << client.get_bytes_sent() + client.get_bytes_received() << ' '
+ << log_header{message, http::field::referer, "\""} << ' '
+ << log_header{message, http::field::user_agent, "\""} << ' '
+ << log_header{message, http::field::range} << dendl;
+ }
}
if (!parser.keep_alive()) {