From: Yehuda Sadeh Date: Fri, 6 Jul 2012 20:14:53 +0000 (-0700) Subject: rgw: handle response-* params X-Git-Tag: v0.49~26 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=97c1562dda2b0f3370bb186e7acbcd9c273210bc;p=ceph.git rgw: handle response-* params Handle response-* params that set response header field values. Fixes #2734, #2735. Backport: argonaut Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 3ff0792b5d2f..9aeb24a1a04b 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -294,16 +294,28 @@ int XMLArgs::parse() NameVal nv(nameval); int ret = nv.parse(); if (ret >= 0) { - val_map[nv.get_name()] = nv.get_val(); - - if ((nv.get_name().compare("acl") == 0) || - (nv.get_name().compare("location") == 0) || - (nv.get_name().compare("uploads") == 0) || - (nv.get_name().compare("partNumber") == 0) || - (nv.get_name().compare("uploadId") == 0) || - (nv.get_name().compare("versionid") == 0) || - (nv.get_name().compare("torrent") == 0)) { - sub_resources[nv.get_name()] = nv.get_val(); + string& name = nv.get_name(); + string& val = nv.get_val(); + val_map[name] = val; + + if ((name.compare("acl") == 0) || + (name.compare("location") == 0) || + (name.compare("uploads") == 0) || + (name.compare("partNumber") == 0) || + (name.compare("uploadId") == 0) || + (name.compare("versionId") == 0) || + (name.compare("torrent") == 0)) { + sub_resources[name] = val; + } else if (name[0] == 'r') { // root of all evil + if ((name.compare("response-content-type") == 0) || + (name.compare("response-content-language") == 0) || + (name.compare("response-expires") == 0) || + (name.compare("response-cache-control") == 0) || + (name.compare("response-content-disposition") == 0) || + (name.compare("response-content-encoding") == 0)) { + sub_resources[name] = val; + has_resp_modifier = true; + } } } @@ -313,19 +325,22 @@ int XMLArgs::parse() return 0; } -string& XMLArgs::get(string& name) +string& XMLArgs::get(string& name, bool *exists) { map::iterator iter; iter = val_map.find(name); - if (iter == val_map.end()) - return empty_str; - return iter->second; + bool e = (iter != val_map.end()); + if (exists) + *exists = e; + if (e) + return iter->second; + return empty_str; } -string& XMLArgs::get(const char *name) +string& XMLArgs::get(const char *name, bool *exists) { string s(name); - return get(s); + return get(s, exists); } bool verify_bucket_permission(struct req_state *s, int perm) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index aa525718e864..22f69f45ac77 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -210,16 +210,22 @@ class XMLArgs string str, empty_str; map val_map; map sub_resources; + + bool has_resp_modifier; public: - XMLArgs() {} - XMLArgs(string s) : str(s) {} + XMLArgs() : has_resp_modifier(false) {} /** Set the arguments; as received */ - void set(string s) { val_map.clear(); sub_resources.clear(); str = s; } + void set(string s) { + has_resp_modifier = false; + val_map.clear(); + sub_resources.clear(); + str = s; + } /** parse the received arguments */ int parse(); /** Get the value for a specific argument parameter */ - string& get(string& name); - string& get(const char *name); + string& get(string& name, bool *exists = NULL); + string& get(const char *name, bool *exists = NULL); /** see if a parameter is contained in this XMLArgs */ bool exists(const char *name) { map::iterator iter = val_map.find(name); @@ -230,6 +236,10 @@ class XMLArgs return (iter != sub_resources.end()); } map& get_sub_resources() { return sub_resources; } + + bool has_response_modifier() { + return has_resp_modifier; + } }; class RGWConf; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index b6f0fa11c550..968b329d2ef2 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -41,6 +41,7 @@ void dump_bucket(struct req_state *s, RGWBucketEnt& obj) int RGWGetObj_REST_S3::send_response(bufferlist& bl) { + string content_type_str; const char *content_type = NULL; int orig_ret = ret; @@ -66,6 +67,28 @@ int RGWGetObj_REST_S3::send_response(bufferlist& bl) } } + if (s->args.has_response_modifier()) { + bool exists; + content_type_str = s->args.get("response-content-type", &exists); + if (exists) + content_type = content_type_str.c_str(); + string val = s->args.get("response-content-language", &exists); + if (exists) + CGI_PRINTF(s, "Content-Language: %s\n", val.c_str()); + val = s->args.get("response-expires", &exists); + if (exists) + CGI_PRINTF(s, "Expires: %s\n", val.c_str()); + val = s->args.get("response-cache-control", &exists); + if (exists) + CGI_PRINTF(s, "Cache-Control: %s\n", val.c_str()); + val = s->args.get("response-content-disposition", &exists); + if (exists) + CGI_PRINTF(s, "Content-Disposition: %s\n", val.c_str()); + val = s->args.get("response-content-encoding", &exists); + if (exists) + CGI_PRINTF(s, "Content-Encoding: %s\n", val.c_str()); + } + for (iter = attrs.begin(); iter != attrs.end(); ++iter) { const char *name = iter->first.c_str(); if (strncmp(name, RGW_ATTR_META_PREFIX, sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {