Chromium Code Reviews| 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..19467587f59887f68fe7d2eff36a4f231bc824e2 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_location, |
|
mmenke
2016/06/29 15:05:09
Could you rename original_location to original_url
estark
2016/06/29 17:44:25
Done.
|
| + const char* referer_header, |
| + const char* response_headers, |
| + MockTransaction* transaction) { |
| + transaction->url = original_location; |
| + 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_location).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_location; |
|
mmenke
2016/06/29 15:05:09
location -> original_url
estark
2016/06/29 17:44:25
Done.
|
| + 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" /* location */, |
|
mmenke
2016/06/29 15:05:09
Similar to above comment, location -> original_url
estark
2016/06/29 17:44:25
Done.
|
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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" /* location */, |
| + "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_location, |
| + 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; |