1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.http.impl;
28
29 import java.io.ByteArrayInputStream;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.net.InetAddress;
33 import java.net.InetSocketAddress;
34 import java.net.Socket;
35 import java.net.SocketException;
36 import java.net.SocketTimeoutException;
37
38 import org.apache.http.Header;
39 import org.apache.http.HttpEntity;
40 import org.apache.http.HttpResponse;
41 import org.apache.http.HttpVersion;
42 import org.apache.http.config.MessageConstraints;
43 import org.apache.http.impl.entity.LaxContentLengthStrategy;
44 import org.apache.http.impl.entity.StrictContentLengthStrategy;
45 import org.apache.http.impl.io.ChunkedInputStream;
46 import org.apache.http.impl.io.ChunkedOutputStream;
47 import org.apache.http.impl.io.ContentLengthInputStream;
48 import org.apache.http.impl.io.ContentLengthOutputStream;
49 import org.apache.http.impl.io.IdentityInputStream;
50 import org.apache.http.impl.io.IdentityOutputStream;
51 import org.apache.http.message.BasicHttpResponse;
52 import org.junit.Assert;
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.mockito.Matchers;
56 import org.mockito.Mock;
57 import org.mockito.Mockito;
58 import org.mockito.MockitoAnnotations;
59
60 public class TestBHttpConnectionBase {
61
62 @Mock
63 private Socket socket;
64
65 private BHttpConnectionBase conn;
66
67 @Before
68 public void setUp() throws Exception {
69 MockitoAnnotations.initMocks(this);
70 conn = new BHttpConnectionBase(1024, 1024,
71 null, null,
72 MessageConstraints.DEFAULT,
73 LaxContentLengthStrategy.INSTANCE,
74 StrictContentLengthStrategy.INSTANCE);
75 }
76
77 @Test
78 public void testBasics() throws Exception {
79 Assert.assertFalse(conn.isOpen());
80 Assert.assertEquals(-1, conn.getLocalPort());
81 Assert.assertEquals(-1, conn.getRemotePort());
82 Assert.assertEquals(null, conn.getLocalAddress());
83 Assert.assertEquals(null, conn.getRemoteAddress());
84 Assert.assertEquals("[Not bound]", conn.toString());
85 }
86
87 @Test
88 public void testSocketBind() throws Exception {
89 final InetAddress localAddress = InetAddress.getByAddress(new byte[] {127, 0, 0, 1});
90 final int localPort = 8888;
91 final InetAddress remoteAddress = InetAddress.getByAddress(new byte[] {10, 0, 0, 2});
92 final int remotePort = 80;
93 final InetSocketAddress localSockAddress = new InetSocketAddress(localAddress, localPort);
94 final InetSocketAddress remoteSockAddress = new InetSocketAddress(remoteAddress, remotePort);
95 Mockito.when(socket.getLocalSocketAddress()).thenReturn(localSockAddress);
96 Mockito.when(socket.getRemoteSocketAddress()).thenReturn(remoteSockAddress);
97 Mockito.when(socket.getLocalAddress()).thenReturn(localAddress);
98 Mockito.when(socket.getLocalPort()).thenReturn(localPort);
99 Mockito.when(socket.getInetAddress()).thenReturn(remoteAddress);
100 Mockito.when(socket.getPort()).thenReturn(remotePort);
101 conn.bind(socket);
102
103 Assert.assertEquals("127.0.0.1:8888<->10.0.0.2:80", conn.toString());
104 Assert.assertTrue(conn.isOpen());
105 Assert.assertEquals(8888, conn.getLocalPort());
106 Assert.assertEquals(80, conn.getRemotePort());
107 Assert.assertEquals(InetAddress.getByAddress(new byte[] {127, 0, 0, 1}), conn.getLocalAddress());
108 Assert.assertEquals(InetAddress.getByAddress(new byte[] {10, 0, 0, 2}), conn.getRemoteAddress());
109 }
110
111 @Test
112 public void testConnectionClose() throws Exception {
113 final InputStream inStream = Mockito.mock(InputStream.class);
114 final OutputStream outStream = Mockito.mock(OutputStream.class);
115
116 Mockito.when(socket.getInputStream()).thenReturn(inStream);
117 Mockito.when(socket.getOutputStream()).thenReturn(outStream);
118
119 conn.bind(socket);
120 conn.ensureOpen();
121 conn.getSessionOutputBuffer().write(0);
122
123 Assert.assertTrue(conn.isOpen());
124
125 conn.close();
126
127 Assert.assertFalse(conn.isOpen());
128
129 Mockito.verify(outStream, Mockito.times(1)).write(
130 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
131 Mockito.verify(socket, Mockito.times(1)).shutdownInput();
132 Mockito.verify(socket, Mockito.times(1)).shutdownOutput();
133 Mockito.verify(socket, Mockito.times(1)).close();
134
135 conn.close();
136 Mockito.verify(socket, Mockito.times(1)).close();
137 Mockito.verify(outStream, Mockito.times(1)).write(
138 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
139 }
140
141 @Test
142 public void testConnectionShutdown() throws Exception {
143 final InputStream inStream = Mockito.mock(InputStream.class);
144 final OutputStream outStream = Mockito.mock(OutputStream.class);
145 Mockito.when(socket.getInputStream()).thenReturn(inStream);
146 Mockito.when(socket.getOutputStream()).thenReturn(outStream);
147
148 conn.bind(socket);
149 conn.ensureOpen();
150 conn.getSessionOutputBuffer().write(0);
151
152 Assert.assertTrue(conn.isOpen());
153
154 conn.shutdown();
155
156 Assert.assertFalse(conn.isOpen());
157
158 Mockito.verify(outStream, Mockito.never()).write(
159 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
160 Mockito.verify(socket, Mockito.never()).shutdownInput();
161 Mockito.verify(socket, Mockito.never()).shutdownOutput();
162 Mockito.verify(socket, Mockito.times(1)).close();
163
164 conn.close();
165 Mockito.verify(socket, Mockito.times(1)).close();
166
167 conn.shutdown();
168 Mockito.verify(socket, Mockito.times(1)).close();
169 }
170
171 @Test
172 public void testPrepareInputLengthDelimited() throws Exception {
173 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
174 message.addHeader("Content-Length", "10");
175 message.addHeader("Content-Type", "stuff");
176 message.addHeader("Content-Encoding", "identity");
177 final HttpEntity entity = conn.prepareInput(message);
178 Assert.assertNotNull(entity);
179 Assert.assertFalse(entity.isChunked());
180 Assert.assertEquals(10, entity.getContentLength());
181 final Header ct = entity.getContentType();
182 Assert.assertNotNull(ct);
183 Assert.assertEquals("stuff", ct.getValue());
184 final Header ce = entity.getContentEncoding();
185 Assert.assertNotNull(ce);
186 Assert.assertEquals("identity", ce.getValue());
187 final InputStream inStream = entity.getContent();
188 Assert.assertNotNull(inStream);
189 Assert.assertTrue((inStream instanceof ContentLengthInputStream));
190 }
191
192 @Test
193 public void testPrepareInputChunked() throws Exception {
194 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
195 message.addHeader("Transfer-Encoding", "chunked");
196 final HttpEntity entity = conn.prepareInput(message);
197 Assert.assertNotNull(entity);
198 Assert.assertTrue(entity.isChunked());
199 Assert.assertEquals(-1, entity.getContentLength());
200 final InputStream inStream = entity.getContent();
201 Assert.assertNotNull(inStream);
202 Assert.assertTrue((inStream instanceof ChunkedInputStream));
203 }
204
205 @Test
206 public void testPrepareInputIdentity() throws Exception {
207 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
208 final HttpEntity entity = conn.prepareInput(message);
209 Assert.assertNotNull(entity);
210 Assert.assertFalse(entity.isChunked());
211 Assert.assertEquals(-1, entity.getContentLength());
212 final InputStream inStream = entity.getContent();
213 Assert.assertNotNull(inStream);
214 Assert.assertTrue((inStream instanceof IdentityInputStream));
215 }
216
217 @Test
218 public void testPrepareOutputLengthDelimited() throws Exception {
219 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
220 message.addHeader("Content-Length", "10");
221 final OutputStream outStream = conn.prepareOutput(message);
222 Assert.assertNotNull(outStream);
223 Assert.assertTrue((outStream instanceof ContentLengthOutputStream));
224 }
225
226 @Test
227 public void testPrepareOutputChunked() throws Exception {
228 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
229 message.addHeader("Transfer-Encoding", "chunked");
230 final OutputStream outStream = conn.prepareOutput(message);
231 Assert.assertNotNull(outStream);
232 Assert.assertTrue((outStream instanceof ChunkedOutputStream));
233 }
234
235 @Test
236 public void testPrepareOutputIdentity() throws Exception {
237 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
238 final OutputStream outStream = conn.prepareOutput(message);
239 Assert.assertNotNull(outStream);
240 Assert.assertTrue((outStream instanceof IdentityOutputStream));
241 }
242
243 @Test
244 public void testSetSocketTimeout() throws Exception {
245 conn.bind(socket);
246
247 conn.setSocketTimeout(123);
248
249 Mockito.verify(socket, Mockito.times(1)).setSoTimeout(123);
250 }
251
252 @Test
253 public void testSetSocketTimeoutException() throws Exception {
254 conn.bind(socket);
255
256 Mockito.doThrow(new SocketException()).when(socket).setSoTimeout(Matchers.anyInt());
257
258 conn.setSocketTimeout(123);
259
260 Mockito.verify(socket, Mockito.times(1)).setSoTimeout(123);
261 }
262
263 @Test
264 public void testGetSocketTimeout() throws Exception {
265 Assert.assertEquals(-1, conn.getSocketTimeout());
266
267 Mockito.when(socket.getSoTimeout()).thenReturn(345);
268 conn.bind(socket);
269
270 Assert.assertEquals(345, conn.getSocketTimeout());
271 }
272
273 @Test
274 public void testGetSocketTimeoutException() throws Exception {
275 Assert.assertEquals(-1, conn.getSocketTimeout());
276
277 Mockito.when(socket.getSoTimeout()).thenThrow(new SocketException());
278 conn.bind(socket);
279
280 Assert.assertEquals(-1, conn.getSocketTimeout());
281 }
282
283 @Test
284 public void testAwaitInputInBuffer() throws Exception {
285 final ByteArrayInputStream inStream = Mockito.spy(new ByteArrayInputStream(
286 new byte[] {1, 2, 3, 4, 5}));
287 Mockito.when(socket.getInputStream()).thenReturn(inStream);
288
289 conn.bind(socket);
290 conn.ensureOpen();
291 conn.getSessionInputBuffer().read();
292
293 Assert.assertTrue(conn.awaitInput(432));
294
295 Mockito.verify(socket, Mockito.never()).setSoTimeout(Matchers.anyInt());
296 Mockito.verify(inStream, Mockito.times(1)).read(
297 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
298 }
299
300 @Test
301 public void testAwaitInputInSocket() throws Exception {
302 final ByteArrayInputStream inStream = Mockito.spy(new ByteArrayInputStream(
303 new byte[] {1, 2, 3, 4, 5}));
304 Mockito.when(socket.getInputStream()).thenReturn(inStream);
305 Mockito.when(socket.getSoTimeout()).thenReturn(345);
306
307 conn.bind(socket);
308 conn.ensureOpen();
309
310 Assert.assertTrue(conn.awaitInput(432));
311
312 Mockito.verify(socket, Mockito.times(1)).setSoTimeout(432);
313 Mockito.verify(socket, Mockito.times(1)).setSoTimeout(345);
314 Mockito.verify(inStream, Mockito.times(1)).read(
315 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
316 }
317
318 @Test
319 public void testAwaitInputNoData() throws Exception {
320 final InputStream inStream = Mockito.mock(InputStream.class);
321 Mockito.when(socket.getInputStream()).thenReturn(inStream);
322 Mockito.when(inStream.read(Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt()))
323 .thenReturn(-1);
324
325 conn.bind(socket);
326 conn.ensureOpen();
327
328 Assert.assertFalse(conn.awaitInput(432));
329 }
330
331 @Test
332 public void testStaleWhenClosed() throws Exception {
333 conn.bind(socket);
334 conn.ensureOpen();
335 conn.close();
336 Assert.assertTrue(conn.isStale());
337 }
338
339 @Test
340 public void testNotStaleWhenHasData() throws Exception {
341 final ByteArrayInputStream inStream = Mockito.spy(new ByteArrayInputStream(
342 new byte[] {1, 2, 3, 4, 5}));
343 Mockito.when(socket.getInputStream()).thenReturn(inStream);
344
345 conn.bind(socket);
346 conn.ensureOpen();
347
348 Assert.assertFalse(conn.isStale());
349 }
350
351 @Test
352 public void testStaleWhenEndOfStream() throws Exception {
353 final InputStream inStream = Mockito.mock(InputStream.class);
354 Mockito.when(socket.getInputStream()).thenReturn(inStream);
355 Mockito.when(inStream.read(Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt()))
356 .thenReturn(-1);
357
358 conn.bind(socket);
359 conn.ensureOpen();
360
361 Assert.assertTrue(conn.isStale());
362 }
363
364 @Test
365 public void testNotStaleWhenTimeout() throws Exception {
366 final InputStream inStream = Mockito.mock(InputStream.class);
367 Mockito.when(socket.getInputStream()).thenReturn(inStream);
368 Mockito.when(inStream.read(Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt()))
369 .thenThrow(new SocketTimeoutException());
370
371 conn.bind(socket);
372 conn.ensureOpen();
373
374 Assert.assertFalse(conn.isStale());
375 }
376
377 @Test
378 public void testStaleWhenIOError() throws Exception {
379 final InputStream inStream = Mockito.mock(InputStream.class);
380 Mockito.when(socket.getInputStream()).thenReturn(inStream);
381 Mockito.when(inStream.read(Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt()))
382 .thenThrow(new SocketException());
383
384 conn.bind(socket);
385 conn.ensureOpen();
386
387 Assert.assertTrue(conn.isStale());
388 }
389
390 }