1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/strings/string_util.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "net/base/net_errors.h" 15 #include "net/http/http_auth_challenge_tokenizer.h" 16 #include "net/http/http_request_info.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 namespace { 20 21 const char kValidOrigin[] = "https://www.proxy.com/"; 22 const char kValidOrigin2[] = "http://www.proxy2.com/"; 23 const char kValidChallenge[] = "SpdyProxy realm=\"SpdyProxy\", " 24 "ps=\"1-2-3-4\""; 25 26 } // namespace 27 28 namespace data_reduction_proxy { 29 30 using net::ERR_INVALID_RESPONSE; 31 using net::ERR_UNSUPPORTED_AUTH_SCHEME; 32 using net::OK; 33 using net::AuthCredentials; 34 using net::BoundNetLog; 35 using net::CompletionCallback; 36 using net::Error; 37 using net::HttpAuth; 38 using net::HttpAuthChallengeTokenizer; 39 using net::HttpAuthHandler; 40 using net::HttpRequestInfo; 41 42 TEST(HttpAuthHandlerDataReductionProxyTest, GenerateAuthToken) { 43 // Verifies that challenge parsing is expected as described in individual 44 // cases below. 45 static const struct { 46 Error err1, // Expected response from hander creation 47 err2; // Expected response from GenerateAuthToken 48 const char* origin; // Origin for challenge 49 const char* challenge; // Challenge string 50 const char* expected_credentials; 51 } tests[] = { 52 // A well-formed challenge where a sid is provided produces a valid 53 // response header echoing the sid and ps token, for either origin. 54 { OK, OK, 55 kValidOrigin, 56 kValidChallenge, 57 "SpdyProxy ps=\"1-2-3-4\", sid=\"sid-string\"",}, 58 59 { OK, OK, 60 kValidOrigin2, 61 kValidChallenge, 62 "SpdyProxy ps=\"1-2-3-4\", sid=\"sid-string\"",}, 63 64 // An origin matching host but not scheme returns 65 // ERR_UNSUPPORTED_AUTH_SCHEME 66 { ERR_UNSUPPORTED_AUTH_SCHEME, OK, 67 "http://www.proxy.com/", "", "",}, 68 69 // An SSL origin not matching the authorized origin returns 70 // ERR_UNSUPPORTED_AUTH_SCHEME. 71 { ERR_UNSUPPORTED_AUTH_SCHEME, OK, 72 "https://www.unconfigured.com/", "", "",}, 73 74 // Absent ps token yields ERR_INVALID_RESPONSE. 75 { ERR_INVALID_RESPONSE, OK, 76 kValidOrigin, "SpdyProxy realm=\"SpdyProxy\"", "",}, 77 }; 78 79 // Run each test case for both proxy and server auth. 80 HttpAuth::Target targets[] = { HttpAuth::AUTH_SERVER, HttpAuth::AUTH_PROXY }; 81 82 83 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(targets); ++i) { 84 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(tests); ++j) { 85 GURL origin(tests[j].origin); 86 GURL authorized_origin(kValidOrigin); 87 GURL authorized_origin2(kValidOrigin2); 88 std::vector<GURL> authorized_origins; 89 authorized_origins.push_back(authorized_origin); 90 authorized_origins.push_back(authorized_origin2); 91 HttpAuthHandlerDataReductionProxy::Factory factory(authorized_origins); 92 scoped_ptr<HttpAuthHandler> spdyproxy; 93 EXPECT_EQ(tests[j].err1, factory.CreateAuthHandlerFromString( 94 tests[j].challenge, targets[i], origin, BoundNetLog(), 95 &spdyproxy)); 96 if (tests[j].err1 != OK) 97 continue; 98 AuthCredentials credentials(base::ASCIIToUTF16(""), 99 base::ASCIIToUTF16("sid-string")); 100 HttpRequestInfo request_info; 101 std::string auth_token; 102 int rv = spdyproxy->GenerateAuthToken(&credentials, &request_info, 103 CompletionCallback(), &auth_token); 104 EXPECT_EQ(tests[j].err2, rv); 105 if (tests[i].err2 != OK) 106 continue; 107 EXPECT_STREQ(tests[i].expected_credentials, auth_token.c_str()); 108 } 109 } 110 } 111 112 TEST(HttpAuthHandlerDataReductionProxyTest, HandleAnotherChallenge) { 113 // Verifies that any repeat challenge is treated as a failure. 114 GURL origin(kValidOrigin); 115 GURL accepted_origin(kValidOrigin); 116 std::vector<GURL> accepted_origins; 117 accepted_origins.push_back(accepted_origin); 118 HttpAuthHandlerDataReductionProxy::Factory factory(accepted_origins); 119 scoped_ptr<HttpAuthHandler> spdyproxy; 120 EXPECT_EQ(OK, factory.CreateAuthHandlerFromString( 121 kValidChallenge, HttpAuth::AUTH_PROXY, origin, 122 BoundNetLog(), &spdyproxy)); 123 std::string challenge(kValidChallenge); 124 HttpAuthChallengeTokenizer tok(challenge.begin(), 125 challenge.end()); 126 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, 127 spdyproxy->HandleAnotherChallenge(&tok)); 128 } 129 130 TEST(HttpAuthHandlerDataReductionProxyTest, ParseChallenge) { 131 // Verifies that various challenge strings are parsed appropriately as 132 // described below. 133 static const struct { 134 const char* challenge; 135 int expected_rv; 136 const char* expected_ps; 137 const char* expected_realm; 138 } tests[] = { 139 // Absent parameters fails. 140 { "SpdyProxy", ERR_INVALID_RESPONSE, "", "", }, 141 142 // Empty parameters fails. 143 { "SpdyProxy ps=\"\"", ERR_INVALID_RESPONSE, "", "", }, 144 145 // Valid challenge parses successfully. 146 { kValidChallenge, OK, "1-2-3-4", "SpdyProxy", }, 147 }; 148 GURL origin(kValidOrigin); 149 GURL accepted_origin(kValidOrigin); 150 GURL accepted_origin2(kValidOrigin2); 151 std::vector<GURL> accepted_origins; 152 accepted_origins.push_back(accepted_origin2); 153 accepted_origins.push_back(accepted_origin); 154 HttpAuthHandlerDataReductionProxy::Factory factory(accepted_origins); 155 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 156 std::string challenge = tests[i].challenge; 157 scoped_ptr<HttpAuthHandler> spdyproxy; 158 int rv = factory.CreateAuthHandlerFromString( 159 challenge, HttpAuth::AUTH_PROXY, origin, BoundNetLog(), &spdyproxy); 160 EXPECT_EQ(tests[i].expected_rv, rv); 161 if (rv == OK) { 162 EXPECT_EQ(tests[i].expected_realm, spdyproxy->realm()); 163 HttpAuthHandlerDataReductionProxy* as_spdyproxy = 164 static_cast<HttpAuthHandlerDataReductionProxy*>(spdyproxy.get()); 165 EXPECT_EQ(tests[i].expected_ps, 166 as_spdyproxy->ps_token_); 167 } 168 } 169 } 170 171 } // namespace data_reduction_proxy 172