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