New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rgw: swift: The http referer should be parsed to compare in swift API #13005
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Jing-Scott: Overall this PR looks good. Some minor changes are needed.
url_spec.length(), url_spec); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool get_http_host(std::string url, std::string& http_host) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SUGGESTION: may we take the url
parameter as boost::string_ref
and return boost::optional<boost::string_ref>
? Then method signature would look like following one:
boost::optional<boost::string_ref> get_http_host(const boost::string_ref url) const
url_spec.length(), url_spec); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool get_http_host(std::string url, std::string& http_host) const { | ||
int pos = url.find("://"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please switch to size_t
?
url_spec.length(), url_spec); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool get_http_host(std::string url, std::string& http_host) const { | ||
int pos = url.find("://"); | ||
if (pos < 0 || pos == (int)url.size() - 3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please compare with the npos
member of a corresponding string class.
url_spec.length(), url_spec); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool get_http_host(std::string url, std::string& http_host) const { | ||
int pos = url.find("://"); | ||
if (pos < 0 || pos == (int)url.size() - 3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No magics, please. Consider boost::string_ref::ends_with
, boost::algorithm::ends_with
or even strlen("://")
.
url_spec.length(), url_spec); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool get_http_host(std::string url, std::string& http_host) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to make this method public
.
return false; | ||
|
||
string scheme = url.substr(0, pos); | ||
if (scheme.empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe starts_with("://")
in the previous if
?
|
||
string url_sub = url.substr(pos + 3); | ||
pos = url_sub.find('@'); | ||
if (pos == (int)url_sub.size()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I would say this condition is always false.
if (pos == (int)url_sub.size()) | ||
return false; | ||
|
||
url_sub = url_sub.substr(pos + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If url_sub
doesn't contain @
then we're doing std::string::npos + 1
which results to 0
on most implementations. However, this isn't a way to go.
@rzarzynski |
The http referer should be parsed to compare with the url set on the container read acl. If we set .r:www.example.com on container read acl, we should parse the hostname 'www.example.com' of the http referer like 'http://www.example.com' from the http request. Fixes: http://tracker.ceph.com/issues/18685 Signed-off-by: Jing Wenjun <jingwenjun@cmss.chinamobile.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only cosmetic changes needed. We're getting close. :-)
if (!get_http_host(http_referer, http_host)) | ||
bool is_match(boost::string_ref http_referer) const { | ||
boost::optional<boost::string_ref> http_host = get_http_host(http_referer); | ||
if ((*http_host).empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In get_http_host
you might want to return boost::none
if parsing fails. Then this conditional would look like:
if (! http_host) {
return false;
}
return true; | ||
} | ||
|
||
if (http_host.length() < url_spec.length()) { | ||
if ((*http_host).length() < host_spec.length()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
boost::optional
has overloads for the ->
operator, so you may write here (and in others places) just:
if (http_host->length() < host_spec.length()) {
/* Wildcard support: a referer matches the spec when its last char are | ||
* perfectly equal to spec. */ | ||
return !http_host.compare(http_host.length() - url_spec.length(), | ||
url_spec.length(), url_spec); | ||
return (*http_host).ends_with(host_spec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, now the code is really much easier to understand. I missed the opportunity for ends_with
last time. Thanks for applying it here!
std::string http_host; | ||
if (!get_http_host(http_referer, http_host)) | ||
bool is_match(boost::string_ref http_referer) const { | ||
boost::optional<boost::string_ref> http_host = get_http_host(http_referer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe const
here?
BTW: using auto
is also perfectly fine in the project.
size_t pos = url.find("://"); | ||
if (pos == boost::string_ref::npos || url.starts_with("://") || | ||
url.ends_with("://") || url.ends_with('@')) { | ||
return boost::string_ref(nullptr, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would propose returning boost::none
(according to one of the comments above).
8a3c09d
to
4129291
Compare
@rzarzynski |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes! Could you please also prepend the link to tracker issue with the Fixes
tag? That and squashing commits would help with backporting the fix to Kraken and Jewel.
/* Wildcard support: a referer matches the spec when its last char are | ||
* perfectly equal to spec. */ | ||
return !http_referer.compare(http_referer.length() - url_spec.length(), | ||
url_spec.length(), url_spec); | ||
return (*http_host).ends_with(host_spec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ->
operator can be applied here as well. I've missed that last time, sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, it's my carelessness!
return false; | ||
} | ||
|
||
boost::string_ref host_spec(url_spec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'm not sure whether we really need the host_spec
temporary. IIUC boost::string_ref
has the operator==
overload for std::string
so we could compare *http_host
directly with url_spec
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if using operator==
like *http_host == url_spec
directly, it will return error. So here I use ->compare
to compare http_host
with url_spec
insteaded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ouch, my fault. Sorry.
4129291
to
c262931
Compare
Hi, @rzarzynski |
c262931
to
941dfad
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very good, thanks! I will schedule a Teuthology run soon.
The Teuthology run looks good to me. There is one but unrelated failure. Merging. |
The http referer should be parsed to compare with the url set on the container read acl. If we set .r:www.example.com on container read acl, we should parse the hostname 'www.example.com' of the http referer like 'http://www.example.com' from the http request.
Signed-off-by: Jing Wenjun jingwenjun@cmss.chinamobile.com