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)).close();
132
133 conn.close();
134 Mockito.verify(socket, Mockito.times(1)).close();
135 Mockito.verify(outStream, Mockito.times(1)).write(
136 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
137 }
138
139 @Test
140 public void testConnectionShutdown() throws Exception {
141 final InputStream inStream = Mockito.mock(InputStream.class);
142 final OutputStream outStream = Mockito.mock(OutputStream.class);
143 Mockito.when(socket.getInputStream()).thenReturn(inStream);
144 Mockito.when(socket.getOutputStream()).thenReturn(outStream);
145
146 conn.bind(socket);
147 conn.ensureOpen();
148 conn.getSessionOutputBuffer().write(0);
149
150 Assert.assertTrue(conn.isOpen());
151
152 conn.shutdown();
153
154 Assert.assertFalse(conn.isOpen());
155
156 Mockito.verify(outStream, Mockito.never()).write(
157 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
158 Mockito.verify(socket, Mockito.never()).shutdownInput();
159 Mockito.verify(socket, Mockito.never()).shutdownOutput();
160 Mockito.verify(socket, Mockito.times(1)).close();
161
162 conn.close();
163 Mockito.verify(socket, Mockito.times(1)).close();
164
165 conn.shutdown();
166 Mockito.verify(socket, Mockito.times(1)).close();
167 }
168
169 @Test
170 public void testPrepareInputLengthDelimited() throws Exception {
171 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
172 message.addHeader("Content-Length", "10");
173 message.addHeader("Content-Type", "stuff");
174 message.addHeader("Content-Encoding", "identity");
175 final HttpEntity entity = conn.prepareInput(message);
176 Assert.assertNotNull(entity);
177 Assert.assertFalse(entity.isChunked());
178 Assert.assertEquals(10, entity.getContentLength());
179 final Header ct = entity.getContentType();
180 Assert.assertNotNull(ct);
181 Assert.assertEquals("stuff", ct.getValue());
182 final Header ce = entity.getContentEncoding();
183 Assert.assertNotNull(ce);
184 Assert.assertEquals("identity", ce.getValue());
185 final InputStream inStream = entity.getContent();
186 Assert.assertNotNull(inStream);
187 Assert.assertTrue((inStream instanceof ContentLengthInputStream));
188 }
189
190 @Test
191 public void testPrepareInputChunked() throws Exception {
192 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
193 message.addHeader("Transfer-Encoding", "chunked");
194 final HttpEntity entity = conn.prepareInput(message);
195 Assert.assertNotNull(entity);
196 Assert.assertTrue(entity.isChunked());
197 Assert.assertEquals(-1, entity.getContentLength());
198 final InputStream inStream = entity.getContent();
199 Assert.assertNotNull(inStream);
200 Assert.assertTrue((inStream instanceof ChunkedInputStream));
201 }
202
203 @Test
204 public void testPrepareInputIdentity() throws Exception {
205 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
206 final HttpEntity entity = conn.prepareInput(message);
207 Assert.assertNotNull(entity);
208 Assert.assertFalse(entity.isChunked());
209 Assert.assertEquals(-1, entity.getContentLength());
210 final InputStream inStream = entity.getContent();
211 Assert.assertNotNull(inStream);
212 Assert.assertTrue((inStream instanceof IdentityInputStream));
213 }
214
215 @Test
216 public void testPrepareOutputLengthDelimited() throws Exception {
217 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
218 message.addHeader("Content-Length", "10");
219 final OutputStream outStream = conn.prepareOutput(message);
220 Assert.assertNotNull(outStream);
221 Assert.assertTrue((outStream instanceof ContentLengthOutputStream));
222 }
223
224 @Test
225 public void testPrepareOutputChunked() throws Exception {
226 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
227 message.addHeader("Transfer-Encoding", "chunked");
228 final OutputStream outStream = conn.prepareOutput(message);
229 Assert.assertNotNull(outStream);
230 Assert.assertTrue((outStream instanceof ChunkedOutputStream));
231 }
232
233 @Test
234 public void testPrepareOutputIdentity() throws Exception {
235 final HttpResponse message = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
236 final OutputStream outStream = conn.prepareOutput(message);
237 Assert.assertNotNull(outStream);
238 Assert.assertTrue((outStream instanceof IdentityOutputStream));
239 }
240
241 @Test
242 public void testSetSocketTimeout() throws Exception {
243 conn.bind(socket);
244
245 conn.setSocketTimeout(123);
246
247 Mockito.verify(socket, Mockito.times(1)).setSoTimeout(123);
248 }
249
250 @Test
251 public void testSetSocketTimeoutException() throws Exception {
252 conn.bind(socket);
253
254 Mockito.doThrow(new SocketException()).when(socket).setSoTimeout(Matchers.anyInt());
255
256 conn.setSocketTimeout(123);
257
258 Mockito.verify(socket, Mockito.times(1)).setSoTimeout(123);
259 }
260
261 @Test
262 public void testGetSocketTimeout() throws Exception {
263 Assert.assertEquals(-1, conn.getSocketTimeout());
264
265 Mockito.when(socket.getSoTimeout()).thenReturn(345);
266 conn.bind(socket);
267
268 Assert.assertEquals(345, conn.getSocketTimeout());
269 }
270
271 @Test
272 public void testGetSocketTimeoutException() throws Exception {
273 Assert.assertEquals(-1, conn.getSocketTimeout());
274
275 Mockito.when(socket.getSoTimeout()).thenThrow(new SocketException());
276 conn.bind(socket);
277
278 Assert.assertEquals(-1, conn.getSocketTimeout());
279 }
280
281 @Test
282 public void testAwaitInputInBuffer() throws Exception {
283 final ByteArrayInputStream inStream = Mockito.spy(new ByteArrayInputStream(
284 new byte[] {1, 2, 3, 4, 5}));
285 Mockito.when(socket.getInputStream()).thenReturn(inStream);
286
287 conn.bind(socket);
288 conn.ensureOpen();
289 conn.getSessionInputBuffer().read();
290
291 Assert.assertTrue(conn.awaitInput(432));
292
293 Mockito.verify(socket, Mockito.never()).setSoTimeout(Matchers.anyInt());
294 Mockito.verify(inStream, Mockito.times(1)).read(
295 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
296 }
297
298 @Test
299 public void testAwaitInputInSocket() throws Exception {
300 final ByteArrayInputStream inStream = Mockito.spy(new ByteArrayInputStream(
301 new byte[] {1, 2, 3, 4, 5}));
302 Mockito.when(socket.getInputStream()).thenReturn(inStream);
303 Mockito.when(socket.getSoTimeout()).thenReturn(345);
304
305 conn.bind(socket);
306 conn.ensureOpen();
307
308 Assert.assertTrue(conn.awaitInput(432));
309
310 Mockito.verify(socket, Mockito.times(1)).setSoTimeout(432);
311 Mockito.verify(socket, Mockito.times(1)).setSoTimeout(345);
312 Mockito.verify(inStream, Mockito.times(1)).read(
313 Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt());
314 }
315
316 @Test
317 public void testAwaitInputNoData() throws Exception {
318 final InputStream inStream = Mockito.mock(InputStream.class);
319 Mockito.when(socket.getInputStream()).thenReturn(inStream);
320 Mockito.when(inStream.read(Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt()))
321 .thenReturn(-1);
322
323 conn.bind(socket);
324 conn.ensureOpen();
325
326 Assert.assertFalse(conn.awaitInput(432));
327 }
328
329 @Test
330 public void testStaleWhenClosed() throws Exception {
331 conn.bind(socket);
332 conn.ensureOpen();
333 conn.close();
334 Assert.assertTrue(conn.isStale());
335 }
336
337 @Test
338 public void testNotStaleWhenHasData() throws Exception {
339 final ByteArrayInputStream inStream = Mockito.spy(new ByteArrayInputStream(
340 new byte[] {1, 2, 3, 4, 5}));
341 Mockito.when(socket.getInputStream()).thenReturn(inStream);
342
343 conn.bind(socket);
344 conn.ensureOpen();
345
346 Assert.assertFalse(conn.isStale());
347 }
348
349 @Test
350 public void testStaleWhenEndOfStream() throws Exception {
351 final InputStream inStream = Mockito.mock(InputStream.class);
352 Mockito.when(socket.getInputStream()).thenReturn(inStream);
353 Mockito.when(inStream.read(Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt()))
354 .thenReturn(-1);
355
356 conn.bind(socket);
357 conn.ensureOpen();
358
359 Assert.assertTrue(conn.isStale());
360 }
361
362 @Test
363 public void testNotStaleWhenTimeout() throws Exception {
364 final InputStream inStream = Mockito.mock(InputStream.class);
365 Mockito.when(socket.getInputStream()).thenReturn(inStream);
366 Mockito.when(inStream.read(Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt()))
367 .thenThrow(new SocketTimeoutException());
368
369 conn.bind(socket);
370 conn.ensureOpen();
371
372 Assert.assertFalse(conn.isStale());
373 }
374
375 @Test
376 public void testStaleWhenIOError() throws Exception {
377 final InputStream inStream = Mockito.mock(InputStream.class);
378 Mockito.when(socket.getInputStream()).thenReturn(inStream);
379 Mockito.when(inStream.read(Matchers.<byte []>any(), Matchers.anyInt(), Matchers.anyInt()))
380 .thenThrow(new SocketException());
381
382 conn.bind(socket);
383 conn.ensureOpen();
384
385 Assert.assertTrue(conn.isStale());
386 }
387
388 }