HttpHeaderParserTest.java revision 8611e831aebbec7d6eebf02c8180e746c26dc05c
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 com.android.volley.toolbox; 18 19import android.test.suitebuilder.annotation.SmallTest; 20 21import com.android.volley.Cache; 22import com.android.volley.NetworkResponse; 23 24import junit.framework.TestCase; 25 26import java.text.DateFormat; 27import java.text.SimpleDateFormat; 28import java.util.Date; 29import java.util.HashMap; 30import java.util.Locale; 31import java.util.Map; 32 33@SmallTest 34public class HttpHeaderParserTest extends TestCase { 35 36 private static long ONE_MINUTE_MILLIS = 1000L * 60; 37 private static long ONE_HOUR_MILLIS = 1000L * 60 * 60; 38 39 private NetworkResponse response; 40 private Map<String, String> headers; 41 42 @Override 43 protected void setUp() throws Exception { 44 super.setUp(); 45 headers = new HashMap<String, String>(); 46 response = new NetworkResponse(0, null, headers, false); 47 } 48 49 public void testParseCacheHeaders_noHeaders() { 50 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 51 52 assertNotNull(entry); 53 assertNull(entry.etag); 54 assertEquals(0, entry.serverDate); 55 assertEquals(0, entry.ttl); 56 assertEquals(0, entry.softTtl); 57 } 58 59 public void testParseCacheHeaders_headersSet() { 60 headers.put("MyCustomHeader", "42"); 61 62 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 63 64 assertNotNull(entry); 65 assertNotNull(entry.responseHeaders); 66 assertEquals(1, entry.responseHeaders.size()); 67 assertEquals("42", entry.responseHeaders.get("MyCustomHeader")); 68 } 69 70 public void testParseCacheHeaders_etag() { 71 headers.put("ETag", "Yow!"); 72 73 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 74 75 assertNotNull(entry); 76 assertEquals("Yow!", entry.etag); 77 } 78 79 public void testParseCacheHeaders_normalExpire() { 80 long now = System.currentTimeMillis(); 81 headers.put("Date", rfc1123Date(now)); 82 headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); 83 84 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 85 86 assertNotNull(entry); 87 assertNull(entry.etag); 88 assertEqualsWithin(entry.serverDate, now, ONE_MINUTE_MILLIS); 89 assertTrue(entry.softTtl >= (now + ONE_HOUR_MILLIS)); 90 assertTrue(entry.ttl == entry.softTtl); 91 } 92 93 public void testParseCacheHeaders_expiresInPast() { 94 long now = System.currentTimeMillis(); 95 headers.put("Date", rfc1123Date(now)); 96 headers.put("Expires", rfc1123Date(now - ONE_HOUR_MILLIS)); 97 98 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 99 100 assertNotNull(entry); 101 assertNull(entry.etag); 102 assertEqualsWithin(entry.serverDate, now, ONE_MINUTE_MILLIS); 103 assertEquals(0, entry.ttl); 104 assertEquals(0, entry.softTtl); 105 } 106 107 public void testParseCacheHeaders_serverRelative() { 108 109 long now = System.currentTimeMillis(); 110 // Set "current" date as one hour in the future 111 headers.put("Date", rfc1123Date(now + ONE_HOUR_MILLIS)); 112 // TTL four hours in the future, so should be three hours from now 113 headers.put("Expires", rfc1123Date(now + 4 * ONE_HOUR_MILLIS)); 114 115 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 116 117 assertEqualsWithin(now + 3 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); 118 assertEquals(entry.softTtl, entry.ttl); 119 } 120 121 public void testParseCacheHeaders_cacheControlOverridesExpires() { 122 long now = System.currentTimeMillis(); 123 headers.put("Date", rfc1123Date(now)); 124 headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); 125 headers.put("Cache-Control", "public, max-age=86400"); 126 127 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 128 129 assertNotNull(entry); 130 assertNull(entry.etag); 131 assertEqualsWithin(now + 24 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); 132 assertEquals(entry.softTtl, entry.ttl); 133 } 134 135 public void testParseCacheHeaders_cacheControlNoCache() { 136 long now = System.currentTimeMillis(); 137 headers.put("Date", rfc1123Date(now)); 138 headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); 139 headers.put("Cache-Control", "no-cache"); 140 141 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 142 143 assertNull(entry); 144 } 145 146 public void testParseCacheHeaders_cacheControlMustRevalidate() { 147 long now = System.currentTimeMillis(); 148 headers.put("Date", rfc1123Date(now)); 149 headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); 150 headers.put("Cache-Control", "must-revalidate"); 151 152 Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); 153 154 assertNotNull(entry); 155 assertNull(entry.etag); 156 assertEqualsWithin(now, entry.ttl, ONE_MINUTE_MILLIS); 157 assertEquals(entry.softTtl, entry.ttl); 158 } 159 160 private void assertEqualsWithin(long expected, long value, long fudgeFactor) { 161 long diff = Math.abs(expected - value); 162 assertTrue(diff < fudgeFactor); 163 } 164 165 private static String rfc1123Date(long millis) { 166 DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); 167 return df.format(new Date(millis)); 168 } 169 170 // -------------------------- 171 172 public void testParseCharset() { 173 // Like the ones we usually see 174 headers.put("Content-Type", "text/plain; charset=utf-8"); 175 assertEquals("utf-8", HttpHeaderParser.parseCharset(headers)); 176 177 // Extra whitespace 178 headers.put("Content-Type", "text/plain; charset=utf-8 "); 179 assertEquals("utf-8", HttpHeaderParser.parseCharset(headers)); 180 181 // Extra parameters 182 headers.put("Content-Type", "text/plain; charset=utf-8; frozzle=bar"); 183 assertEquals("utf-8", HttpHeaderParser.parseCharset(headers)); 184 185 // No Content-Type header 186 headers.clear(); 187 assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); 188 189 // Empty value 190 headers.put("Content-Type", "text/plain; charset="); 191 assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); 192 193 // None specified 194 headers.put("Content-Type", "text/plain"); 195 assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); 196 197 // None specified, extra semicolon 198 headers.put("Content-Type", "text/plain;"); 199 assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); 200 } 201} 202