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