diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2012-02-15 01:40:12 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2012-02-15 01:40:12 +0900 |
| commit | b7dbcea58bf0fea8792a653a64d8a87ae584d839 (patch) | |
| tree | 2d63a3939f0bee56d3ee36c16b6b9b48c17193da /src/Request.cc | |
| parent | 9e302b86df6ed9ada7399c91fb33a8d955912d59 (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.cc | 50 |
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); } |
