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.hc.core5.http.message;
29
30 import org.apache.hc.core5.http.Header;
31 import org.apache.hc.core5.http.HttpVersion;
32 import org.apache.hc.core5.http.Method;
33 import org.apache.hc.core5.http.ParseException;
34 import org.apache.hc.core5.http.ProtocolVersion;
35 import org.apache.hc.core5.util.CharArrayBuffer;
36 import org.junit.jupiter.api.Assertions;
37 import org.junit.jupiter.api.BeforeEach;
38 import org.junit.jupiter.api.Test;
39
40
41
42
43
44 public class TestBasicLineParser {
45
46 private BasicLineParser parser;
47
48 @BeforeEach
49 public void setup() {
50 this.parser = BasicLineParser.INSTANCE;
51 }
52
53 @Test
54 public void testRLParse() throws Exception {
55 final CharArrayBuffer buf = new CharArrayBuffer(64);
56
57 buf.clear();
58 buf.append("GET /stuff HTTP/1.1");
59 RequestLine requestline = this.parser.parseRequestLine(buf);
60 Assertions.assertEquals("GET /stuff HTTP/1.1", requestline.toString());
61 Assertions.assertEquals(Method.GET.name(), requestline.getMethod());
62 Assertions.assertEquals("/stuff", requestline.getUri());
63 Assertions.assertEquals(HttpVersion.HTTP_1_1, requestline.getProtocolVersion());
64
65
66 buf.clear();
67 buf.append(" GET /stuff HTTP/1.1 ");
68 requestline = this.parser.parseRequestLine(buf);
69 Assertions.assertEquals("GET /stuff HTTP/1.1", requestline.toString());
70 Assertions.assertEquals(Method.GET.name(), requestline.getMethod());
71 Assertions.assertEquals("/stuff", requestline.getUri());
72 Assertions.assertEquals(HttpVersion.HTTP_1_1, requestline.getProtocolVersion());
73
74
75 buf.clear();
76 buf.append("\rGET /stuff HTTP/1.1");
77 requestline = this.parser.parseRequestLine(buf);
78 Assertions.assertEquals(Method.GET.name(), requestline.getMethod());
79 Assertions.assertEquals("/stuff", requestline.getUri());
80 Assertions.assertEquals(HttpVersion.HTTP_1_1, requestline.getProtocolVersion());
81 }
82
83 @Test
84 public void testRLParseFailure() throws Exception {
85 final CharArrayBuffer buf = new CharArrayBuffer(64);
86 buf.clear();
87 buf.append(" ");
88 Assertions.assertThrows(ParseException.class, () -> parser.parseRequestLine(buf));
89 buf.clear();
90 buf.append(" GET");
91 Assertions.assertThrows(ParseException.class, () -> parser.parseRequestLine(buf));
92 buf.clear();
93 buf.append("GET /stuff");
94 Assertions.assertThrows(ParseException.class, () -> parser.parseRequestLine(buf));
95 buf.clear();
96 buf.append("GET/stuff HTTP/1.1");
97 Assertions.assertThrows(ParseException.class, () -> parser.parseRequestLine(buf));
98 buf.clear();
99 buf.append("GET /stuff HTTP/1.1 Oooooooooooppsie");
100 Assertions.assertThrows(ParseException.class, () -> parser.parseRequestLine(buf));
101 }
102
103 @Test
104 public void testSLParse() throws Exception {
105 final CharArrayBuffer buf = new CharArrayBuffer(64);
106
107 buf.clear();
108 buf.append("HTTP/1.1 200 OK");
109 StatusLine statusLine = this.parser.parseStatusLine(buf);
110 Assertions.assertEquals("HTTP/1.1 200 OK", statusLine.toString());
111 Assertions.assertEquals(HttpVersion.HTTP_1_1, statusLine.getProtocolVersion());
112 Assertions.assertEquals(200, statusLine.getStatusCode());
113 Assertions.assertEquals("OK", statusLine.getReasonPhrase());
114
115
116 buf.clear();
117 buf.append("HTTP/1.1 404 Not Found");
118 statusLine = this.parser.parseStatusLine(buf);
119 Assertions.assertEquals(404, statusLine.getStatusCode());
120 Assertions.assertEquals("Not Found", statusLine.getReasonPhrase());
121
122
123 buf.clear();
124 buf.append("HTTP/1.1 404 Non Trouve");
125 statusLine = this.parser.parseStatusLine(buf);
126 Assertions.assertEquals("Non Trouve", statusLine.getReasonPhrase());
127
128
129 buf.clear();
130 buf.append("HTTP/1.1 404 Not Found\r\n");
131 statusLine = this.parser.parseStatusLine(buf);
132 Assertions.assertEquals("Not Found", statusLine.getReasonPhrase());
133
134
135 buf.clear();
136 buf.append("HTTP/1.1 200 ");
137 statusLine = this.parser.parseStatusLine(buf);
138 Assertions.assertEquals(200, statusLine.getStatusCode());
139 Assertions.assertEquals("", statusLine.getReasonPhrase());
140
141
142 buf.clear();
143 buf.append("HTTP/1.1 200");
144 statusLine = this.parser.parseStatusLine(buf);
145 Assertions.assertEquals(200, statusLine.getStatusCode());
146 Assertions.assertEquals("", statusLine.getReasonPhrase());
147
148
149 buf.clear();
150 buf.append("HTTP/1.1 200 OK");
151 statusLine = this.parser.parseStatusLine(buf);
152 Assertions.assertEquals(200, statusLine.getStatusCode());
153 Assertions.assertEquals("OK", statusLine.getReasonPhrase());
154
155
156 buf.clear();
157 buf.append("\nHTTP/1.1 200 OK");
158 statusLine = this.parser.parseStatusLine(buf);
159 Assertions.assertEquals(200, statusLine.getStatusCode());
160 Assertions.assertEquals("OK", statusLine.getReasonPhrase());
161 Assertions.assertEquals(HttpVersion.HTTP_1_1, statusLine.getProtocolVersion());
162
163
164 buf.clear();
165 buf.append(" HTTP/1.1 200 OK");
166 statusLine = this.parser.parseStatusLine(buf);
167 Assertions.assertEquals(200, statusLine.getStatusCode());
168 Assertions.assertEquals("OK", statusLine.getReasonPhrase());
169 Assertions.assertEquals(HttpVersion.HTTP_1_1, statusLine.getProtocolVersion());
170 }
171
172 @Test
173 public void testSLParseFailure() throws Exception {
174 final CharArrayBuffer buf = new CharArrayBuffer(64);
175 buf.clear();
176 buf.append("xxx 200 OK");
177 Assertions.assertThrows(ParseException.class, () -> parser.parseStatusLine(buf));
178 buf.clear();
179 buf.append("HTTP/1.1 xxx OK");
180 Assertions.assertThrows(ParseException.class, () -> parser.parseStatusLine(buf));
181 buf.clear();
182 buf.append("HTTP/1.1 ");
183 Assertions.assertThrows(ParseException.class, () -> parser.parseStatusLine(buf));
184 buf.clear();
185 buf.append("HTTP/1.1");
186 Assertions.assertThrows(ParseException.class, () -> parser.parseStatusLine(buf));
187 buf.clear();
188 buf.append("HTTP/1.1 -200 OK");
189 Assertions.assertThrows(ParseException.class, () -> parser.parseStatusLine(buf));
190 buf.clear();
191 buf.append("HTTP/1.1 0200 OK");
192 Assertions.assertThrows(ParseException.class, () -> parser.parseStatusLine(buf));
193 buf.clear();
194 buf.append("HTTP/1.1 2000 OK");
195 Assertions.assertThrows(ParseException.class, () -> parser.parseStatusLine(buf));
196 }
197
198 @Test
199 public void testHttpVersionParsing() throws Exception {
200 final CharArrayBuffer buffer = new CharArrayBuffer(16);
201 buffer.append("HTTP/1.1");
202 final ParserCursor cursor = new ParserCursor(0, buffer.length());
203
204 final ProtocolVersion version = parser.parseProtocolVersion(buffer, cursor);
205 Assertions.assertEquals("HTTP", version.getProtocol(), "HTTP protocol name");
206 Assertions.assertEquals(1, version.getMajor(), "HTTP major version number");
207 Assertions.assertEquals(1, version.getMinor(), "HTTP minor version number");
208 Assertions.assertEquals("HTTP/1.1", version.toString(), "HTTP version number");
209 Assertions.assertEquals(buffer.length(), cursor.getPos());
210 Assertions.assertTrue(cursor.atEnd());
211
212 buffer.clear();
213 buffer.append("HTTP/1.123 123");
214 final ParserCursor cursor2 = new ParserCursor(0, buffer.length());
215
216 final ProtocolVersion version2 = parser.parseProtocolVersion(buffer, cursor2);
217 Assertions.assertEquals( "HTTP", version2.getProtocol(), "HTTP protocol name");
218 Assertions.assertEquals( 1, version2.getMajor(), "HTTP major version number");
219 Assertions.assertEquals(123, version2.getMinor(), "HTTP minor version number");
220 Assertions.assertEquals("HTTP/1.123", version2.toString(), "HTTP version number");
221 Assertions.assertEquals(' ', buffer.charAt(cursor2.getPos()));
222 Assertions.assertEquals(buffer.length() - 4, cursor2.getPos());
223 Assertions.assertFalse(cursor2.atEnd());
224 }
225
226 @Test
227 public void testInvalidHttpVersionParsing() throws Exception {
228 final CharArrayBuffer buffer = new CharArrayBuffer(16);
229 buffer.clear();
230 buffer.append(" ");
231 final ParserCursor cursor1 = new ParserCursor(0, buffer.length());
232 Assertions.assertThrows(ParseException.class, () ->
233 parser.parseProtocolVersion(buffer, cursor1));
234 buffer.clear();
235 buffer.append("HTT");
236 final ParserCursor cursor2 = new ParserCursor(0, buffer.length());
237 Assertions.assertThrows(ParseException.class, () ->
238 parser.parseProtocolVersion(buffer, cursor2));
239 buffer.clear();
240 buffer.append("crap");
241 final ParserCursor cursor3 = new ParserCursor(0, buffer.length());
242 Assertions.assertThrows(ParseException.class, () ->
243 parser.parseProtocolVersion(buffer, cursor3));
244 buffer.clear();
245 buffer.append("HTTP/crap");
246 final ParserCursor cursor4 = new ParserCursor(0, buffer.length());
247 Assertions.assertThrows(ParseException.class, () ->
248 parser.parseProtocolVersion(buffer, cursor4));
249 buffer.clear();
250 buffer.append("HTTP/1");
251 final ParserCursor cursor5 = new ParserCursor(0, buffer.length());
252 Assertions.assertThrows(ParseException.class, () ->
253 parser.parseProtocolVersion(buffer, cursor5));
254 buffer.clear();
255 buffer.append("HTTP/1.");
256 final ParserCursor cursor7 = new ParserCursor(0, buffer.length());
257 Assertions.assertThrows(ParseException.class, () ->
258 parser.parseProtocolVersion(buffer, cursor7));
259 buffer.clear();
260 buffer.append("HTTP/whatever.whatever whatever");
261 final ParserCursor cursor8 = new ParserCursor(0, buffer.length());
262 Assertions.assertThrows(ParseException.class, () ->
263 parser.parseProtocolVersion(buffer, cursor8));
264 buffer.clear();
265 buffer.append("HTTP/1.whatever whatever");
266 final ParserCursor cursor9 = new ParserCursor(0, buffer.length());
267 Assertions.assertThrows(ParseException.class, () ->
268 parser.parseProtocolVersion(buffer, cursor9));
269 }
270
271 @Test
272 public void testHeaderParse() throws Exception {
273 final CharArrayBuffer buf = new CharArrayBuffer(64);
274
275 buf.clear();
276 buf.append("header: blah");
277 Header header = this.parser.parseHeader(buf);
278 Assertions.assertEquals("header", header.getName());
279 Assertions.assertEquals("blah", header.getValue());
280
281
282 buf.clear();
283 buf.append(" header: blah ");
284 header = this.parser.parseHeader(buf);
285 Assertions.assertEquals("header", header.getName());
286 Assertions.assertEquals("blah", header.getValue());
287 }
288
289 @Test
290 public void testInvalidHeaderParsing() throws Exception {
291 final CharArrayBuffer buffer = new CharArrayBuffer(16);
292 buffer.clear();
293 buffer.append("");
294 Assertions.assertThrows(ParseException.class, () -> parser.parseHeader(buffer));
295 buffer.clear();
296 buffer.append("blah");
297 Assertions.assertThrows(ParseException.class, () -> parser.parseHeader(buffer));
298 buffer.clear();
299 buffer.append(":");
300 Assertions.assertThrows(ParseException.class, () -> parser.parseHeader(buffer));
301 buffer.clear();
302 buffer.append(" :");
303 Assertions.assertThrows(ParseException.class, () -> parser.parseHeader(buffer));
304 buffer.clear();
305 buffer.append(": blah");
306 Assertions.assertThrows(ParseException.class, () -> parser.parseHeader(buffer));
307 buffer.clear();
308 buffer.append(" : blah");
309 Assertions.assertThrows(ParseException.class, () -> parser.parseHeader(buffer));
310 buffer.clear();
311 buffer.append("header : blah");
312 Assertions.assertThrows(ParseException.class, () -> parser.parseHeader(buffer));
313 }
314
315 }