ResponseCacheAdapterTest.java revision 4944713f5c5b141966ac82973d6a31a634e8e01e
1/* 2 * Copyright (C) 2014 Square, Inc. 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 */ 16package com.squareup.okhttp.internal.http; 17 18import com.squareup.okhttp.OkHttpClient; 19import com.squareup.okhttp.internal.SslContextBuilder; 20import com.squareup.okhttp.mockwebserver.MockResponse; 21import com.squareup.okhttp.mockwebserver.MockWebServer; 22 23import org.junit.After; 24import org.junit.Before; 25import org.junit.Test; 26 27import java.io.IOException; 28import java.net.CacheRequest; 29import java.net.CacheResponse; 30import java.net.HttpURLConnection; 31import java.net.ResponseCache; 32import java.net.URI; 33import java.net.URISyntaxException; 34import java.net.URL; 35import java.net.URLConnection; 36import java.util.Collections; 37import java.util.List; 38import java.util.Map; 39 40import javax.net.ssl.HostnameVerifier; 41import javax.net.ssl.HttpsURLConnection; 42import javax.net.ssl.SSLContext; 43import javax.net.ssl.SSLSession; 44 45import static org.junit.Assert.assertArrayEquals; 46import static org.junit.Assert.assertEquals; 47import static org.junit.Assert.assertFalse; 48import static org.junit.Assert.assertNotNull; 49import static org.junit.Assert.assertNull; 50import static org.junit.Assert.assertTrue; 51import static org.junit.Assert.fail; 52 53/** 54 * A white-box test for {@link ResponseCacheAdapter}. See also: 55 * <ul> 56 * <li>{@link ResponseCacheTest} for black-box tests that check that {@link ResponseCache} 57 * classes are called correctly by OkHttp.</li> 58 * <li>{@link JavaApiConverterTest} for tests that check Java API classes / OkHttp conversion 59 * logic. </li> 60 * </ul> 61 */ 62public class ResponseCacheAdapterTest { 63 64 private static final SSLContext sslContext = SslContextBuilder.localhost(); 65 private static final HostnameVerifier NULL_HOSTNAME_VERIFIER = new HostnameVerifier() { 66 public boolean verify(String hostname, SSLSession session) { 67 return true; 68 } 69 }; 70 71 private MockWebServer server; 72 73 private OkHttpClient client; 74 75 private HttpURLConnection connection; 76 77 @Before public void setUp() throws Exception { 78 server = new MockWebServer(); 79 client = new OkHttpClient(); 80 } 81 82 @After public void tearDown() throws Exception { 83 if (connection != null) { 84 connection.disconnect(); 85 } 86 server.shutdown(); 87 } 88 89 @Test public void get_httpGet() throws Exception { 90 final URL serverUrl = configureServer(new MockResponse()); 91 assertEquals("http", serverUrl.getProtocol()); 92 93 ResponseCache responseCache = new NoOpResponseCache() { 94 @Override 95 public CacheResponse get(URI uri, String method, Map<String, List<String>> headers) throws IOException { 96 assertEquals(toUri(serverUrl), uri); 97 assertEquals("GET", method); 98 assertTrue("Arbitrary standard header not present", headers.containsKey("User-Agent")); 99 assertEquals(Collections.singletonList("value1"), headers.get("key1")); 100 return null; 101 } 102 }; 103 client.setResponseCache(responseCache); 104 105 connection = client.open(serverUrl); 106 connection.setRequestProperty("key1", "value1"); 107 108 executeGet(connection); 109 } 110 111 @Test public void get_httpsGet() throws Exception { 112 final URL serverUrl = configureHttpsServer(new MockResponse()); 113 assertEquals("https", serverUrl.getProtocol()); 114 115 ResponseCache responseCache = new NoOpResponseCache() { 116 @Override 117 public CacheResponse get(URI uri, String method, Map<String, List<String>> headers) 118 throws IOException { 119 assertEquals("https", uri.getScheme()); 120 assertEquals(toUri(serverUrl), uri); 121 assertEquals("GET", method); 122 assertTrue("Arbitrary standard header not present", headers.containsKey("User-Agent")); 123 assertEquals(Collections.singletonList("value1"), headers.get("key1")); 124 return null; 125 } 126 }; 127 client.setResponseCache(responseCache); 128 client.setSslSocketFactory(sslContext.getSocketFactory()); 129 client.setHostnameVerifier(NULL_HOSTNAME_VERIFIER); 130 131 connection = client.open(serverUrl); 132 connection.setRequestProperty("key1", "value1"); 133 134 executeGet(connection); 135 } 136 137 @Test public void put_httpGet() throws Exception { 138 final String statusLine = "HTTP/1.1 200 Fantastic"; 139 final URL serverUrl = configureServer( 140 new MockResponse() 141 .setStatus(statusLine) 142 .addHeader("A", "c")); 143 144 ResponseCache responseCache = new NoOpResponseCache() { 145 @Override 146 public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException { 147 assertTrue(urlConnection instanceof HttpURLConnection); 148 assertFalse(urlConnection instanceof HttpsURLConnection); 149 150 assertEquals(0, urlConnection.getContentLength()); 151 152 HttpURLConnection httpUrlConnection = (HttpURLConnection) urlConnection; 153 assertEquals("GET", httpUrlConnection.getRequestMethod()); 154 assertTrue(httpUrlConnection.getDoInput()); 155 assertFalse(httpUrlConnection.getDoOutput()); 156 157 assertEquals("Fantastic", httpUrlConnection.getResponseMessage()); 158 assertEquals(toUri(serverUrl), uri); 159 assertEquals(serverUrl, urlConnection.getURL()); 160 assertEquals("value", urlConnection.getRequestProperty("key")); 161 162 // Check retrieval by string key. 163 assertEquals(statusLine, httpUrlConnection.getHeaderField(null)); 164 assertEquals("c", httpUrlConnection.getHeaderField("A")); 165 // The RI and OkHttp supports case-insensitive matching for this method. 166 assertEquals("c", httpUrlConnection.getHeaderField("a")); 167 return null; 168 } 169 }; 170 client.setResponseCache(responseCache); 171 172 connection = client.open(serverUrl); 173 connection.setRequestProperty("key", "value"); 174 executeGet(connection); 175 } 176 177 @Test public void put_httpPost() throws Exception { 178 final String statusLine = "HTTP/1.1 200 Fantastic"; 179 final URL serverUrl = configureServer( 180 new MockResponse() 181 .setStatus(statusLine) 182 .addHeader("A", "c")); 183 184 ResponseCache responseCache = new NoOpResponseCache() { 185 @Override 186 public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException { 187 assertTrue(urlConnection instanceof HttpURLConnection); 188 assertFalse(urlConnection instanceof HttpsURLConnection); 189 190 assertEquals(0, urlConnection.getContentLength()); 191 192 HttpURLConnection httpUrlConnection = (HttpURLConnection) urlConnection; 193 assertEquals("POST", httpUrlConnection.getRequestMethod()); 194 assertTrue(httpUrlConnection.getDoInput()); 195 assertTrue(httpUrlConnection.getDoOutput()); 196 197 assertEquals("Fantastic", httpUrlConnection.getResponseMessage()); 198 assertEquals(toUri(serverUrl), uri); 199 assertEquals(serverUrl, urlConnection.getURL()); 200 assertEquals("value", urlConnection.getRequestProperty("key")); 201 202 // Check retrieval by string key. 203 assertEquals(statusLine, httpUrlConnection.getHeaderField(null)); 204 assertEquals("c", httpUrlConnection.getHeaderField("A")); 205 // The RI and OkHttp supports case-insensitive matching for this method. 206 assertEquals("c", httpUrlConnection.getHeaderField("a")); 207 return null; 208 } 209 }; 210 client.setResponseCache(responseCache); 211 212 connection = client.open(serverUrl); 213 214 executePost(connection); 215 } 216 217 @Test public void put_httpsGet() throws Exception { 218 final URL serverUrl = configureHttpsServer(new MockResponse()); 219 assertEquals("https", serverUrl.getProtocol()); 220 221 ResponseCache responseCache = new NoOpResponseCache() { 222 @Override 223 public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException { 224 assertTrue(urlConnection instanceof HttpsURLConnection); 225 assertEquals(toUri(serverUrl), uri); 226 assertEquals(serverUrl, urlConnection.getURL()); 227 228 HttpsURLConnection cacheHttpsUrlConnection = (HttpsURLConnection) urlConnection; 229 HttpsURLConnection realHttpsUrlConnection = (HttpsURLConnection) connection; 230 assertEquals(realHttpsUrlConnection.getCipherSuite(), 231 cacheHttpsUrlConnection.getCipherSuite()); 232 assertEquals(realHttpsUrlConnection.getPeerPrincipal(), 233 cacheHttpsUrlConnection.getPeerPrincipal()); 234 assertArrayEquals(realHttpsUrlConnection.getLocalCertificates(), 235 cacheHttpsUrlConnection.getLocalCertificates()); 236 assertArrayEquals(realHttpsUrlConnection.getServerCertificates(), 237 cacheHttpsUrlConnection.getServerCertificates()); 238 assertEquals(realHttpsUrlConnection.getLocalPrincipal(), 239 cacheHttpsUrlConnection.getLocalPrincipal()); 240 return null; 241 } 242 }; 243 client.setResponseCache(responseCache); 244 client.setSslSocketFactory(sslContext.getSocketFactory()); 245 client.setHostnameVerifier(NULL_HOSTNAME_VERIFIER); 246 247 connection = client.open(serverUrl); 248 executeGet(connection); 249 } 250 251 private void executeGet(HttpURLConnection connection) throws IOException { 252 connection.connect(); 253 connection.getHeaderFields(); 254 connection.disconnect(); 255 } 256 257 private void executePost(HttpURLConnection connection) throws IOException { 258 connection.setDoOutput(true); 259 connection.connect(); 260 connection.getOutputStream().write("Hello World".getBytes()); 261 connection.disconnect(); 262 } 263 264 private URL configureServer(MockResponse mockResponse) throws Exception { 265 server.enqueue(mockResponse); 266 server.play(); 267 return server.getUrl("/"); 268 } 269 270 private URL configureHttpsServer(MockResponse mockResponse) throws Exception { 271 server.useHttps(sslContext.getSocketFactory(), false /* tunnelProxy */); 272 server.enqueue(mockResponse); 273 server.play(); 274 return server.getUrl("/"); 275 } 276 277 private static class NoOpResponseCache extends ResponseCache { 278 279 @Override 280 public CacheResponse get(URI uri, String s, Map<String, List<String>> stringListMap) 281 throws IOException { 282 return null; 283 } 284 285 @Override 286 public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException { 287 return null; 288 } 289 } 290 291 private static URI toUri(URL serverUrl) { 292 try { 293 return serverUrl.toURI(); 294 } catch (URISyntaxException e) { 295 fail(e.getMessage()); 296 return null; 297 } 298 } 299} 300