| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 12 #include "net/http/http_auth_challenge_tokenizer.h" | 12 #include "net/http/http_auth_challenge_tokenizer.h" |
| 13 #include "net/http/http_auth_handler_basic.h" | 13 #include "net/http/http_auth_handler_basic.h" |
| 14 #include "net/http/http_request_info.h" | 14 #include "net/http/http_request_info.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 16 |
| 17 namespace net { | 17 namespace net { |
| 18 | 18 |
| 19 TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) { | 19 TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) { |
| 20 static const struct { | 20 static const struct { |
| 21 const char* username; | 21 const char* username; |
| 22 const char* password; | 22 const char* password; |
| 23 const char* expected_credentials; | 23 const char* expected_credentials; |
| 24 } tests[] = { | 24 } tests[] = { |
| 25 { "foo", "bar", "Basic Zm9vOmJhcg==" }, | 25 {"foo", "bar", "Basic Zm9vOmJhcg=="}, |
| 26 // Empty username | 26 // Empty username |
| 27 { "", "foobar", "Basic OmZvb2Jhcg==" }, | 27 {"", "foobar", "Basic OmZvb2Jhcg=="}, |
| 28 // Empty password | 28 // Empty password |
| 29 { "anon", "", "Basic YW5vbjo=" }, | 29 {"anon", "", "Basic YW5vbjo="}, |
| 30 // Empty username and empty password. | 30 // Empty username and empty password. |
| 31 { "", "", "Basic Og==" }, | 31 {"", "", "Basic Og=="}, |
| 32 }; | 32 }; |
| 33 GURL origin("http://www.example.com"); | 33 GURL origin("http://www.example.com"); |
| 34 HttpAuthHandlerBasic::Factory factory; | 34 HttpAuthHandlerBasic::Factory factory; |
| 35 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 35 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 36 std::string challenge = "Basic realm=\"Atlantis\""; | 36 std::string challenge = "Basic realm=\"Atlantis\""; |
| 37 scoped_ptr<HttpAuthHandler> basic; | 37 scoped_ptr<HttpAuthHandler> basic; |
| 38 EXPECT_EQ(OK, factory.CreateAuthHandlerFromString( | 38 EXPECT_EQ( |
| 39 challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), &basic)); | 39 OK, |
| 40 factory.CreateAuthHandlerFromString( |
| 41 challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), &basic)); |
| 40 AuthCredentials credentials(base::ASCIIToUTF16(tests[i].username), | 42 AuthCredentials credentials(base::ASCIIToUTF16(tests[i].username), |
| 41 base::ASCIIToUTF16(tests[i].password)); | 43 base::ASCIIToUTF16(tests[i].password)); |
| 42 HttpRequestInfo request_info; | 44 HttpRequestInfo request_info; |
| 43 std::string auth_token; | 45 std::string auth_token; |
| 44 int rv = basic->GenerateAuthToken(&credentials, &request_info, | 46 int rv = basic->GenerateAuthToken( |
| 45 CompletionCallback(), &auth_token); | 47 &credentials, &request_info, CompletionCallback(), &auth_token); |
| 46 EXPECT_EQ(OK, rv); | 48 EXPECT_EQ(OK, rv); |
| 47 EXPECT_STREQ(tests[i].expected_credentials, auth_token.c_str()); | 49 EXPECT_STREQ(tests[i].expected_credentials, auth_token.c_str()); |
| 48 } | 50 } |
| 49 } | 51 } |
| 50 | 52 |
| 51 TEST(HttpAuthHandlerBasicTest, HandleAnotherChallenge) { | 53 TEST(HttpAuthHandlerBasicTest, HandleAnotherChallenge) { |
| 52 static const struct { | 54 static const struct { |
| 53 const char* challenge; | 55 const char* challenge; |
| 54 HttpAuth::AuthorizationResult expected_rv; | 56 HttpAuth::AuthorizationResult expected_rv; |
| 55 } tests[] = { | 57 } tests[] = {// The handler is initialized using this challenge. The first |
| 56 // The handler is initialized using this challenge. The first | 58 // time HandleAnotherChallenge is called with it should cause it |
| 57 // time HandleAnotherChallenge is called with it should cause it | 59 // to treat the second challenge as a rejection since it is for |
| 58 // to treat the second challenge as a rejection since it is for | 60 // the same realm. |
| 59 // the same realm. | 61 {"Basic realm=\"First\"", HttpAuth::AUTHORIZATION_RESULT_REJECT}, |
| 60 { | |
| 61 "Basic realm=\"First\"", | |
| 62 HttpAuth::AUTHORIZATION_RESULT_REJECT | |
| 63 }, | |
| 64 | 62 |
| 65 // A challenge for a different realm. | 63 // A challenge for a different realm. |
| 66 { | 64 {"Basic realm=\"Second\"", |
| 67 "Basic realm=\"Second\"", | 65 HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM}, |
| 68 HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM | |
| 69 }, | |
| 70 | 66 |
| 71 // Although RFC 2617 isn't explicit about this case, if there is | 67 // Although RFC 2617 isn't explicit about this case, if there is |
| 72 // more than one realm directive, we pick the last one. So this | 68 // more than one realm directive, we pick the last one. So this |
| 73 // challenge should be treated as being for "First" realm. | 69 // challenge should be treated as being for "First" realm. |
| 74 { | 70 {"Basic realm=\"Second\",realm=\"First\"", |
| 75 "Basic realm=\"Second\",realm=\"First\"", | 71 HttpAuth::AUTHORIZATION_RESULT_REJECT}, |
| 76 HttpAuth::AUTHORIZATION_RESULT_REJECT | |
| 77 }, | |
| 78 | 72 |
| 79 // And this one should be treated as if it was for "Second." | 73 // And this one should be treated as if it was for "Second." |
| 80 { | 74 {"basic realm=\"First\",realm=\"Second\"", |
| 81 "basic realm=\"First\",realm=\"Second\"", | 75 HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM}}; |
| 82 HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM | |
| 83 } | |
| 84 }; | |
| 85 | 76 |
| 86 GURL origin("http://www.example.com"); | 77 GURL origin("http://www.example.com"); |
| 87 HttpAuthHandlerBasic::Factory factory; | 78 HttpAuthHandlerBasic::Factory factory; |
| 88 scoped_ptr<HttpAuthHandler> basic; | 79 scoped_ptr<HttpAuthHandler> basic; |
| 89 EXPECT_EQ(OK, factory.CreateAuthHandlerFromString( | 80 EXPECT_EQ(OK, |
| 90 tests[0].challenge, HttpAuth::AUTH_SERVER, origin, | 81 factory.CreateAuthHandlerFromString(tests[0].challenge, |
| 91 BoundNetLog(), &basic)); | 82 HttpAuth::AUTH_SERVER, |
| 83 origin, |
| 84 BoundNetLog(), |
| 85 &basic)); |
| 92 | 86 |
| 93 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 87 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 94 std::string challenge(tests[i].challenge); | 88 std::string challenge(tests[i].challenge); |
| 95 HttpAuthChallengeTokenizer tok(challenge.begin(), | 89 HttpAuthChallengeTokenizer tok(challenge.begin(), challenge.end()); |
| 96 challenge.end()); | |
| 97 EXPECT_EQ(tests[i].expected_rv, basic->HandleAnotherChallenge(&tok)); | 90 EXPECT_EQ(tests[i].expected_rv, basic->HandleAnotherChallenge(&tok)); |
| 98 } | 91 } |
| 99 } | 92 } |
| 100 | 93 |
| 101 TEST(HttpAuthHandlerBasicTest, InitFromChallenge) { | 94 TEST(HttpAuthHandlerBasicTest, InitFromChallenge) { |
| 102 static const struct { | 95 static const struct { |
| 103 const char* challenge; | 96 const char* challenge; |
| 104 int expected_rv; | 97 int expected_rv; |
| 105 const char* expected_realm; | 98 const char* expected_realm; |
| 106 } tests[] = { | 99 } tests[] = { |
| 107 // No realm (we allow this even though realm is supposed to be required | 100 // No realm (we allow this even though realm is supposed to be required |
| 108 // according to RFC 2617.) | 101 // according to RFC 2617.) |
| 109 { | 102 { |
| 110 "Basic", | 103 "Basic", OK, "", |
| 111 OK, | |
| 112 "", | |
| 113 }, | 104 }, |
| 114 | 105 |
| 115 // Realm is empty string. | 106 // Realm is empty string. |
| 116 { | 107 { |
| 117 "Basic realm=\"\"", | 108 "Basic realm=\"\"", OK, "", |
| 118 OK, | |
| 119 "", | |
| 120 }, | 109 }, |
| 121 | 110 |
| 122 // Realm is valid. | 111 // Realm is valid. |
| 123 { | 112 { |
| 124 "Basic realm=\"test_realm\"", | 113 "Basic realm=\"test_realm\"", OK, "test_realm", |
| 125 OK, | |
| 126 "test_realm", | |
| 127 }, | 114 }, |
| 128 | 115 |
| 129 // The parser ignores tokens which aren't known. | 116 // The parser ignores tokens which aren't known. |
| 130 { | 117 { |
| 131 "Basic realm=\"test_realm\",unknown_token=foobar", | 118 "Basic realm=\"test_realm\",unknown_token=foobar", OK, "test_realm", |
| 132 OK, | |
| 133 "test_realm", | |
| 134 }, | 119 }, |
| 135 | 120 |
| 136 // The parser skips over tokens which aren't known. | 121 // The parser skips over tokens which aren't known. |
| 137 { | 122 { |
| 138 "Basic unknown_token=foobar,realm=\"test_realm\"", | 123 "Basic unknown_token=foobar,realm=\"test_realm\"", OK, "test_realm", |
| 139 OK, | |
| 140 "test_realm", | |
| 141 }, | 124 }, |
| 142 | 125 |
| 143 #if 0 | 126 #if 0 |
| 144 // TODO(cbentzel): It's unclear what the parser should do in these cases. | 127 // TODO(cbentzel): It's unclear what the parser should do in these cases. |
| 145 // It seems like this should either be treated as invalid, | 128 // It seems like this should either be treated as invalid, |
| 146 // or the spaces should be used as a separator. | 129 // or the spaces should be used as a separator. |
| 147 { | 130 { |
| 148 "Basic realm=\"test_realm\" unknown_token=foobar", | 131 "Basic realm=\"test_realm\" unknown_token=foobar", |
| 149 OK, | 132 OK, |
| 150 "test_realm", | 133 "test_realm", |
| 151 }, | 134 }, |
| 152 | 135 |
| 153 // The parser skips over tokens which aren't known. | 136 // The parser skips over tokens which aren't known. |
| 154 { | 137 { |
| 155 "Basic unknown_token=foobar realm=\"test_realm\"", | 138 "Basic unknown_token=foobar realm=\"test_realm\"", |
| 156 OK, | 139 OK, |
| 157 "test_realm", | 140 "test_realm", |
| 158 }, | 141 }, |
| 159 #endif | 142 #endif |
| 160 | 143 |
| 161 // The parser fails when the first token is not "Basic". | 144 // The parser fails when the first token is not "Basic". |
| 162 { | 145 {"Negotiate", ERR_INVALID_RESPONSE, ""}, |
| 163 "Negotiate", | |
| 164 ERR_INVALID_RESPONSE, | |
| 165 "" | |
| 166 }, | |
| 167 | 146 |
| 168 // Although RFC 2617 isn't explicit about this case, if there is | 147 // Although RFC 2617 isn't explicit about this case, if there is |
| 169 // more than one realm directive, we pick the last one. | 148 // more than one realm directive, we pick the last one. |
| 170 { | 149 { |
| 171 "Basic realm=\"foo\",realm=\"bar\"", | 150 "Basic realm=\"foo\",realm=\"bar\"", OK, "bar", |
| 172 OK, | |
| 173 "bar", | |
| 174 }, | 151 }, |
| 175 | 152 |
| 176 // Handle ISO-8859-1 character as part of the realm. The realm is converted | 153 // Handle ISO-8859-1 character as part of the realm. The realm is converted |
| 177 // to UTF-8. | 154 // to UTF-8. |
| 178 { | 155 { |
| 179 "Basic realm=\"foo-\xE5\"", | 156 "Basic realm=\"foo-\xE5\"", OK, "foo-\xC3\xA5", |
| 180 OK, | |
| 181 "foo-\xC3\xA5", | |
| 182 }, | 157 }, |
| 183 }; | 158 }; |
| 184 HttpAuthHandlerBasic::Factory factory; | 159 HttpAuthHandlerBasic::Factory factory; |
| 185 GURL origin("http://www.example.com"); | 160 GURL origin("http://www.example.com"); |
| 186 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 161 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 187 std::string challenge = tests[i].challenge; | 162 std::string challenge = tests[i].challenge; |
| 188 scoped_ptr<HttpAuthHandler> basic; | 163 scoped_ptr<HttpAuthHandler> basic; |
| 189 int rv = factory.CreateAuthHandlerFromString( | 164 int rv = factory.CreateAuthHandlerFromString( |
| 190 challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), &basic); | 165 challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(), &basic); |
| 191 EXPECT_EQ(tests[i].expected_rv, rv); | 166 EXPECT_EQ(tests[i].expected_rv, rv); |
| 192 if (rv == OK) | 167 if (rv == OK) |
| 193 EXPECT_EQ(tests[i].expected_realm, basic->realm()); | 168 EXPECT_EQ(tests[i].expected_realm, basic->realm()); |
| 194 } | 169 } |
| 195 } | 170 } |
| 196 | 171 |
| 197 } // namespace net | 172 } // namespace net |
| OLD | NEW |