Skip to content

Commit 66430cb

Browse files
Merge pull request #9 from PelicanPlatform/issue-7
Fix issue with host header and canonicalURI
2 parents fa09814 + e4676a2 commit 66430cb

File tree

2 files changed

+31
-38
lines changed

2 files changed

+31
-38
lines changed

src/S3Commands.cc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ std::string AmazonRequest::canonicalizeQueryString() {
3434
return AWSv4Impl::canonicalizeQueryString( query_parameters );
3535
}
3636

37+
// Takes in the configured `s3.service_url` and uses the bucket/object requested to generate
38+
// the virtual host URL, as well as the canonical URI (which is the path to the object).
3739
bool AmazonRequest::parseURL( const std::string & url,
40+
const std::string & bucket,
41+
const std::string & object,
3842
std::string & host,
3943
std::string & path ) {
4044
auto i = url.find( "://" );
@@ -43,13 +47,13 @@ bool AmazonRequest::parseURL( const std::string & url,
4347

4448
auto j = url.find( "/", i + 3 );
4549
if( j == std::string::npos ) {
46-
host = substring( url, i + 3 );
47-
path = "/";
50+
host = bucket + "." + substring( url, i + 3 );
51+
path = "/" + object;
4852
return true;
4953
}
5054

51-
host = substring( url, i + 3, j );
52-
path = substring( url, j );
55+
host = bucket + "." + substring( url, i + 3, j );
56+
path = substring( url, j ) + object;
5357
return true;
5458
}
5559

@@ -164,7 +168,7 @@ bool AmazonRequest::createV4Signature( const std::string & payload,
164168
std::string payloadHash;
165169
convertMessageDigestToLowercaseHex( messageDigest, mdLength, payloadHash );
166170
if( sendContentSHA ) {
167-
headers[ "x-amz-content-sha256" ] = payloadHash;
171+
headers[ "X-Amz-Content-Sha256" ] = payloadHash;
168172
}
169173

170174
// The canonical list of headers is a sorted list of lowercase header

src/S3Commands.hh

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,33 @@ public:
99
const std::string & s,
1010
const std::string & akf,
1111
const std::string & skf,
12+
const std::string & b,
13+
const std::string & o,
1214
int sv = 4
1315
) :
1416
HTTPRequest( s ),
1517
accessKeyFile(akf),
1618
secretKeyFile(skf),
17-
signatureVersion(sv)
19+
signatureVersion(sv),
20+
bucket(b),
21+
object(o)
1822
{
1923
requiresSignature = true;
20-
if (! parseURL(hostUrl, host, canonicalURI)) {
24+
// Start off by parsing the hostUrl, which we use in conjunction with the bucket to fill in the host (for setting host header).
25+
// For example, if the incoming hostUrl (which we get from config) is "https://my-url.com:443", the bucket is "my-bucket", and
26+
// the object is "my-object", then the host will be "my-bucket.my-url.com:443" and the canonicalURI will be "/my-object".
27+
if (! parseURL(hostUrl, b, o, host, canonicalURI)) {
2128
errorCode = "E_INVALID_SERVICE_URL";
2229
errorMessage = "Failed to parse host and canonicalURI from service URL.";
2330
}
2431

2532
if( canonicalURI.empty() ) { canonicalURI = "/"; }
2633

34+
// Now that we have the host and canonicalURI, we can build the actual url we perform the curl against.
35+
// Using the previous example, we'd get a new hostUrl of "https://my-bucket.my-url.com:443/my-object".
36+
hostUrl = protocol + "://" +
37+
host + canonicalURI;
38+
2739
// If we can, set the region based on the host.
2840
size_t secondDot = host.find( ".", 2 + 1 );
2941
if( host.find( "s3." ) == 0 ) {
@@ -38,6 +50,8 @@ public:
3850
return &secretKeyFile; }
3951

4052
bool parseURL( const std::string & url,
53+
const std::string & bucket,
54+
const std::string & object,
4155
std::string & host,
4256
std::string & path );
4357

@@ -57,6 +71,9 @@ protected:
5771
std::string host;
5872
std::string canonicalURI;
5973

74+
std::string bucket;
75+
std::string object;
76+
6077
std::string region;
6178
std::string service;
6279

@@ -76,21 +93,13 @@ public:
7693
const std::string & b,
7794
const std::string & o
7895
) :
79-
AmazonRequest(s, akf, skf),
80-
bucket(b),
81-
object(o)
82-
{
83-
hostUrl = protocol + "://" + bucket + "." +
84-
host + canonicalURI + object;
85-
}
96+
AmazonRequest(s, akf, skf, b, o){}
8697

8798
virtual ~AmazonS3Upload();
8899

89100
virtual bool SendRequest( const std::string & payload, off_t offset, size_t size );
90101

91102
protected:
92-
std::string bucket;
93-
std::string object;
94103
std::string path;
95104
};
96105

@@ -104,21 +113,11 @@ public:
104113
const std::string & b,
105114
const std::string & o
106115
) :
107-
AmazonRequest(s, akf, skf),
108-
bucket(b),
109-
object(o)
110-
{
111-
hostUrl = protocol + "://" + bucket + "." +
112-
host + canonicalURI + object;
113-
}
116+
AmazonRequest(s, akf, skf, b, o){}
114117

115118
virtual ~AmazonS3Download();
116119

117120
virtual bool SendRequest( off_t offset, size_t size );
118-
119-
protected:
120-
std::string bucket;
121-
std::string object;
122121
};
123122

124123
class AmazonS3Head : public AmazonRequest {
@@ -131,21 +130,11 @@ public:
131130
const std::string & b,
132131
const std::string & o
133132
) :
134-
AmazonRequest(s, akf, skf),
135-
bucket(b),
136-
object(o)
137-
{
138-
hostUrl = protocol + "://" + bucket + "." +
139-
host + canonicalURI + object;
140-
}
133+
AmazonRequest(s, akf, skf, b, o){}
141134

142135
virtual ~AmazonS3Head();
143136

144137
virtual bool SendRequest();
145-
146-
protected:
147-
std::string bucket;
148-
std::string object;
149138
};
150139

151140
#endif /* S3_COMMANDS_H */

0 commit comments

Comments
 (0)