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 "net/http/http_auth_challenge_tokenizer.h"
6#include "testing/gtest/include/gtest/gtest.h"
7
8namespace net {
9
10TEST(HttpAuthChallengeTokenizerTest, Basic) {
11  std::string challenge_str = "Basic realm=\"foobar\"";
12  HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
13                                       challenge_str.end());
14  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
15
16  EXPECT_TRUE(parameters.valid());
17  EXPECT_EQ(std::string("Basic"), challenge.scheme());
18  EXPECT_TRUE(parameters.GetNext());
19  EXPECT_TRUE(parameters.valid());
20  EXPECT_EQ(std::string("realm"), parameters.name());
21  EXPECT_EQ(std::string("foobar"), parameters.value());
22  EXPECT_FALSE(parameters.GetNext());
23}
24
25// Use a name=value property with no quote marks.
26TEST(HttpAuthChallengeTokenizerTest, NoQuotes) {
27  std::string challenge_str = "Basic realm=foobar@baz.com";
28  HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
29                                       challenge_str.end());
30  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
31
32  EXPECT_TRUE(parameters.valid());
33  EXPECT_EQ(std::string("Basic"), challenge.scheme());
34  EXPECT_TRUE(parameters.GetNext());
35  EXPECT_TRUE(parameters.valid());
36  EXPECT_EQ(std::string("realm"), parameters.name());
37  EXPECT_EQ(std::string("foobar@baz.com"), parameters.value());
38  EXPECT_FALSE(parameters.GetNext());
39}
40
41// Use a name=value property with mismatching quote marks.
42TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotes) {
43  std::string challenge_str = "Basic realm=\"foobar@baz.com";
44  HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
45                                       challenge_str.end());
46  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
47
48  EXPECT_TRUE(parameters.valid());
49  EXPECT_EQ(std::string("Basic"), challenge.scheme());
50  EXPECT_TRUE(parameters.GetNext());
51  EXPECT_TRUE(parameters.valid());
52  EXPECT_EQ(std::string("realm"), parameters.name());
53  EXPECT_EQ(std::string("foobar@baz.com"), parameters.value());
54  EXPECT_FALSE(parameters.GetNext());
55}
56
57// Use a name= property without a value and with mismatching quote marks.
58TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesNoValue) {
59  std::string challenge_str = "Basic realm=\"";
60  HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
61                                       challenge_str.end());
62  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
63
64  EXPECT_TRUE(parameters.valid());
65  EXPECT_EQ(std::string("Basic"), challenge.scheme());
66  EXPECT_TRUE(parameters.GetNext());
67  EXPECT_TRUE(parameters.valid());
68  EXPECT_EQ(std::string("realm"), parameters.name());
69  EXPECT_EQ(std::string(), parameters.value());
70  EXPECT_FALSE(parameters.GetNext());
71}
72
73// Use a name=value property with mismatching quote marks and spaces in the
74// value.
75TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesSpaces) {
76  std::string challenge_str = "Basic realm=\"foo bar";
77  HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
78                                       challenge_str.end());
79  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
80
81  EXPECT_TRUE(parameters.valid());
82  EXPECT_EQ(std::string("Basic"), challenge.scheme());
83  EXPECT_TRUE(parameters.GetNext());
84  EXPECT_TRUE(parameters.valid());
85  EXPECT_EQ(std::string("realm"), parameters.name());
86  EXPECT_EQ(std::string("foo bar"), parameters.value());
87  EXPECT_FALSE(parameters.GetNext());
88}
89
90// Use multiple name=value properties with mismatching quote marks in the last
91// value.
92TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesMultiple) {
93  std::string challenge_str = "Digest qop=auth-int, algorithm=md5, realm=\"foo";
94  HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
95                                       challenge_str.end());
96  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
97
98  EXPECT_TRUE(parameters.valid());
99  EXPECT_EQ(std::string("Digest"), challenge.scheme());
100  EXPECT_TRUE(parameters.GetNext());
101  EXPECT_TRUE(parameters.valid());
102  EXPECT_EQ(std::string("qop"), parameters.name());
103  EXPECT_EQ(std::string("auth-int"), parameters.value());
104  EXPECT_TRUE(parameters.GetNext());
105  EXPECT_TRUE(parameters.valid());
106  EXPECT_EQ(std::string("algorithm"), parameters.name());
107  EXPECT_EQ(std::string("md5"), parameters.value());
108  EXPECT_TRUE(parameters.GetNext());
109  EXPECT_TRUE(parameters.valid());
110  EXPECT_EQ(std::string("realm"), parameters.name());
111  EXPECT_EQ(std::string("foo"), parameters.value());
112  EXPECT_FALSE(parameters.GetNext());
113}
114
115// Use a name= property which has no value.
116TEST(HttpAuthChallengeTokenizerTest, NoValue) {
117  std::string challenge_str = "Digest qop=";
118  HttpAuthChallengeTokenizer challenge(
119      challenge_str.begin(), challenge_str.end());
120  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
121
122  EXPECT_TRUE(parameters.valid());
123  EXPECT_EQ(std::string("Digest"), challenge.scheme());
124  EXPECT_FALSE(parameters.GetNext());
125  EXPECT_FALSE(parameters.valid());
126}
127
128// Specify multiple properties, comma separated.
129TEST(HttpAuthChallengeTokenizerTest, Multiple) {
130  std::string challenge_str =
131      "Digest algorithm=md5, realm=\"Oblivion\", qop=auth-int";
132  HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
133                                       challenge_str.end());
134  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
135
136  EXPECT_TRUE(parameters.valid());
137  EXPECT_EQ(std::string("Digest"), challenge.scheme());
138  EXPECT_TRUE(parameters.GetNext());
139  EXPECT_TRUE(parameters.valid());
140  EXPECT_EQ(std::string("algorithm"), parameters.name());
141  EXPECT_EQ(std::string("md5"), parameters.value());
142  EXPECT_TRUE(parameters.GetNext());
143  EXPECT_TRUE(parameters.valid());
144  EXPECT_EQ(std::string("realm"), parameters.name());
145  EXPECT_EQ(std::string("Oblivion"), parameters.value());
146  EXPECT_TRUE(parameters.GetNext());
147  EXPECT_TRUE(parameters.valid());
148  EXPECT_EQ(std::string("qop"), parameters.name());
149  EXPECT_EQ(std::string("auth-int"), parameters.value());
150  EXPECT_FALSE(parameters.GetNext());
151  EXPECT_TRUE(parameters.valid());
152}
153
154// Use a challenge which has no property.
155TEST(HttpAuthChallengeTokenizerTest, NoProperty) {
156  std::string challenge_str = "NTLM";
157  HttpAuthChallengeTokenizer challenge(
158      challenge_str.begin(), challenge_str.end());
159  HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
160
161  EXPECT_TRUE(parameters.valid());
162  EXPECT_EQ(std::string("NTLM"), challenge.scheme());
163  EXPECT_FALSE(parameters.GetNext());
164}
165
166// Use a challenge with Base64 encoded token.
167TEST(HttpAuthChallengeTokenizerTest, Base64) {
168  std::string challenge_str = "NTLM  SGVsbG8sIFdvcmxkCg===";
169  HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
170                                       challenge_str.end());
171
172  EXPECT_EQ(std::string("NTLM"), challenge.scheme());
173  // Notice the two equal statements below due to padding removal.
174  EXPECT_EQ(std::string("SGVsbG8sIFdvcmxkCg=="), challenge.base64_param());
175}
176
177}  // namespace net
178