1/*
2* Copyright (C) 2011 The Android Open Source Project
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8*      http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17package libcore.net.http;
18
19import java.net.URI;
20import java.util.Arrays;
21import java.util.Collections;
22import java.util.Date;
23import junit.framework.TestCase;
24
25public final class ParsedHeadersTest extends TestCase {
26
27    private URI uri;
28
29    @Override protected void setUp() throws Exception {
30        super.setUp();
31        uri = new URI("http", "localhost", "/");
32    }
33
34    public void testUpperCaseHttpHeaders() {
35        RawHeaders headers = new RawHeaders();
36        headers.add("CACHE-CONTROL", "no-store");
37        headers.add("DATE", "Thu, 01 Jan 1970 00:00:01 UTC");
38        headers.add("EXPIRES", "Thu, 01 Jan 1970 00:00:02 UTC");
39        headers.add("LAST-MODIFIED", "Thu, 01 Jan 1970 00:00:03 UTC");
40        headers.add("ETAG", "v1");
41        headers.add("PRAGMA", "no-cache");
42        ResponseHeaders parsedHeaders = new ResponseHeaders(uri, headers);
43        assertTrue(parsedHeaders.isNoStore());
44        assertEquals(new Date(1000), parsedHeaders.getServedDate());
45        assertEquals(new Date(2000), parsedHeaders.getExpires());
46        assertEquals(new Date(3000), parsedHeaders.getLastModified());
47        assertEquals("v1", parsedHeaders.getEtag());
48        assertTrue(parsedHeaders.isNoCache());
49    }
50
51    public void testCommaSeparatedCacheControlHeaders() {
52        RawHeaders headers = new RawHeaders();
53        headers.add("Cache-Control", "no-store, max-age=60, public");
54        ResponseHeaders parsedHeaders = new ResponseHeaders(uri, headers);
55        assertTrue(parsedHeaders.isNoStore());
56        assertEquals(60, parsedHeaders.getMaxAgeSeconds());
57        assertTrue(parsedHeaders.isPublic());
58    }
59
60    public void testQuotedFieldName() {
61        RawHeaders headers = new RawHeaders();
62        headers.add("Cache-Control", "private=\"Set-Cookie\", no-store");
63        ResponseHeaders parsedHeaders = new ResponseHeaders(uri, headers);
64        assertTrue(parsedHeaders.isNoStore());
65    }
66
67    public void testUnquotedValue() {
68        RawHeaders headers = new RawHeaders();
69        headers.add("Cache-Control", "private=Set-Cookie, no-store");
70        ResponseHeaders parsedHeaders = new ResponseHeaders(uri, headers);
71        assertTrue(parsedHeaders.isNoStore());
72    }
73
74    public void testQuotedValue() {
75        RawHeaders headers = new RawHeaders();
76        headers.add("Cache-Control", "private=\" a, no-cache, c \", no-store");
77        ResponseHeaders parsedHeaders = new ResponseHeaders(uri, headers);
78        assertTrue(parsedHeaders.isNoStore());
79        assertFalse(parsedHeaders.isNoCache());
80    }
81
82    public void testDanglingQuote() {
83        RawHeaders headers = new RawHeaders();
84        headers.add("Cache-Control", "private=\"a, no-cache, c");
85        ResponseHeaders parsedHeaders = new ResponseHeaders(uri, headers);
86        assertFalse(parsedHeaders.isNoCache());
87    }
88
89    public void testTrailingComma() {
90        RawHeaders headers = new RawHeaders();
91        headers.add("Cache-Control", "public,");
92        ResponseHeaders parsedHeaders = new ResponseHeaders(uri, headers);
93        assertTrue(parsedHeaders.isPublic());
94    }
95
96    public void testTrailingEquals() {
97        RawHeaders headers = new RawHeaders();
98        headers.add("Cache-Control", "private=");
99        new ResponseHeaders(uri, headers);
100    }
101
102    public void testSpaceBeforeEquals() {
103        RawHeaders headers = new RawHeaders();
104        headers.add("Cache-Control", "max-age =60");
105        RequestHeaders parsedHeaders = new RequestHeaders(uri, headers);
106        assertEquals(60, parsedHeaders.getMaxAgeSeconds());
107    }
108
109    public void testSpaceAfterEqualsWithQuotes() {
110        RawHeaders headers = new RawHeaders();
111        headers.add("Cache-Control", "max-age= \"60\"");
112        RequestHeaders parsedHeaders = new RequestHeaders(uri, headers);
113        assertEquals(60, parsedHeaders.getMaxAgeSeconds());
114    }
115
116    public void testSpaceAfterEqualsWithoutQuotes() {
117        RawHeaders headers = new RawHeaders();
118        headers.add("Cache-Control", "max-age= 60");
119        RequestHeaders parsedHeaders = new RequestHeaders(uri, headers);
120        assertEquals(60, parsedHeaders.getMaxAgeSeconds());
121    }
122
123    public void testCacheControlRequestDirectivesAreCaseInsensitive() {
124        RawHeaders headers = new RawHeaders();
125        headers.add("Cache-Control", "NO-CACHE");
126        headers.add("Cache-Control", "MAX-AGE=60");
127        headers.add("Cache-Control", "MAX-STALE=70");
128        headers.add("Cache-Control", "MIN-FRESH=80");
129        headers.add("Cache-Control", "ONLY-IF-CACHED");
130        RequestHeaders parsedHeaders = new RequestHeaders(uri, headers);
131        assertTrue(parsedHeaders.isNoCache());
132        assertEquals(60, parsedHeaders.getMaxAgeSeconds());
133        assertEquals(70, parsedHeaders.getMaxStaleSeconds());
134        assertEquals(80, parsedHeaders.getMinFreshSeconds());
135        assertTrue(parsedHeaders.isOnlyIfCached());
136    }
137
138    public void testCacheControlResponseDirectivesAreCaseInsensitive() {
139        RawHeaders headers = new RawHeaders();
140        headers.add("Cache-Control", "NO-CACHE");
141        headers.add("Cache-Control", "NO-STORE");
142        headers.add("Cache-Control", "MAX-AGE=60");
143        headers.add("Cache-Control", "S-MAXAGE=70");
144        headers.add("Cache-Control", "PUBLIC");
145        headers.add("Cache-Control", "MUST-REVALIDATE");
146        ResponseHeaders parsedHeaders = new ResponseHeaders(uri, headers);
147        assertTrue(parsedHeaders.isNoCache());
148        assertTrue(parsedHeaders.isNoStore());
149        assertEquals(60, parsedHeaders.getMaxAgeSeconds());
150        assertEquals(70, parsedHeaders.getSMaxAgeSeconds());
151        assertTrue(parsedHeaders.isPublic());
152        assertTrue(parsedHeaders.isMustRevalidate());
153    }
154
155    public void testPragmaDirectivesAreCaseInsensitive() {
156        RawHeaders headers = new RawHeaders();
157        headers.add("Pragma", "NO-CACHE");
158        RequestHeaders parsedHeaders = new RequestHeaders(uri, headers);
159        assertTrue(parsedHeaders.isNoCache());
160    }
161
162    public void testMissingInteger() {
163        RawHeaders headers = new RawHeaders();
164        headers.add("Cache-Control", "max-age");
165        RequestHeaders parsedHeaders = new RequestHeaders(uri, headers);
166        assertEquals(-1, parsedHeaders.getMaxAgeSeconds());
167    }
168
169    public void testInvalidInteger() {
170        RawHeaders headers = new RawHeaders();
171        headers.add("Cache-Control", "MAX-AGE=pi");
172        RequestHeaders requestHeaders = new RequestHeaders(uri, headers);
173        assertEquals(-1, requestHeaders.getMaxAgeSeconds());
174    }
175
176    public void testVeryLargeInteger() {
177        RawHeaders headers = new RawHeaders();
178        headers.add("Cache-Control", "MAX-AGE=" + (Integer.MAX_VALUE + 1L));
179        RequestHeaders parsedHeaders = new RequestHeaders(uri, headers);
180        assertEquals(Integer.MAX_VALUE, parsedHeaders.getMaxAgeSeconds());
181    }
182
183    public void testNegativeInteger() {
184        RawHeaders headers = new RawHeaders();
185        headers.add("Cache-Control", "MAX-AGE=-2");
186        RequestHeaders parsedHeaders = new RequestHeaders(uri, headers);
187        assertEquals(0, parsedHeaders.getMaxAgeSeconds());
188    }
189
190    public void testParseChallengesWithCommaInRealm() {
191        RawHeaders headers = new RawHeaders();
192        headers.add("WWW-Authenticate", "s1 realm=\"ab,cd\", s2 realm=\"ef,gh\"");
193        assertEquals(Arrays.asList(new Challenge("s1", "ab,cd"), new Challenge("s2", "ef,gh")),
194                HeaderParser.parseChallenges(headers, "WWW-Authenticate"));
195    }
196
197    public void testParseChallengesWithMultipleHeaders() {
198        RawHeaders headers = new RawHeaders();
199        headers.add("WWW-Authenticate", "s1 realm=\"abc\"");
200        headers.add("WWW-Authenticate", "s2 realm=\"def\"");
201        assertEquals(Arrays.asList(new Challenge("s1", "abc"), new Challenge("s2", "def")),
202                HeaderParser.parseChallenges(headers, "WWW-Authenticate"));
203    }
204
205    public void testParseChallengesWithExtraWhitespace() {
206        RawHeaders headers = new RawHeaders();
207        headers.add("WWW-Authenticate", "  s1  realm=\"a\"  ,  s2  realm=\"b\",  ");
208        assertEquals(Arrays.asList(new Challenge("s1", "a"), new Challenge("s2", "b")),
209                HeaderParser.parseChallenges(headers, "WWW-Authenticate"));
210    }
211
212    public void testParseChallengesWithMissingRealm() {
213        RawHeaders headers = new RawHeaders();
214        headers.add("WWW-Authenticate", "Basic");
215        assertEquals(Collections.<Challenge>emptyList(),
216                HeaderParser.parseChallenges(headers, "WWW-Authenticate"));
217    }
218
219    public void testParseChallengesWithEmptyRealm() {
220        RawHeaders headers = new RawHeaders();
221        headers.add("WWW-Authenticate", "Basic realm=\"\"");
222        assertEquals(Arrays.asList(new Challenge("Basic", "")),
223                HeaderParser.parseChallenges(headers, "WWW-Authenticate"));
224    }
225
226    public void testParseChallengesWithMissingScheme() {
227        RawHeaders headers = new RawHeaders();
228        headers.add("WWW-Authenticate", "realm=\"a\"");
229        assertEquals(Collections.<Challenge>emptyList(),
230                HeaderParser.parseChallenges(headers, "WWW-Authenticate"));
231    }
232
233    // http://code.google.com/p/android/issues/detail?id=11140
234    public void testParseChallengesWithManyParameters() {
235        RawHeaders headers = new RawHeaders();
236        headers.add("WWW-Authenticate", "Digest realm=\"abc\","
237                + " qop=\"auth,auth-int\","
238                + " nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\","
239                + " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\","
240                + " Basic realm=\"def\"");
241        assertEquals(Arrays.asList(new Challenge("Digest", "abc"), new Challenge("Basic", "def")),
242                HeaderParser.parseChallenges(headers, "WWW-Authenticate"));
243    }
244}
245