SyncApiTest.java revision 3c938a3f6b61ce5e2dba0d039b03fe73b89fd26c
13c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller/* 23c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Copyright (C) 2014 Square, Inc. 33c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 43c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License"); 53c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * you may not use this file except in compliance with the License. 63c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * You may obtain a copy of the License at 73c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 83c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * http://www.apache.org/licenses/LICENSE-2.0 93c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 103c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Unless required by applicable law or agreed to in writing, software 113c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS, 123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * See the License for the specific language governing permissions and 143c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * limitations under the License. 153c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerpackage com.squareup.okhttp; 173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.internal.RecordingHostnameVerifier; 193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.internal.SslContextBuilder; 203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.mockwebserver.MockResponse; 213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.mockwebserver.MockWebServer; 223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.mockwebserver.RecordedRequest; 233c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport com.squareup.okhttp.mockwebserver.SocketPolicy; 243c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.io.File; 253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.io.IOException; 263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.net.HttpURLConnection; 273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport java.util.UUID; 283c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport javax.net.ssl.SSLContext; 293c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport org.junit.After; 303c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport org.junit.Before; 313c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport org.junit.Test; 323c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport static org.junit.Assert.assertEquals; 343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport static org.junit.Assert.assertNull; 353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport static org.junit.Assert.assertTrue; 363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerimport static org.junit.Assert.fail; 373c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 383c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerpublic final class SyncApiTest { 393c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private MockWebServer server = new MockWebServer(); 403c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private OkHttpClient client = new OkHttpClient(); 413c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private static final SSLContext sslContext = SslContextBuilder.localhost(); 433c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private HttpResponseCache cache; 443c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 453c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Before public void setUp() throws Exception { 463c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller String tmp = System.getProperty("java.io.tmpdir"); 473c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller File cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID()); 483c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller cache = new HttpResponseCache(cacheDir, Integer.MAX_VALUE); 493c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 503c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 513c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @After public void tearDown() throws Exception { 523c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.shutdown(); 533c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller cache.delete(); 543c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 553c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 563c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void get() throws Exception { 573c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 583c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("abc") 593c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Content-Type: text/plain")); 603c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 613c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 623c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder() 633c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .url(server.getUrl("/")) 643c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .header("User-Agent", "SyncApiTest") 653c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .build(); 663c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 673c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(request) 683c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(200) 693c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertContainsHeaders("Content-Type: text/plain") 703c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("abc"); 713c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 723c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertTrue(server.takeRequest().getHeaders().contains("User-Agent: SyncApiTest")); 733c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 743c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 753c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void connectionPooling() throws Exception { 763c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setBody("abc")); 773c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setBody("def")); 783c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setBody("ghi")); 793c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 803c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 813c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/a")).build()) 823c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("abc"); 833c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 843c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/b")).build()) 853c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("def"); 863c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 873c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/c")).build()) 883c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("ghi"); 893c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 903c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(0, server.takeRequest().getSequenceNumber()); 913c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(1, server.takeRequest().getSequenceNumber()); 923c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(2, server.takeRequest().getSequenceNumber()); 933c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 943c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 953c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void tls() throws Exception { 963c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.useHttps(sslContext.getSocketFactory(), false); 973c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 983c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("abc") 993c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Content-Type: text/plain")); 1003c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 1013c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1023c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller client.setSslSocketFactory(sslContext.getSocketFactory()); 1033c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller client.setHostnameVerifier(new RecordingHostnameVerifier()); 1043c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1053c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/")).build()) 1063c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertHandshake(); 1073c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1083c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1093c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void recoverFromTlsHandshakeFailure() throws Exception { 1103c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.useHttps(sslContext.getSocketFactory(), false); 1113c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.FAIL_HANDSHAKE)); 1123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setBody("abc")); 1133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 1143c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1153c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller client.setSslSocketFactory(sslContext.getSocketFactory()); 1163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller client.setHostnameVerifier(new RecordingHostnameVerifier()); 1173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/")).build()) 1193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("abc"); 1203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void post() throws Exception { 1233c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setBody("abc")); 1243c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 1253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder() 1273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .url(server.getUrl("/")) 1283c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .post(Request.Body.create(MediaType.parse("text/plain"), "def")) 1293c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .build(); 1303c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1313c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(request) 1323c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(200) 1333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("abc"); 1343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller RecordedRequest recordedRequest = server.takeRequest(); 1363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("def", recordedRequest.getUtf8Body()); 1373c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("3", recordedRequest.getHeader("Content-Length")); 1383c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("text/plain; charset=utf-8", recordedRequest.getHeader("Content-Type")); 1393c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1403c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1413c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void cache() throws Exception { 1423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setBody("A").addHeader("ETag: v1")); 1433c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_NOT_MODIFIED)); 1443c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 1453c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1463c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller client.setOkResponseCache(cache); 1473c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1483c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/")).build()) 1493c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(200).assertBody("A"); 1503c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertNull(server.takeRequest().getHeader("If-None-Match")); 1513c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1523c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/")).build()) 1533c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(200).assertBody("A"); 1543c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("v1", server.takeRequest().getHeader("If-None-Match")); 1553c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1563c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1573c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void redirect() throws Exception { 1583c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 1593c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setResponseCode(301) 1603c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Location: /b") 1613c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Test", "Redirect from /a to /b") 1623c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("/a has moved!")); 1633c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 1643c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setResponseCode(302) 1653c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Location: /c") 1663c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Test", "Redirect from /b to /c") 1673c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("/b has moved!")); 1683c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setBody("C")); 1693c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 1703c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1713c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/a")).build()) 1723c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(200) 1733c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("C") 1743c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .redirectedBy() 1753c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(302) 1763c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertContainsHeaders("Test: Redirect from /b to /c") 1773c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .redirectedBy() 1783c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(301) 1793c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertContainsHeaders("Test: Redirect from /a to /b"); 1803c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1813c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(0, server.takeRequest().getSequenceNumber()); // New connection. 1823c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(1, server.takeRequest().getSequenceNumber()); // Connection reused. 1833c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(2, server.takeRequest().getSequenceNumber()); // Connection reused again! 1843c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 1853c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1863c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void redirectWithRedirectsDisabled() throws Exception { 1873c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller client.setFollowProtocolRedirects(false); 1883c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 1893c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setResponseCode(301) 1903c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Location: /b") 1913c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Test", "Redirect from /a to /b") 1923c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("/a has moved!")); 1933c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 1943c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 1953c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/a")).build()) 1963c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(301) 1973c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("/a has moved!") 1983c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertContainsHeaders("Location: /b"); 1993c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2003c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2013c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void follow20Redirects() throws Exception { 2023c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller for (int i = 0; i < 20; i++) { 2033c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 2043c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setResponseCode(301) 2053c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Location: /" + (i + 1)) 2063c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("Redirecting to /" + (i + 1))); 2073c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2083c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse().setBody("Success!")); 2093c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 2103c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2113c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(new Request.Builder().url(server.getUrl("/0")).build()) 2123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(200) 2133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("Success!"); 2143c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2153c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void doesNotFollow21Redirects() throws Exception { 2173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller for (int i = 0; i < 21; i++) { 2183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 2193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setResponseCode(301) 2203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Location: /" + (i + 1)) 2213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("Redirecting to /" + (i + 1))); 2223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2233c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 2243c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller try { 2263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller client.execute(new Request.Builder().url(server.getUrl("/0")).build()); 2273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller fail(); 2283c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } catch (IOException e) { 2293c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("Too many redirects: 21", e.getMessage()); 2303c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2313c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2323c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller @Test public void postBodyRetransmittedOnRedirect() throws Exception { 2343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 2353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setResponseCode(302) 2363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .addHeader("Location: /b") 2373c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("Moved to /b !")); 2383c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.enqueue(new MockResponse() 2393c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .setBody("This is b.")); 2403c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller server.play(); 2413c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Request request = new Request.Builder() 2433c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .url(server.getUrl("/")) 2443c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .post(Request.Body.create(MediaType.parse("text/plain"), "body!")) 2453c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .build(); 2463c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2473c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller onSuccess(request) 2483c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertCode(200) 2493c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller .assertBody("This is b."); 2503c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2513c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller RecordedRequest request1 = server.takeRequest(); 2523c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("body!", request1.getUtf8Body()); 2533c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("5", request1.getHeader("Content-Length")); 2543c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("text/plain; charset=utf-8", request1.getHeader("Content-Type")); 2553c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(0, request1.getSequenceNumber()); 2563c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2573c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller RecordedRequest request2 = server.takeRequest(); 2583c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("body!", request2.getUtf8Body()); 2593c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("5", request2.getHeader("Content-Length")); 2603c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals("text/plain; charset=utf-8", request2.getHeader("Content-Type")); 2613c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller assertEquals(1, request2.getSequenceNumber()); 2623c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2633c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 2643c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private RecordedResponse onSuccess(Request request) throws IOException { 2653c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Response response = client.execute(request); 2663c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return new RecordedResponse(request, response, response.body().string(), null); 2673c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 2683c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller} 269