}
dest.append("\n");
- if (canonical_qs)
+ if (canonical_qs) {
dest.append(canonical_qs);
+ }
dest.append("\n");
if (canonical_hdrs)
return true;
}
-static void escape_char(char c, string& dst)
+void rgw_uri_escape_char(char c, string& dst)
{
char buf[16];
snprintf(buf, sizeof(buf), "%%%.2X", (int)(unsigned char)c);
const char *p = src.c_str();
for (unsigned i = 0; i < src.size(); i++, p++) {
if (char_needs_url_encoding(*p)) {
- escape_char(*p, dst);
+ rgw_uri_escape_char(*p, dst);
continue;
}
extern bool verify_object_permission(struct req_state *s, int perm);
/** Convert an input URL into a sane object name
* by converting %-escaped strings into characters, etc*/
+extern void rgw_uri_escape_char(char c, string& dst);
extern bool url_decode(const string& src_str, string& dest_str, bool in_query = false);
extern void url_encode(const string& src, string& dst, bool in_query = false);
return (isalnum(c) || isspace(c) || (c == '+') || (c == '/') || (c == '='));
}
+static bool char_needs_aws4_escaping(char c)
+{
+ if ((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9')) {
+ return false;
+ }
+
+ switch (c) {
+ case '-':
+ case '_':
+ case '.':
+ case '~':
+ return false;
+ }
+ return true;
+}
+
+static void aws4_uri_encode(const string& src, string& dst)
+{
+ const char *p = src.c_str();
+ for (unsigned i = 0; i < src.size(); i++, p++) {
+ if (char_needs_aws4_escaping(*p)) {
+ rgw_uri_escape_char(*p, dst);
+ continue;
+ }
+
+ dst.append(p, 1);
+ }
+}
+
/*
* handle v4 signatures (rados auth only)
*/
getline(kv, key, '=');
getline(kv, val, '=');
if (!using_qs || key != "X-Amz-Signature") {
- canonical_qs_map[key] = val;
+ string encoded_key;
+ string encoded_val;
+
+ aws4_uri_encode(key, encoded_key);
+ aws4_uri_encode(val, encoded_val);
+
+ canonical_qs_map[encoded_key] = encoded_val;
}
}