1package com.squareup.okhttp.apache;
2
3import com.squareup.okhttp.mockwebserver.MockResponse;
4import com.squareup.okhttp.mockwebserver.MockWebServer;
5import com.squareup.okhttp.mockwebserver.RecordedRequest;
6import java.io.ByteArrayInputStream;
7import java.io.ByteArrayOutputStream;
8import java.io.IOException;
9import java.io.InputStream;
10import java.io.OutputStreamWriter;
11import java.nio.charset.Charset;
12import java.util.Arrays;
13import java.util.zip.GZIPInputStream;
14import java.util.zip.GZIPOutputStream;
15import org.apache.http.Header;
16import org.apache.http.HttpResponse;
17import org.apache.http.client.methods.HttpGet;
18import org.apache.http.client.methods.HttpPost;
19import org.apache.http.entity.ByteArrayEntity;
20import org.apache.http.entity.InputStreamEntity;
21import org.apache.http.util.EntityUtils;
22import org.junit.After;
23import org.junit.Before;
24import org.junit.Test;
25
26import static org.junit.Assert.assertEquals;
27import static org.junit.Assert.assertNotNull;
28import static org.junit.Assert.assertNull;
29import static org.junit.Assert.assertTrue;
30
31public class OkApacheClientTest {
32  private MockWebServer server;
33  private OkApacheClient client;
34
35  @Before public void setUp() throws IOException {
36    client = new OkApacheClient();
37    server = new MockWebServer();
38    server.play();
39  }
40
41  @After public void tearDown() throws IOException {
42    server.shutdown();
43  }
44
45  @Test public void success() throws Exception {
46    server.enqueue(new MockResponse().setBody("Hello, World!"));
47
48    HttpGet request = new HttpGet(server.getUrl("/").toURI());
49    HttpResponse response = client.execute(request);
50    String actual = EntityUtils.toString(response.getEntity());
51    assertEquals("Hello, World!", actual);
52  }
53
54  @Test public void redirect() throws Exception {
55    server.enqueue(new MockResponse().setResponseCode(302).addHeader("Location", "/foo"));
56    server.enqueue(new MockResponse().setBody("Hello, Redirect!"));
57
58    HttpGet request = new HttpGet(server.getUrl("/").toURI());
59    HttpResponse response = client.execute(request);
60    String actual = EntityUtils.toString(response.getEntity());
61    assertEquals("Hello, Redirect!", actual);
62  }
63
64  @Test public void sessionExpired() throws Exception {
65    server.enqueue(new MockResponse().setResponseCode(422));
66
67    HttpGet request = new HttpGet(server.getUrl("/").toURI());
68    HttpResponse response = client.execute(request);
69    assertEquals(422, response.getStatusLine().getStatusCode());
70  }
71
72  @Test public void headers() throws Exception {
73    server.enqueue(new MockResponse().addHeader("Foo", "Bar"));
74    server.enqueue(new MockResponse().addHeader("Foo", "Bar").addHeader("Foo", "Baz"));
75
76    HttpGet request1 = new HttpGet(server.getUrl("/").toURI());
77    HttpResponse response1 = client.execute(request1);
78    Header[] headers1 = response1.getHeaders("Foo");
79    assertEquals(1, headers1.length);
80    assertEquals("Bar", headers1[0].getValue());
81
82    HttpGet request2 = new HttpGet(server.getUrl("/").toURI());
83    HttpResponse response2 = client.execute(request2);
84    Header[] headers2 = response2.getHeaders("Foo");
85    assertEquals(2, headers2.length);
86    assertEquals("Bar", headers2[0].getValue());
87    assertEquals("Baz", headers2[1].getValue());
88  }
89
90  @Test public void noEntity() throws Exception {
91    server.enqueue(new MockResponse());
92
93    HttpPost post = new HttpPost(server.getUrl("/").toURI());
94    client.execute(post);
95  }
96
97  @Test public void postByteEntity() throws Exception {
98    server.enqueue(new MockResponse());
99
100    final HttpPost post = new HttpPost(server.getUrl("/").toURI());
101    byte[] body = "Hello, world!".getBytes("UTF-8");
102    post.setEntity(new ByteArrayEntity(body));
103    client.execute(post);
104
105    RecordedRequest request = server.takeRequest();
106    assertTrue(Arrays.equals(body, request.getBody()));
107    assertEquals(request.getHeader("Content-Length"), "13");
108  }
109
110  @Test public void postInputStreamEntity() throws Exception {
111    server.enqueue(new MockResponse());
112
113    final HttpPost post = new HttpPost(server.getUrl("/").toURI());
114    byte[] body = "Hello, world!".getBytes("UTF-8");
115    post.setEntity(new InputStreamEntity(new ByteArrayInputStream(body), body.length));
116    client.execute(post);
117
118    RecordedRequest request = server.takeRequest();
119    assertTrue(Arrays.equals(body, request.getBody()));
120    assertEquals(request.getHeader("Content-Length"), "13");
121  }
122
123  @Test public void contentType() throws Exception {
124    server.enqueue(new MockResponse().setBody("<html><body><h1>Hello, World!</h1></body></html>")
125        .setHeader("Content-Type", "text/html"));
126    server.enqueue(new MockResponse().setBody("{\"Message\": { \"text\": \"Hello, World!\" } }")
127        .setHeader("Content-Type", "application/json"));
128    server.enqueue(new MockResponse().setBody("Hello, World!"));
129
130    HttpGet request1 = new HttpGet(server.getUrl("/").toURI());
131    HttpResponse response1 = client.execute(request1);
132    Header[] headers1 = response1.getHeaders("Content-Type");
133    assertEquals(1, headers1.length);
134    assertEquals("text/html", headers1[0].getValue());
135    assertNotNull(response1.getEntity().getContentType());
136    assertEquals("text/html", response1.getEntity().getContentType().getValue());
137
138    HttpGet request2 = new HttpGet(server.getUrl("/").toURI());
139    HttpResponse response2 = client.execute(request2);
140    Header[] headers2 = response2.getHeaders("Content-Type");
141    assertEquals(1, headers2.length);
142    assertEquals("application/json", headers2[0].getValue());
143    assertNotNull(response2.getEntity().getContentType());
144    assertEquals("application/json", response2.getEntity().getContentType().getValue());
145
146    HttpGet request3 = new HttpGet(server.getUrl("/").toURI());
147    HttpResponse response3 = client.execute(request3);
148    Header[] headers3 = response3.getHeaders("Content-Type");
149    assertEquals(0, headers3.length);
150    assertNull(response3.getEntity().getContentType());
151  }
152
153  @Test public void contentEncoding() throws Exception {
154    String text = "{\"Message\": { \"text\": \"Hello, World!\" } }";
155    ByteArrayOutputStream bodyBytes = new ByteArrayOutputStream();
156    OutputStreamWriter body = new OutputStreamWriter(new GZIPOutputStream(bodyBytes),
157        Charset.forName("UTF-8"));
158    body.write(text);
159    body.close();
160    server.enqueue(new MockResponse().setBody(bodyBytes.toByteArray())
161        .setHeader("Content-Encoding", "gzip"));
162
163    byte[] tmp = new byte[32];
164
165    HttpGet request1 = new HttpGet(server.getUrl("/").toURI());
166    request1.setHeader("Accept-encoding", "gzip"); // not transparent gzip
167    HttpResponse response1 = client.execute(request1);
168    Header[] headers1 = response1.getHeaders("Content-Encoding");
169    assertEquals(1, headers1.length);
170    assertEquals("gzip", headers1[0].getValue());
171    assertNotNull(response1.getEntity().getContentEncoding());
172    assertEquals("gzip", response1.getEntity().getContentEncoding().getValue());
173    InputStream content = new GZIPInputStream(response1.getEntity().getContent());
174    ByteArrayOutputStream rspBodyBytes = new ByteArrayOutputStream();
175    for (int len = content.read(tmp); len >= 0; len = content.read(tmp)) {
176      rspBodyBytes.write(tmp, 0, len);
177    }
178    String decodedContent = rspBodyBytes.toString("UTF-8");
179    assertEquals(text, decodedContent);
180  }
181
182  @Test public void jsonGzipResponse() throws Exception {
183    String text = "{\"Message\": { \"text\": \"Hello, World!\" } }";
184    ByteArrayOutputStream bodyBytes = new ByteArrayOutputStream();
185    OutputStreamWriter body = new OutputStreamWriter(new GZIPOutputStream(bodyBytes),
186        Charset.forName("UTF-8"));
187    body.write(text);
188    body.close();
189    server.enqueue(new MockResponse().setBody(bodyBytes.toByteArray())
190        .setHeader("Content-Encoding", "gzip")
191        .setHeader("Content-Type", "application/json"));
192
193    byte[] tmp = new byte[32];
194
195    HttpGet request1 = new HttpGet(server.getUrl("/").toURI());
196    request1.setHeader("Accept-encoding", "gzip"); // not transparent gzip
197    HttpResponse response1 = client.execute(request1);
198    Header[] headers1a = response1.getHeaders("Content-Encoding");
199    assertEquals(1, headers1a.length);
200    assertEquals("gzip", headers1a[0].getValue());
201    assertNotNull(response1.getEntity().getContentEncoding());
202    assertEquals("gzip", response1.getEntity().getContentEncoding().getValue());
203    Header[] headers1b = response1.getHeaders("Content-Type");
204    assertEquals(1, headers1b.length);
205    assertEquals("application/json", headers1b[0].getValue());
206    assertNotNull(response1.getEntity().getContentType());
207    assertEquals("application/json", response1.getEntity().getContentType().getValue());
208    InputStream content = new GZIPInputStream(response1.getEntity().getContent());
209    ByteArrayOutputStream rspBodyBytes = new ByteArrayOutputStream();
210    for (int len = content.read(tmp); len >= 0; len = content.read(tmp)) {
211      rspBodyBytes.write(tmp, 0, len);
212    }
213    String decodedContent = rspBodyBytes.toString("UTF-8");
214    assertEquals(text, decodedContent);
215  }
216
217  @Test public void jsonTransparentGzipResponse() throws Exception {
218    String text = "{\"Message\": { \"text\": \"Hello, World!\" } }";
219    ByteArrayOutputStream bodyBytes = new ByteArrayOutputStream();
220    OutputStreamWriter body = new OutputStreamWriter(new GZIPOutputStream(bodyBytes),
221        Charset.forName("UTF-8"));
222    body.write(text);
223    body.close();
224    server.enqueue(new MockResponse().setBody(bodyBytes.toByteArray())
225        .setHeader("Content-Encoding", "gzip")
226        .setHeader("Content-Type", "application/json"));
227
228    byte[] tmp = new byte[32];
229
230    HttpGet request1 = new HttpGet(server.getUrl("/").toURI());
231    // expecting transparent gzip response by not adding header "Accept-encoding: gzip"
232    HttpResponse response1 = client.execute(request1);
233    Header[] headers1a = response1.getHeaders("Content-Encoding");
234    assertEquals(0, headers1a.length);
235    assertNull(response1.getEntity().getContentEncoding());
236    // content length should also be absent
237    Header[] headers1b = response1.getHeaders("Content-Length");
238    assertEquals(0, headers1b.length);
239    assertTrue(response1.getEntity().getContentLength() < 0);
240    Header[] headers1c = response1.getHeaders("Content-Type");
241    assertEquals(1, headers1c.length);
242    assertEquals("application/json", headers1c[0].getValue());
243    assertNotNull(response1.getEntity().getContentType());
244    assertEquals("application/json", response1.getEntity().getContentType().getValue());
245    InputStream content = response1.getEntity().getContent();
246    ByteArrayOutputStream rspBodyBytes = new ByteArrayOutputStream();
247    for (int len = content.read(tmp); len >= 0; len = content.read(tmp)) {
248      rspBodyBytes.write(tmp, 0, len);
249    }
250    String decodedContent = rspBodyBytes.toString("UTF-8");
251    assertEquals(text, decodedContent);
252  }
253}
254