Home | History | Annotate | Download | only in browser
      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