1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.http;
21
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertNotEquals;
24 import static org.junit.Assert.assertTrue;
25
26 import java.nio.charset.CharacterCodingException;
27 import java.nio.charset.Charset;
28 import java.nio.charset.CharsetEncoder;
29
30 import org.apache.mina.core.buffer.IoBuffer;
31 import org.apache.mina.core.filterchain.IoFilter.NextFilter;
32 import org.apache.mina.core.session.DummySession;
33 import org.apache.mina.core.session.IoSession;
34 import org.apache.mina.filter.codec.AbstractProtocolDecoderOutput;
35 import org.apache.mina.filter.codec.ProtocolDecoder;
36 import org.apache.mina.http.api.HttpEndOfContent;
37 import org.apache.mina.http.api.HttpRequest;
38 import org.junit.Test;
39
40 public class HttpServerDecoderTest {
41 private static final CharsetEncoder encoder = Charset.forName("US-ASCII").newEncoder();
42
43 private static final ProtocolDecoder decoder = new HttpServerDecoder();
44
45 private static final String DECODER_STATE_ATT = "http.ds";
46
47
48
49
50 private static IoSession session = new DummySession();
51
52
53
54
55
56
57
58
59
60 protected static IoBuffer getRequestBuffer(String method, String body) throws CharacterCodingException {
61 IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
62 buffer.putString(method + " / HTTP/1.1\r\nHost: dummy\r\n", encoder);
63
64 if (body != null) {
65 buffer.putString("Content-Length: " + body.length() + "\r\n\r\n", encoder);
66 buffer.putString(body, encoder);
67 } else {
68 buffer.putString("\r\n", encoder);
69 }
70
71 buffer.rewind();
72
73 return buffer;
74 }
75
76 protected static IoBuffer getRequestBuffer(String method) throws CharacterCodingException {
77 return getRequestBuffer(method, null);
78 }
79
80
81
82
83
84
85
86
87
88 protected static AbstractProtocolDecoderOutput executeRequest(String method, String body) throws Exception {
89 AbstractProtocolDecoderOutput out = new AbstractProtocolDecoderOutput() {
90 public void flush(NextFilter nextFilter, IoSession session) {
91 }
92 };
93
94 IoBuffer buffer = getRequestBuffer(method, body);
95
96 while (buffer.hasRemaining()) {
97 decoder.decode(session, buffer, out);
98 }
99
100 return out;
101 }
102
103 @Test
104 public void testGetRequestWithoutBody() throws Exception {
105 AbstractProtocolDecoderOutput out = executeRequest("GET", null);
106 assertEquals(2, out.getMessageQueue().size());
107 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
108 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
109 }
110
111 @Test
112 public void testGetRequestBody() throws Exception {
113 AbstractProtocolDecoderOutput out = executeRequest("GET", "body");
114 assertEquals(3, out.getMessageQueue().size());
115 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
116 assertTrue(out.getMessageQueue().poll() instanceof IoBuffer);
117 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
118 }
119
120 @Test
121 public void testPutRequestWithoutBody() throws Exception {
122 AbstractProtocolDecoderOutput out = executeRequest("PUT", null);
123 assertEquals(2, out.getMessageQueue().size());
124 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
125 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
126 }
127
128 @Test
129 public void testPutRequestBody() throws Exception {
130 AbstractProtocolDecoderOutput out = executeRequest("PUT", "body");
131 assertEquals(3, out.getMessageQueue().size());
132 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
133 assertTrue(out.getMessageQueue().poll() instanceof IoBuffer);
134 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
135 }
136
137 @Test
138 public void testPostRequestWithoutBody() throws Exception {
139 AbstractProtocolDecoderOutput out = executeRequest("POST", null);
140 assertEquals(2, out.getMessageQueue().size());
141 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
142 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
143 }
144
145 @Test
146 public void testPostRequestBody() throws Exception {
147 AbstractProtocolDecoderOutput out = executeRequest("POST", "body");
148 assertEquals(3, out.getMessageQueue().size());
149 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
150 assertTrue(out.getMessageQueue().poll() instanceof IoBuffer);
151 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
152 }
153
154 @Test
155 public void testDeleteRequestWithoutBody() throws Exception {
156 AbstractProtocolDecoderOutput out = executeRequest("DELETE", null);
157 assertEquals(2, out.getMessageQueue().size());
158 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
159 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
160 }
161
162 @Test
163 public void testDeleteRequestBody() throws Exception {
164 AbstractProtocolDecoderOutput out = executeRequest("DELETE", "body");
165 assertEquals(3, out.getMessageQueue().size());
166 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
167 assertTrue(out.getMessageQueue().poll() instanceof IoBuffer);
168 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
169 }
170
171 @Test
172 public void testDIRMINA965NoContent() throws Exception {
173 AbstractProtocolDecoderOutput out = new AbstractProtocolDecoderOutput() {
174 public void flush(NextFilter nextFilter, IoSession session) {
175 }
176 };
177 IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
178 buffer.putString("GET / HTTP/1.1\r\nHost: ", encoder);
179 buffer.rewind();
180 while (buffer.hasRemaining()) {
181 decoder.decode(session, buffer, out);
182 }
183 buffer = IoBuffer.allocate(0).setAutoExpand(true);
184 buffer.putString("dummy\r\n\r\n", encoder);
185 buffer.rewind();
186 while (buffer.hasRemaining()) {
187 decoder.decode(session, buffer, out);
188 }
189 assertEquals(2, out.getMessageQueue().size());
190 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
191 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
192 }
193
194 @Test
195 public void testDIRMINA965WithContent() throws Exception {
196 AbstractProtocolDecoderOutput out = new AbstractProtocolDecoderOutput() {
197 public void flush(NextFilter nextFilter, IoSession session) {
198 }
199 };
200 IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
201 buffer.putString("GET / HTTP/1.1\r\nHost: ", encoder);
202 buffer.rewind();
203 while (buffer.hasRemaining()) {
204 decoder.decode(session, buffer, out);
205 }
206 buffer = IoBuffer.allocate(0).setAutoExpand(true);
207 buffer.putString("dummy\r\nContent-Length: 1\r\n\r\nA", encoder);
208 buffer.rewind();
209 while (buffer.hasRemaining()) {
210 decoder.decode(session, buffer, out);
211 }
212 assertEquals(3, out.getMessageQueue().size());
213 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
214 assertTrue(out.getMessageQueue().poll() instanceof IoBuffer);
215 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
216 }
217 @Test
218 public void testDIRMINA965WithContentOnTwoChunks() throws Exception {
219 AbstractProtocolDecoderOutput out = new AbstractProtocolDecoderOutput() {
220 public void flush(NextFilter nextFilter, IoSession session) {
221 }
222 };
223 IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
224 buffer.putString("GET / HTTP/1.1\r\nHost: ", encoder);
225 buffer.rewind();
226 while (buffer.hasRemaining()) {
227 decoder.decode(session, buffer, out);
228 }
229 buffer = IoBuffer.allocate(0).setAutoExpand(true);
230 buffer.putString("dummy\r\nContent-Length: 2\r\n\r\nA", encoder);
231 buffer.rewind();
232 while (buffer.hasRemaining()) {
233 decoder.decode(session, buffer, out);
234 }
235 buffer = IoBuffer.allocate(0).setAutoExpand(true);
236 buffer.putString("B", encoder);
237 buffer.rewind();
238 while (buffer.hasRemaining()) {
239 decoder.decode(session, buffer, out);
240 }
241 assertEquals(4, out.getMessageQueue().size());
242 assertTrue(out.getMessageQueue().poll() instanceof HttpRequest);
243 assertTrue(out.getMessageQueue().poll() instanceof IoBuffer);
244 assertTrue(out.getMessageQueue().poll() instanceof IoBuffer);
245 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
246 }
247
248 @Test
249 public void verifyThatHeaderWithoutLeadingSpaceIsSupported() throws Exception {
250 AbstractProtocolDecoderOutput out = new AbstractProtocolDecoderOutput() {
251 public void flush(NextFilter nextFilter, IoSession session) {
252 }
253 };
254 IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
255 buffer.putString("GET / HTTP/1.0\r\nHost:localhost\r\n\r\n", encoder);
256 buffer.rewind();
257 while (buffer.hasRemaining()) {
258 decoder.decode(session, buffer, out);
259 }
260 assertEquals(2, out.getMessageQueue().size());
261 HttpRequest request = (HttpRequest) out.getMessageQueue().poll();
262 assertEquals("localhost", request.getHeader("host"));
263 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
264 }
265
266 @Test
267 public void verifyThatLeadingSpacesAreRemovedFromHeader() throws Exception {
268 AbstractProtocolDecoderOutput out = new AbstractProtocolDecoderOutput() {
269 public void flush(NextFilter nextFilter, IoSession session) {
270 }
271 };
272 IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
273 buffer.putString("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n", encoder);
274 buffer.rewind();
275 while (buffer.hasRemaining()) {
276 decoder.decode(session, buffer, out);
277 }
278 assertEquals(2, out.getMessageQueue().size());
279 HttpRequest request = (HttpRequest) out.getMessageQueue().poll();
280 assertEquals("localhost", request.getHeader("host"));
281 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
282 }
283
284 @Test
285 public void verifyThatTrailingSpacesAreRemovedFromHeader() throws Exception {
286 AbstractProtocolDecoderOutput out = new AbstractProtocolDecoderOutput() {
287 public void flush(NextFilter nextFilter, IoSession session) {
288 }
289 };
290 IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
291 buffer.putString("GET / HTTP/1.0\r\nHost:localhost \r\n\r\n", encoder);
292 buffer.rewind();
293 while (buffer.hasRemaining()) {
294 decoder.decode(session, buffer, out);
295 }
296 assertEquals(2, out.getMessageQueue().size());
297 HttpRequest request = (HttpRequest) out.getMessageQueue().poll();
298 assertEquals("localhost", request.getHeader("host"));
299 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
300 }
301
302 @Test
303 public void dosOnRequestWithAdditionalData() throws Exception {
304 AbstractProtocolDecoderOutput out = new AbstractProtocolDecoderOutput() {
305 public void flush(NextFilter nextFilter, IoSession session) {
306 }
307 };
308 IoBuffer buffer = IoBuffer.allocate(0).setAutoExpand(true);
309 buffer.putString("GET / HTTP/1.0\r\nHost:localhost \r\n\r\ndummy", encoder);
310 buffer.rewind();
311 int prevBufferPosition = buffer.position();
312 while (buffer.hasRemaining()) {
313 decoder.decode(session, buffer, out);
314 assertNotEquals("Buffer at new position", prevBufferPosition, buffer.position());
315 prevBufferPosition = buffer.position();
316 }
317 assertEquals(2, out.getMessageQueue().size());
318 HttpRequest request = (HttpRequest) out.getMessageQueue().poll();
319 assertEquals("localhost", request.getHeader("host"));
320 assertTrue(out.getMessageQueue().poll() instanceof HttpEndOfContent);
321 session.removeAttribute(DECODER_STATE_ATT);
322 }
323 }