aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/IO/S3/Requests.cpp
blob: 56d2e44a2c42a9f8a159f296c008e3c8639f4c84 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <IO/S3/Requests.h>

#if USE_AWS_S3

#include <Common/logger_useful.h>
#include <aws/core/endpoint/EndpointParameter.h>
#include <aws/core/utils/xml/XmlSerializer.h>

namespace DB::S3
{

Aws::Http::HeaderValueCollection CopyObjectRequest::GetRequestSpecificHeaders() const
{
    auto headers = Model::CopyObjectRequest::GetRequestSpecificHeaders();
    if (api_mode != ApiMode::GCS)
        return headers;

    /// GCS supports same headers as S3 but with a prefix x-goog instead of x-amz
    /// we have to replace all the prefixes client set internally
    const auto replace_with_gcs_header = [&](const std::string & amz_header, const std::string & gcs_header)
    {
        if (const auto it = headers.find(amz_header); it != headers.end())
        {
            auto header_value = std::move(it->second);
            headers.erase(it);
            headers.emplace(gcs_header, std::move(header_value));
        }
    };

    replace_with_gcs_header("x-amz-copy-source", "x-goog-copy-source");
    replace_with_gcs_header("x-amz-metadata-directive", "x-goog-metadata-directive");
    replace_with_gcs_header("x-amz-storage-class", "x-goog-storage-class");

    /// replace all x-amz-meta- headers
    std::vector<std::pair<std::string, std::string>> new_meta_headers;
    for (auto it = headers.begin(); it != headers.end();)
    {
        if (it->first.starts_with("x-amz-meta-"))
        {
            auto value = std::move(it->second);
            auto header = "x-goog" + it->first.substr(/* x-amz */ 5);
            new_meta_headers.emplace_back(std::pair{std::move(header), std::move(value)});
            it = headers.erase(it);
        }
        else
            ++it;
    }

    for (auto & [header, value] : new_meta_headers)
        headers.emplace(std::move(header), std::move(value));

    return headers;
}

Aws::String ComposeObjectRequest::SerializePayload() const
{
    if (component_names.empty())
        return {};

    Aws::Utils::Xml::XmlDocument payload_doc = Aws::Utils::Xml::XmlDocument::CreateWithRootNode("ComposeRequest");
    auto root_node = payload_doc.GetRootElement();

    for (const auto & name : component_names)
    {
        auto component_node = root_node.CreateChildElement("Component");
        auto name_node = component_node.CreateChildElement("Name");
        name_node.SetText(name);
    }

    return payload_doc.ConvertToString();
}

void ComposeObjectRequest::AddQueryStringParameters(Aws::Http::URI & /*uri*/) const
{
}

Aws::Http::HeaderValueCollection ComposeObjectRequest::GetRequestSpecificHeaders() const
{
    if (content_type.empty())
        return {};

    return {Aws::Http::HeaderValuePair(Aws::Http::CONTENT_TYPE_HEADER, content_type)};
}

Aws::Endpoint::EndpointParameters ComposeObjectRequest::GetEndpointContextParams() const
{
    EndpointParameters parameters;
    if (BucketHasBeenSet())
        parameters.emplace_back("Bucket", GetBucket(), Aws::Endpoint::EndpointParameter::ParameterOrigin::OPERATION_CONTEXT);

    return parameters;
}

const Aws::String & ComposeObjectRequest::GetBucket() const
{
    return bucket;
}

bool ComposeObjectRequest::BucketHasBeenSet() const
{
    return !bucket.empty();
}

void ComposeObjectRequest::SetBucket(const Aws::String & value)
{
    bucket = value;
}

void ComposeObjectRequest::SetBucket(Aws::String && value)
{
    bucket = std::move(value);
}

void ComposeObjectRequest::SetBucket(const char * value)
{
    bucket.assign(value);
}

const Aws::String & ComposeObjectRequest::GetKey() const
{
    return key;
}

bool ComposeObjectRequest::KeyHasBeenSet() const
{
    return !key.empty();
}

void ComposeObjectRequest::SetKey(const Aws::String & value)
{
    key = value;
}

void ComposeObjectRequest::SetKey(Aws::String && value)
{
    key = std::move(value);
}

void ComposeObjectRequest::SetKey(const char * value)
{
    key.assign(value);
}

void ComposeObjectRequest::SetComponentNames(std::vector<Aws::String> component_names_)
{
    component_names = std::move(component_names_);
}

void ComposeObjectRequest::SetContentType(Aws::String value)
{
    content_type = std::move(value);
}

}

#endif