summaryrefslogtreecommitdiff
path: root/src/Request.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2012-02-15 01:40:12 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2012-02-15 01:40:12 +0900
commitb7dbcea58bf0fea8792a653a64d8a87ae584d839 (patch)
tree2d63a3939f0bee56d3ee36c16b6b9b48c17193da /src/Request.cc
parent9e302b86df6ed9ada7399c91fb33a8d955912d59 (diff)
Check scheme part in redirected URI more strictly.
The previous implementation mistakenly sees '/abspath?uri=http://foo' as an absolute URI because it contains '://', but actually it is not. This change checks scheme part is constructed in the allowed character set described in RFC 3986 Section 3.1.
Diffstat (limited to 'src/Request.cc')
-rw-r--r--src/Request.cc50
1 files changed, 34 insertions, 16 deletions
diff --git a/src/Request.cc b/src/Request.cc
index 82f7f4e7..b3ab8a21 100644
--- a/src/Request.cc
+++ b/src/Request.cc
@@ -114,23 +114,41 @@ bool Request::redirectUri(const std::string& uri) {
redirectedUri = getProtocol();
redirectedUri += ":";
redirectedUri += uri;
- } else if(uri.find("://") == std::string::npos) {
- // rfc2616 requires absolute URI should be provided by Location header
- // field, but some servers don't obey this rule.
- // UPDATE: draft-ietf-httpbis-p2-semantics-18 now allows this.
- uri::UriStruct rus(us_);
- rus.query.clear();
- rus.file.clear();
- size_t offset = 0;
- if(uri[0] == '/') {
- // abosulute path
- rus.dir.clear();
- offset = 1;
- }
- redirectedUri = uri::construct(rus);
- redirectedUri.append(uri.begin()+offset, uri.end());
} else {
- redirectedUri = uri;
+ std::string::size_type schemeEnd = uri.find("://");
+ bool absUri;
+ if(schemeEnd == std::string::npos) {
+ absUri = false;
+ } else {
+ absUri = true;
+ // Check that scheme is acceptable one.
+ for(size_t i = 0; i < schemeEnd; ++i) {
+ char c = uri[i];
+ if(!util::isAlpha(c) && !util::isDigit(c) &&
+ c != '+' && c != '-' && c != '.') {
+ absUri = false;
+ break;
+ }
+ }
+ }
+ if(absUri) {
+ redirectedUri = uri;
+ } else {
+ // rfc2616 requires absolute URI should be provided by Location header
+ // field, but some servers don't obey this rule.
+ // UPDATE: draft-ietf-httpbis-p2-semantics-18 now allows this.
+ uri::UriStruct rus(us_);
+ rus.query.clear();
+ rus.file.clear();
+ size_t offset = 0;
+ if(uri[0] == '/') {
+ // abosulute path
+ rus.dir.clear();
+ offset = 1;
+ }
+ redirectedUri = uri::construct(rus);
+ redirectedUri.append(uri.begin()+offset, uri.end());
+ }
}
return parseUri(redirectedUri);
}