1#include <s3api/s3_connection.hpp>
3#include <userver/clients/http/client.hpp>
4#include <userver/http/common_headers.hpp>
5#include <userver/logging/log.hpp>
6#include <userver/s3api/models/request.hpp>
13clients::http::Request& GetMethod(
14 clients::http::Request& req,
16 std::string_view body,
23 return req
.get(std::string{url}
);
25 return req
.head(std::string{url}
);
27 return req
.post(std::string{url}
, std::string{body}
);
29 return req
.put(std::string{url}
, std::string{body}
);
33 throw std::runtime_error(
"Unknown http method");
44std::string
S3Connection::MakeHostHeader(std::string_view api_url, std::string_view bucket) {
45 const auto schema_pos = api_url.find(
"://");
46 auto authority = schema_pos == std::string_view::npos ? api_url : api_url.substr(schema_pos + 3);
48 const auto path_pos = authority.find(
'/');
49 if (path_pos != std::string_view::npos) {
50 authority = authority.substr(0, path_pos);
53 if (!bucket.empty()) {
54 return fmt::format(
"{}.{}", bucket, authority);
57 return std::string{authority};
60std::string
S3Connection::GetHostHeader(
const Request& r)
const {
return MakeHostHeader(api_url_, r.bucket); }
62std::shared_ptr<clients::http::Response>
S3Connection::RequestApi(
Request& r, std::string_view method_name) {
63 r.headers
[USERVER_NAMESPACE::http::
headers::kHost
] = GetHostHeader(r);
66 const std::string full_url = GetUrl(r, connection_type_);
67 LOG_DEBUG() <<
"S3 file full_url: " << full_url;
72 if (config_.proxy.has_value()) {
73 http_req
.proxy(config_.proxy.value()
);
78 std::shared_ptr<clients::http::Response> response;
80 response = GetMethod(http_req, full_url, r.body, r.method)
.perform();
83 LOG_WARNING() <<
"S3Api : Http Request Timeout: " << full_url;
86 LOG_INFO() <<
"S3Api : Http Request to mds failed " << response->
body() <<
" : " << full_url;
92std::shared_ptr<clients::http::Response>
S3Connection::DoStartApiRequest(
const Request& r)
const {
93 auto headers = r.headers;
94 headers
[USERVER_NAMESPACE::http::
headers::kHost
] = GetHostHeader(r);
96 const std::string full_url = GetUrl(r, connection_type_);
100 return GetMethod(http_req, full_url, r.body, r.method)
.perform();
103std::shared_ptr<clients::http::Response>
S3Connection::StartApiRequest(
const Request& request)
const {
104 return DoStartApiRequest(request);
107std::string
S3Connection::GetUrl(
const Request& r, S3ConnectionType connection_type)
const {
108 std::string full_url = api_url_;
109 const bool is_localhost = api_url_.find(
"localhost:") != std::string::npos;
110 const auto schema_pos = full_url.find(
"://");
111 if (schema_pos == std::string::npos) {
112 if (!is_localhost && !r.bucket.empty()) {
113 full_url = fmt::format(
"{}.{}", r.bucket, api_url_);
115 if (connection_type == S3ConnectionType::kHttps) {
116 full_url =
"https://" + full_url;
118 full_url =
"http://" + full_url;
121 if (!is_localhost && !r.bucket.empty()) {
122 const auto schema = full_url.substr(0, schema_pos);
123 const auto schemaless_url = full_url.substr(schema_pos + 3);
124 full_url = fmt::format(
"{}://{}.{}", schema, r.bucket, schemaless_url);
127 if (!r.req.empty()) {
135 clients::http::
Client& http_client,
136 S3ConnectionType connection_type,
137 std::string server_url,
140 return std::make_shared<
S3Connection>(http_client, connection_type, std::move(server_url), params);