HttpHeaderParserTest.java revision ba53551261044a9811835c1fb89d4ec48a88a43b
1d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/*
2d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Copyright (C) 2011 The Android Open Source Project
3d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
4d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License");
5d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * you may not use this file except in compliance with the License.
6d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * You may obtain a copy of the License at
7d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
8d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *      http://www.apache.org/licenses/LICENSE-2.0
9d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
10d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software
11d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS,
12d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * See the License for the specific language governing permissions and
14d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * limitations under the License.
15d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */
16d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
17d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupackage com.android.volley.toolbox;
18d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
19d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.test.suitebuilder.annotation.SmallTest;
20d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
21d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.Cache;
22d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.NetworkResponse;
23d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
248611e831aebbec7d6eebf02c8180e746c26dc05cRalph Bergmannimport junit.framework.TestCase;
258611e831aebbec7d6eebf02c8180e746c26dc05cRalph Bergmann
26ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmannimport org.apache.http.Header;
27ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmannimport org.apache.http.message.BasicHeader;
28ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann
29d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.text.DateFormat;
30d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.text.SimpleDateFormat;
31d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Date;
32d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.HashMap;
338611e831aebbec7d6eebf02c8180e746c26dc05cRalph Bergmannimport java.util.Locale;
34d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Map;
35d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
36d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru@SmallTest
37d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupublic class HttpHeaderParserTest extends TestCase {
38d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
39d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private static long ONE_MINUTE_MILLIS = 1000L * 60;
40d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private static long ONE_HOUR_MILLIS = 1000L * 60 * 60;
41d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
42d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private NetworkResponse response;
43d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private Map<String, String> headers;
44d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
45d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    @Override
46d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    protected void setUp() throws Exception {
47d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        super.setUp();
48d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers = new HashMap<String, String>();
49d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        response = new NetworkResponse(0, null, headers, false);
50d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
51d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
52d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCacheHeaders_noHeaders() {
53d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
54d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
55d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNotNull(entry);
56d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNull(entry.etag);
57d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals(0, entry.serverDate);
58d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals(0, entry.ttl);
59d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals(0, entry.softTtl);
60d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
61d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
62e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru    public void testParseCacheHeaders_headersSet() {
63e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru        headers.put("MyCustomHeader", "42");
64e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru
65e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
66e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru
67e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru        assertNotNull(entry);
68e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru        assertNotNull(entry.responseHeaders);
69e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru        assertEquals(1, entry.responseHeaders.size());
70e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru        assertEquals("42", entry.responseHeaders.get("MyCustomHeader"));
71e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru    }
72e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru
73d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCacheHeaders_etag() {
74d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("ETag", "Yow!");
75d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
76d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
77d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
78d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNotNull(entry);
79d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals("Yow!", entry.etag);
80d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
81d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
82d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCacheHeaders_normalExpire() {
83d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        long now = System.currentTimeMillis();
84d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Date", rfc1123Date(now));
85d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS));
86d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
87d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
88d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
89d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNotNull(entry);
90d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNull(entry.etag);
91d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEqualsWithin(entry.serverDate, now, ONE_MINUTE_MILLIS);
92d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertTrue(entry.softTtl >= (now + ONE_HOUR_MILLIS));
93d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertTrue(entry.ttl == entry.softTtl);
94d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
95d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
96d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCacheHeaders_expiresInPast() {
97d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        long now = System.currentTimeMillis();
98d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Date", rfc1123Date(now));
99d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Expires", rfc1123Date(now - ONE_HOUR_MILLIS));
100d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
101d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
102d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
103d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNotNull(entry);
104d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNull(entry.etag);
105d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEqualsWithin(entry.serverDate, now, ONE_MINUTE_MILLIS);
106d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals(0, entry.ttl);
107d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals(0, entry.softTtl);
108d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
109d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
110d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCacheHeaders_serverRelative() {
111d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
112d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        long now = System.currentTimeMillis();
113d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // Set "current" date as one hour in the future
114d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Date", rfc1123Date(now + ONE_HOUR_MILLIS));
115d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // TTL four hours in the future, so should be three hours from now
116d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Expires", rfc1123Date(now + 4 * ONE_HOUR_MILLIS));
117d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
118d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
119d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
120d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEqualsWithin(now + 3 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS);
121d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals(entry.softTtl, entry.ttl);
122d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
123d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
124d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCacheHeaders_cacheControlOverridesExpires() {
125d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        long now = System.currentTimeMillis();
126d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Date", rfc1123Date(now));
127d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS));
128d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Cache-Control", "public, max-age=86400");
129d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
130d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
131d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
132d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNotNull(entry);
133d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNull(entry.etag);
134d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEqualsWithin(now + 24 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS);
135d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals(entry.softTtl, entry.ttl);
136d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
137d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
138d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCacheHeaders_cacheControlNoCache() {
139d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        long now = System.currentTimeMillis();
140d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Date", rfc1123Date(now));
141d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS));
142d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Cache-Control", "no-cache");
143d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
144d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
145d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
146d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNull(entry);
147d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
148d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
149d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCacheHeaders_cacheControlMustRevalidate() {
150d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        long now = System.currentTimeMillis();
151d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Date", rfc1123Date(now));
152d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS));
153d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Cache-Control", "must-revalidate");
154d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
155d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
156d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
157d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNotNull(entry);
158d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertNull(entry.etag);
159d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEqualsWithin(now, entry.ttl, ONE_MINUTE_MILLIS);
160d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals(entry.softTtl, entry.ttl);
161d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
162d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
163d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private void assertEqualsWithin(long expected, long value, long fudgeFactor) {
164d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        long diff = Math.abs(expected - value);
165d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertTrue(diff < fudgeFactor);
166d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
167d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
168d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private static String rfc1123Date(long millis) {
1698611e831aebbec7d6eebf02c8180e746c26dc05cRalph Bergmann        DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
170d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        return df.format(new Date(millis));
171d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
172d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
173d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    // --------------------------
174d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
175d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testParseCharset() {
176d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // Like the ones we usually see
177d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Content-Type", "text/plain; charset=utf-8");
178d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals("utf-8", HttpHeaderParser.parseCharset(headers));
179d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
180d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // Extra whitespace
181d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Content-Type", "text/plain;    charset=utf-8 ");
182d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals("utf-8", HttpHeaderParser.parseCharset(headers));
183d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
184d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // Extra parameters
185d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Content-Type", "text/plain; charset=utf-8; frozzle=bar");
186d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals("utf-8", HttpHeaderParser.parseCharset(headers));
187d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
188d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // No Content-Type header
189d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.clear();
190d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers));
191d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
192d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // Empty value
193d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Content-Type", "text/plain; charset=");
194d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers));
195d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
196d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // None specified
197d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Content-Type", "text/plain");
198d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers));
199d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
200d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // None specified, extra semicolon
201d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        headers.put("Content-Type", "text/plain;");
202d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers));
203d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
204ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann
205ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann    public void testParseCaseInsensitive() {
206ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann
207ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        long now = System.currentTimeMillis();
208ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann
209ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        Header[] headersArray = new Header[5];
210ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        headersArray[0] = new BasicHeader("eTAG", "Yow!");
211ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        headersArray[1] = new BasicHeader("DATE", rfc1123Date(now));
212ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        headersArray[2] = new BasicHeader("expires", rfc1123Date(now + ONE_HOUR_MILLIS));
213ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        headersArray[3] = new BasicHeader("cache-control", "public, max-age=86400");
214ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        headersArray[4] = new BasicHeader("content-type", "text/plain");
215ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann
216ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        Map<String, String> headers = BasicNetwork.convertHeaders(headersArray);
217ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        NetworkResponse response = new NetworkResponse(0, null, headers, false);
218ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
219ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann
220ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        assertNotNull(entry);
221ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        assertEquals("Yow!", entry.etag);
222ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        assertEqualsWithin(now + 24 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS);
223ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        assertEquals(entry.softTtl, entry.ttl);
224ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann        assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers));
225ba53551261044a9811835c1fb89d4ec48a88a43bRalph Bergmann    }
226d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru}
227