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
28 package org.apache.http.nio.integration;
29
30 import java.io.BufferedReader;
31 import java.io.BufferedWriter;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.InputStreamReader;
35 import java.io.OutputStream;
36 import java.io.OutputStreamWriter;
37 import java.net.InetSocketAddress;
38 import java.net.Socket;
39
40 import org.apache.http.HttpEntity;
41 import org.apache.http.HttpEntityEnclosingRequest;
42 import org.apache.http.HttpException;
43 import org.apache.http.HttpRequest;
44 import org.apache.http.HttpResponse;
45 import org.apache.http.entity.ContentType;
46 import org.apache.http.nio.entity.NByteArrayEntity;
47 import org.apache.http.nio.entity.NStringEntity;
48 import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
49 import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
50 import org.apache.http.nio.reactor.ListenerEndpoint;
51 import org.apache.http.nio.testserver.HttpCoreNIOTestBase;
52 import org.apache.http.protocol.HTTP;
53 import org.apache.http.protocol.HttpContext;
54 import org.apache.http.protocol.HttpRequestHandler;
55 import org.apache.http.protocol.ImmutableHttpProcessor;
56 import org.apache.http.protocol.ResponseConnControl;
57 import org.apache.http.protocol.ResponseContent;
58 import org.apache.http.protocol.ResponseServer;
59 import org.apache.http.util.EntityUtils;
60 import org.junit.After;
61 import org.junit.Assert;
62 import org.junit.Before;
63 import org.junit.Test;
64
65
66
67
68 public class TestServerSidePipelining extends HttpCoreNIOTestBase {
69
70 @Before
71 public void setUp() throws Exception {
72 initServer();
73 this.server.setHttpProcessor(new ImmutableHttpProcessor(
74 new ResponseServer("TEST-SERVER/1.1"), new ResponseContent(), new ResponseConnControl()));
75 final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
76 this.server.registerHandler("*", new BasicAsyncRequestHandler(new HttpRequestHandler() {
77
78 @Override
79 public void handle(
80 final HttpRequest request,
81 final HttpResponse response,
82 final HttpContext context) throws HttpException, IOException {
83 final String content = "thank you very much";
84 final NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
85 response.setEntity(entity);
86 }
87
88 }));
89 this.server.registerHandler("/goodbye", new BasicAsyncRequestHandler(new HttpRequestHandler() {
90
91 @Override
92 public void handle(
93 final HttpRequest request,
94 final HttpResponse response,
95 final HttpContext context) throws HttpException, IOException {
96 final String content = "and goodbye";
97 final NStringEntity entity = new NStringEntity(content, ContentType.DEFAULT_TEXT);
98 response.setEntity(entity);
99 response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
100 }
101
102 }));
103 this.server.registerHandler("/echo", new BasicAsyncRequestHandler(new HttpRequestHandler() {
104
105 @Override
106 public void handle(
107 final HttpRequest request,
108 final HttpResponse response,
109 final HttpContext context) throws HttpException, IOException {
110 final HttpEntity responseEntity;
111 if (request instanceof HttpEntityEnclosingRequest) {
112 final HttpEntity requestEntity = ((HttpEntityEnclosingRequest) request).getEntity();
113 final ContentType contentType = ContentType.getOrDefault(requestEntity);
114 responseEntity = new NByteArrayEntity(
115 EntityUtils.toByteArray(requestEntity), contentType);
116 } else {
117 responseEntity = new NStringEntity("Say what?", ContentType.DEFAULT_TEXT);
118 }
119 response.setEntity(responseEntity);
120 }
121
122 }));
123 }
124
125 @After
126 public void tearDown() throws Exception {
127 shutDownServer();
128 }
129
130 @Test
131 public void testGetRequestPipelining() throws Exception {
132 this.server.start();
133
134 final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
135 endpoint.waitFor();
136
137 final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
138 final Socket socket = new Socket("localhost", address.getPort());
139 try {
140 final OutputStream outStream = socket.getOutputStream();
141 final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outStream, "US-ASCII"));
142 writer.write("GET / HTTP/1.1\r\n");
143 writer.write("Host: localhost\r\n");
144 writer.write("\r\n");
145 writer.write("GET / HTTP/1.1\r\n");
146 writer.write("Host: localhost\r\n");
147 writer.write("\r\n");
148 writer.write("GET / HTTP/1.1\r\n");
149 writer.write("Host: localhost\r\n");
150 writer.write("\r\n");
151 writer.write("GET / HTTP/1.1\r\n");
152 writer.write("Host: localhost\r\n");
153 writer.write("Connection: close\r\n");
154 writer.write("\r\n");
155 writer.flush();
156 final InputStream inStream = socket.getInputStream();
157 final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, "US-ASCII"));
158 final StringBuilder buf = new StringBuilder();
159 final char[] tmp = new char[1024];
160 int l;
161 while ((l = reader.read(tmp)) != -1) {
162 buf.append(tmp, 0, l);
163 }
164 reader.close();
165 writer.close();
166 final String expected =
167 "HTTP/1.1 200 OK\r\n" +
168 "Server: TEST-SERVER/1.1\r\n" +
169 "Content-Length: 19\r\n" +
170 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
171 "\r\n" +
172 "thank you very much" +
173 "HTTP/1.1 200 OK\r\n" +
174 "Server: TEST-SERVER/1.1\r\n" +
175 "Content-Length: 19\r\n" +
176 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
177 "\r\n" +
178 "thank you very much" +
179 "HTTP/1.1 200 OK\r\n" +
180 "Server: TEST-SERVER/1.1\r\n" +
181 "Content-Length: 19\r\n" +
182 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
183 "\r\n" +
184 "thank you very much" +
185 "HTTP/1.1 200 OK\r\n" +
186 "Server: TEST-SERVER/1.1\r\n" +
187 "Content-Length: 19\r\n" +
188 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
189 "Connection: close\r\n" +
190 "\r\n" +
191 "thank you very much";
192 Assert.assertEquals(expected, buf.toString());
193
194 } finally {
195 socket.close();
196 }
197
198 }
199
200 @Test
201 public void testPostRequestPipelining() throws Exception {
202 this.server.start();
203
204 final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
205 endpoint.waitFor();
206
207 final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
208 final Socket socket = new Socket("localhost", address.getPort());
209 try {
210 final OutputStream outStream = socket.getOutputStream();
211 final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outStream, "US-ASCII"));
212 writer.write("POST /echo HTTP/1.1\r\n");
213 writer.write("Host: localhost\r\n");
214 writer.write("Content-Length: 16\r\n");
215 writer.write("Content-Type: text/plain; charset=ISO-8859-1\r\n");
216 writer.write("\r\n");
217 writer.write("blah blah blah\r\n");
218 writer.write("POST /echo HTTP/1.1\r\n");
219 writer.write("Host: localhost\r\n");
220 writer.write("Transfer-Encoding: chunked\r\n");
221 writer.write("Content-Type: text/plain; charset=ISO-8859-1\r\n");
222 writer.write("\r\n");
223 writer.write("10\r\n");
224 writer.write("yada yada yada\r\n");
225 writer.write("\r\n");
226 writer.write("0\r\n");
227 writer.write("\r\n");
228 writer.write("GET / HTTP/1.1\r\n");
229 writer.write("Host: localhost\r\n");
230 writer.write("\r\n");
231 writer.write("GET /goodbye HTTP/1.1\r\n");
232 writer.write("Host: localhost\r\n");
233 writer.write("\r\n");
234 writer.flush();
235 final InputStream inStream = socket.getInputStream();
236 final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, "US-ASCII"));
237 final StringBuilder buf = new StringBuilder();
238 final char[] tmp = new char[1024];
239 int l;
240 while ((l = reader.read(tmp)) != -1) {
241 buf.append(tmp, 0, l);
242 }
243 reader.close();
244 writer.close();
245 final String expected =
246 "HTTP/1.1 200 OK\r\n" +
247 "Server: TEST-SERVER/1.1\r\n" +
248 "Content-Length: 16\r\n" +
249 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
250 "\r\n" +
251 "blah blah blah\r\n" +
252 "HTTP/1.1 200 OK\r\n" +
253 "Server: TEST-SERVER/1.1\r\n" +
254 "Content-Length: 16\r\n" +
255 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
256 "\r\n" +
257 "yada yada yada\r\n" +
258 "HTTP/1.1 200 OK\r\n" +
259 "Server: TEST-SERVER/1.1\r\n" +
260 "Content-Length: 19\r\n" +
261 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
262 "\r\n" +
263 "thank you very much" +
264 "HTTP/1.1 200 OK\r\n" +
265 "Connection: Close\r\n" +
266 "Server: TEST-SERVER/1.1\r\n" +
267 "Content-Length: 11\r\n" +
268 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
269 "\r\n" +
270 "and goodbye";
271 Assert.assertEquals(expected, buf.toString());
272
273 } finally {
274 socket.close();
275 }
276
277 }
278
279 @Test
280 public void testPostRequestPipeliningExpectContinue() throws Exception {
281 this.server.start();
282
283 final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
284 endpoint.waitFor();
285
286 final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
287 final Socket socket = new Socket("localhost", address.getPort());
288 try {
289 final OutputStream outStream = socket.getOutputStream();
290 final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outStream, "US-ASCII"));
291 writer.write("POST /echo HTTP/1.1\r\n");
292 writer.write("Host: localhost\r\n");
293 writer.write("Expect: 100-Continue\r\n");
294 writer.write("Content-Length: 16\r\n");
295 writer.write("Content-Type: text/plain; charset=ISO-8859-1\r\n");
296 writer.write("\r\n");
297 writer.write("blah blah blah\r\n");
298 writer.write("POST /echo HTTP/1.1\r\n");
299 writer.write("Host: localhost\r\n");
300 writer.write("Expect: 100-Continue\r\n");
301 writer.write("Content-Length: 16\r\n");
302 writer.write("Content-Type: text/plain; charset=ISO-8859-1\r\n");
303 writer.write("\r\n");
304 writer.write("yada yada yada\r\n");
305 writer.write("POST /echo HTTP/1.1\r\n");
306 writer.write("Host: localhost\r\n");
307 writer.write("Expect: 100-Continue\r\n");
308 writer.write("Content-Length: 16\r\n");
309 writer.write("Content-Type: text/plain; charset=ISO-8859-1\r\n");
310 writer.write("Connection: close\r\n");
311 writer.write("\r\n");
312 writer.write("booo booo booo\r\n");
313 writer.flush();
314 final InputStream inStream = socket.getInputStream();
315 final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, "US-ASCII"));
316 final StringBuilder buf = new StringBuilder();
317 final char[] tmp = new char[1024];
318 int l;
319 while ((l = reader.read(tmp)) != -1) {
320 buf.append(tmp, 0, l);
321 }
322 reader.close();
323 writer.close();
324 final String expected = "HTTP/1.1 200 OK\r\n" +
325 "Server: TEST-SERVER/1.1\r\n" +
326 "Content-Length: 16\r\n" +
327 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
328 "\r\n" +
329 "blah blah blah\r\n" +
330 "HTTP/1.1 200 OK\r\n" +
331 "Server: TEST-SERVER/1.1\r\n" +
332 "Content-Length: 16\r\n" +
333 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
334 "\r\n" +
335 "yada yada yada\r\n" +
336 "HTTP/1.1 200 OK\r\n" +
337 "Server: TEST-SERVER/1.1\r\n" +
338 "Content-Length: 16\r\n" +
339 "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
340 "Connection: close\r\n" +
341 "\r\n" +
342 "booo booo booo\r\n";
343 Assert.assertEquals(expected, buf.toString());
344
345 } finally {
346 socket.close();
347 }
348 }
349
350 }