| Index: net/url_request/url_request_job_unittest.cc
|
| diff --git a/net/url_request/url_request_job_unittest.cc b/net/url_request/url_request_job_unittest.cc
|
| index 61d9188f540bf3290330aa8b54eafa3ec3b43eef..4583aa83d85b95355e8f9e42aeb894c18fc23f3e 100644
|
| --- a/net/url_request/url_request_job_unittest.cc
|
| +++ b/net/url_request/url_request_job_unittest.cc
|
| @@ -9,6 +9,8 @@
|
| #include "base/run_loop.h"
|
| #include "net/base/request_priority.h"
|
| #include "net/http/http_transaction_test_util.h"
|
| +#include "net/test/cert_test_util.h"
|
| +#include "net/test/test_data_directory.h"
|
| #include "net/url_request/url_request.h"
|
| #include "net/url_request/url_request_test_util.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -61,6 +63,32 @@ void BrotliHelloServer(const HttpRequestInfo* request,
|
| response_data->assign(kBrotliHelloData, sizeof(kBrotliHelloData) - 1);
|
| }
|
|
|
| +void MakeMockReferrerPolicyTransaction(const char* original_url,
|
| + const char* referer_header,
|
| + const char* response_headers,
|
| + MockTransaction* transaction) {
|
| + transaction->url = original_url;
|
| + transaction->method = "GET";
|
| + transaction->request_time = base::Time();
|
| + transaction->request_headers = referer_header;
|
| + transaction->load_flags = LOAD_NORMAL;
|
| + transaction->status = "HTTP/1.1 302 Found";
|
| + transaction->response_headers = response_headers;
|
| + transaction->response_time = base::Time();
|
| + transaction->data = "hello";
|
| + transaction->test_mode = TEST_MODE_NORMAL;
|
| + transaction->handler = nullptr;
|
| + if (GURL(original_url).SchemeIsCryptographic()) {
|
| + transaction->cert =
|
| + net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
|
| + } else {
|
| + transaction->cert = nullptr;
|
| + }
|
| + transaction->cert_status = 0;
|
| + transaction->ssl_connection_status = 0;
|
| + transaction->return_code = OK;
|
| +}
|
| +
|
| const MockTransaction kGZip_Transaction = {
|
| "http://www.google.com/gzyp",
|
| "GET",
|
| @@ -233,6 +261,199 @@ TEST(URLRequestJob, RedirectTransactionNotifiedWhenDone) {
|
| RemoveMockTransaction(&kRedirect_Transaction);
|
| }
|
|
|
| +TEST(URLRequestJob, RedirectTransactionWithReferrerPolicyHeader) {
|
| + struct TestCase {
|
| + const char* original_url;
|
| + const char* original_referrer;
|
| + const char* response_headers;
|
| + URLRequest::ReferrerPolicy original_referrer_policy;
|
| + URLRequest::ReferrerPolicy expected_final_referrer_policy;
|
| + const char* expected_final_referrer;
|
| + };
|
| +
|
| + const TestCase kTests[] = {
|
| + // If a redirect serves 'Referrer-Policy: no-referrer', then the referrer
|
| + // should be cleared.
|
| + {"http://foo.test/one" /* original url */,
|
| + "http://foo.test/one" /* original referrer */,
|
| + "Location: http://foo.test/test\n"
|
| + "Referrer-Policy: no-referrer\n",
|
| + // original policy
|
| + URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
|
| + URLRequest::NO_REFERRER /* expected final policy */,
|
| + "" /* expected final referrer */},
|
| +
|
| + // Same as above but for the legacy keyword 'never'.
|
| + {"http://foo.test/one" /* original url */,
|
| + "http://foo.test/one" /* original referrer */,
|
| + "Location: http://foo.test/test\nReferrer-Policy: never\n",
|
| + // original policy
|
| + URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
|
| + URLRequest::NO_REFERRER /* expected final policy */,
|
| + "" /* expected final referrer */},
|
| +
|
| + // If a redirect serves 'Referrer-Policy:
|
| + // no-referrer-when-downgrade', then the referrer should be cleared
|
| + // on downgrade, even if the original request's policy specified
|
| + // that the referrer should never be cleared.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: http://foo.test\n"
|
| + "Referrer-Policy: no-referrer-when-downgrade\n",
|
| + URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
|
| + // expected final policy
|
| + URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
|
| + "" /* expected final referrer */},
|
| +
|
| + // Same as above but for the legacy keyword 'default'.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: http://foo.test\n"
|
| + "Referrer-Policy: default\n",
|
| + URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
|
| + // expected final policy
|
| + URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
|
| + "" /* expected final referrer */},
|
| +
|
| + // If a redirect serves 'Referrer-Policy: origin', then the referrer
|
| + // should be stripped to its origin, even if the original request's
|
| + // policy specified that the referrer should never be cleared.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: https://foo.test/two\n"
|
| + "Referrer-Policy: origin\n",
|
| + URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
|
| + URLRequest::ORIGIN /* expected final policy */,
|
| + "https://foo.test/" /* expected final referrer */},
|
| +
|
| + // If a redirect serves 'Referrer-Policy: origin-when-cross-origin',
|
| + // then the referrer should be untouched for a same-origin redirect...
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/referrer" /* original referrer */,
|
| + "Location: https://foo.test/two\n"
|
| + "Referrer-Policy: origin-when-cross-origin\n",
|
| + URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
|
| + URLRequest::
|
| + ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected final policy */,
|
| + "https://foo.test/referrer" /* expected final referrer */},
|
| +
|
| + // ... but should be stripped to the origin for a cross-origin redirect.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: https://bar.test/two\n"
|
| + "Referrer-Policy: origin-when-cross-origin\n",
|
| + URLRequest::NEVER_CLEAR_REFERRER /* original policy */,
|
| + URLRequest::
|
| + ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected final policy */,
|
| + "https://foo.test/" /* expected final referrer */},
|
| +
|
| + // If a redirect serves 'Referrer-Policy: unsafe-url', then the
|
| + // referrer should remain, even if originally set to clear on
|
| + // downgrade.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: https://bar.test/two\n"
|
| + "Referrer-Policy: unsafe-url\n",
|
| + URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
|
| + URLRequest::NEVER_CLEAR_REFERRER /* expected final policy */,
|
| + "https://foo.test/one" /* expected final referrer */},
|
| +
|
| + // Same as above but for the legacy keyword 'always'.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: https://bar.test/two\n"
|
| + "Referrer-Policy: always\n",
|
| + URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
|
| + URLRequest::NEVER_CLEAR_REFERRER /* expected final policy */,
|
| + "https://foo.test/one" /* expected final referrer */},
|
| +
|
| + // An invalid keyword should leave the policy untouched.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: https://bar.test/two\n"
|
| + "Referrer-Policy: not-a-valid-policy\n",
|
| + URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
|
| + URLRequest::
|
| + ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected final policy */,
|
| + "https://foo.test/" /* expected final referrer */},
|
| +
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: http://bar.test/two\n"
|
| + "Referrer-Policy: not-a-valid-policy\n",
|
| + // original policy
|
| + URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
|
| + // expected final policy
|
| + URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
|
| + "" /* expected final referrer */},
|
| +
|
| + // The last valid keyword should take precedence.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: https://bar.test/two\n"
|
| + "Referrer-Policy: unsafe-url\n"
|
| + "Referrer-Policy: not-a-valid-policy\n",
|
| + URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
|
| + URLRequest::NEVER_CLEAR_REFERRER /* expected final policy */,
|
| + "https://foo.test/one" /* expected final referrer */},
|
| +
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: https://bar.test/two\n"
|
| + "Referrer-Policy: unsafe-url\n"
|
| + "Referrer-Policy: origin\n",
|
| + URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
|
| + URLRequest::ORIGIN /* expected final policy */,
|
| + "https://foo.test/" /* expected final referrer */},
|
| +
|
| + // An empty header should not affect the request.
|
| + {"https://foo.test/one" /* original url */,
|
| + "https://foo.test/one" /* original referrer */,
|
| + "Location: https://bar.test/two\n"
|
| + "Referrer-Policy: \n",
|
| + URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* original policy */,
|
| + URLRequest::
|
| + ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN /* expected final policy */,
|
| + "https://foo.test/" /* expected final referrer */},
|
| + };
|
| +
|
| + for (const auto& test : kTests) {
|
| + MockTransaction transaction;
|
| + std::string request_headers =
|
| + "Referer: " + std::string(test.original_referrer) + "\n";
|
| + MakeMockReferrerPolicyTransaction(test.original_url,
|
| + request_headers.c_str(),
|
| + test.response_headers, &transaction);
|
| +
|
| + MockNetworkLayer network_layer;
|
| + TestURLRequestContext context;
|
| + context.set_enable_referrer_policy_header(true);
|
| + context.set_http_transaction_factory(&network_layer);
|
| +
|
| + TestDelegate d;
|
| + std::unique_ptr<URLRequest> req(
|
| + context.CreateRequest(GURL(transaction.url), DEFAULT_PRIORITY, &d));
|
| + AddMockTransaction(&transaction);
|
| +
|
| + req->set_referrer_policy(test.original_referrer_policy);
|
| + req->SetReferrer(test.original_referrer);
|
| +
|
| + req->set_method("GET");
|
| + req->Start();
|
| +
|
| + base::RunLoop().Run();
|
| +
|
| + EXPECT_TRUE(network_layer.done_reading_called());
|
| +
|
| + RemoveMockTransaction(&transaction);
|
| +
|
| + // Test that the referrer policy and referrer were set correctly
|
| + // according to the header received during the redirect.
|
| + EXPECT_EQ(test.expected_final_referrer_policy, req->referrer_policy());
|
| + EXPECT_EQ(test.expected_final_referrer, req->referrer());
|
| + }
|
| +}
|
| +
|
| TEST(URLRequestJob, TransactionNotCachedWhenNetworkDelegateRedirects) {
|
| MockNetworkLayer network_layer;
|
| TestNetworkDelegate network_delegate;
|
|
|