1 // Copyright (c) 2011 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 "net/http/http_auth_controller.h" 6 7 #include "net/base/net_errors.h" 8 #include "net/base/net_log.h" 9 #include "net/base/test_completion_callback.h" 10 #include "net/http/http_auth_cache.h" 11 #include "net/http/http_auth_handler_mock.h" 12 #include "net/http/http_request_info.h" 13 #include "net/http/http_response_headers.h" 14 #include "net/http/http_util.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 17 namespace net { 18 19 namespace { 20 21 enum HandlerRunMode { 22 RUN_HANDLER_SYNC, 23 RUN_HANDLER_ASYNC 24 }; 25 26 enum SchemeState { 27 SCHEME_IS_DISABLED, 28 SCHEME_IS_ENABLED 29 }; 30 31 // Runs an HttpAuthController with a single round mock auth handler 32 // that returns |handler_rv| on token generation. The handler runs in 33 // async if |run_mode| is RUN_HANDLER_ASYNC. Upon completion, the 34 // return value of the controller is tested against 35 // |expected_controller_rv|. |scheme_state| indicates whether the 36 // auth scheme used should be disabled after this run. 37 void RunSingleRoundAuthTest(HandlerRunMode run_mode, 38 int handler_rv, 39 int expected_controller_rv, 40 SchemeState scheme_state) { 41 BoundNetLog dummy_log; 42 HttpAuthCache dummy_auth_cache; 43 44 HttpRequestInfo request; 45 request.method = "GET"; 46 request.url = GURL("http://example.com"); 47 48 const std::string headers_raw_string = 49 "HTTP/1.1 407\r\n" 50 "Proxy-Authenticate: MOCK foo\r\n" 51 "\r\n"; 52 std::string headers_string = HttpUtil::AssembleRawHeaders( 53 headers_raw_string.c_str(), headers_raw_string.length()); 54 scoped_refptr<HttpResponseHeaders> headers( 55 new HttpResponseHeaders(headers_string)); 56 57 HttpAuthHandlerMock::Factory auth_handler_factory; 58 HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock(); 59 auth_handler->SetGenerateExpectation((run_mode == RUN_HANDLER_ASYNC), 60 handler_rv); 61 auth_handler_factory.set_mock_handler(auth_handler, HttpAuth::AUTH_PROXY); 62 auth_handler_factory.set_do_init_from_challenge(true); 63 64 scoped_refptr<HttpAuthController> controller( 65 new HttpAuthController(HttpAuth::AUTH_PROXY, 66 GURL("http://example.com"), 67 &dummy_auth_cache, &auth_handler_factory)); 68 ASSERT_EQ(OK, 69 controller->HandleAuthChallenge(headers, false, false, dummy_log)); 70 EXPECT_TRUE(controller->HaveAuthHandler()); 71 controller->ResetAuth(string16(), string16()); 72 EXPECT_TRUE(controller->HaveAuth()); 73 74 TestCompletionCallback callback; 75 EXPECT_EQ((run_mode == RUN_HANDLER_ASYNC)? ERR_IO_PENDING: 76 expected_controller_rv, 77 controller->MaybeGenerateAuthToken(&request, &callback, 78 dummy_log)); 79 if (run_mode == RUN_HANDLER_ASYNC) 80 EXPECT_EQ(expected_controller_rv, callback.WaitForResult()); 81 EXPECT_EQ((scheme_state == SCHEME_IS_DISABLED), 82 controller->IsAuthSchemeDisabled(HttpAuth::AUTH_SCHEME_MOCK)); 83 } 84 85 } // namespace 86 87 // If an HttpAuthHandler returns an error code that indicates a 88 // permanent error, the HttpAuthController should disable the scheme 89 // used and retry the request. 90 TEST(HttpAuthControllerTest, PermanentErrors) { 91 92 // Run a synchronous handler that returns 93 // ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS. We expect a return value 94 // of OK from the controller so we can retry the request. 95 RunSingleRoundAuthTest(RUN_HANDLER_SYNC, 96 ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS, 97 OK, SCHEME_IS_DISABLED); 98 99 // Now try an async handler that returns 100 // ERR_MISSING_AUTH_CREDENTIALS. Async and sync handlers invoke 101 // different code paths in HttpAuthController when generating 102 // tokens. 103 RunSingleRoundAuthTest(RUN_HANDLER_ASYNC, ERR_MISSING_AUTH_CREDENTIALS, OK, 104 SCHEME_IS_DISABLED); 105 106 // If a non-permanent error is returned by the handler, then the 107 // controller should report it unchanged. 108 RunSingleRoundAuthTest(RUN_HANDLER_ASYNC, ERR_INVALID_AUTH_CREDENTIALS, 109 ERR_INVALID_AUTH_CREDENTIALS, SCHEME_IS_ENABLED); 110 } 111 112 } // namespace net 113