diff --git a/src/Request.cc b/src/Request.cc index dfdfff19..82f7f4e7 100644 --- a/src/Request.cc +++ b/src/Request.cc @@ -108,9 +108,16 @@ bool Request::redirectUri(const std::string& uri) { return false; } std::string redirectedUri; - if(uri.find("://") == std::string::npos) { + if(util::startsWith(uri, "//")) { + // Network-path reference (according to RFC 3986, Section 4.2) + // Just complement current protocol. + 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(); diff --git a/test/RequestTest.cc b/test/RequestTest.cc index 3f71fe7c..d21af8e7 100644 --- a/test/RequestTest.cc +++ b/test/RequestTest.cc @@ -137,6 +137,11 @@ void RequestTest::testRedirectUri() "relativepath/to/file"), req.getCurrentUri()); CPPUNIT_ASSERT_EQUAL(4, req.getRedirectCount()); + + // Give network-path reference + CPPUNIT_ASSERT(req.redirectUri("//host/to/file")); + CPPUNIT_ASSERT_EQUAL(std::string("http://host/to/file"), req.getCurrentUri()); + CPPUNIT_ASSERT_EQUAL(5, req.getRedirectCount()); } void RequestTest::testRedirectUri2()