~ubuntu-branches/ubuntu/oneiric/squid3/oneiric-security

« back to all changes in this revision

Viewing changes to src/tests/testHttpRequest.cc

  • Committer: Bazaar Package Importer
  • Author(s): Mahyuddin Susanto
  • Date: 2011-02-15 18:46:13 UTC
  • mfrom: (21.2.4 sid)
  • Revision ID: james.westby@ubuntu.com-20110215184613-1u3dh5sz4i055flk
Tags: 3.1.10-1ubuntu1
* Merge from debian unstable. (LP: #719283)  Remaining changes:
  - debian/patches/18-fix-ftbfs-binutils-gold.dpatch: Add library linker into
    LIBS instead to LDFLAGS to fixing FTBFS binutils-gold.
* Drop Ubuntu configuration for ufw which landed in Debian and sync it: 
  - debian/squid3.ufw.profile.

Show diffs side-by-side

added added

removed removed

Lines of Context:
209
209
    input.reset();
210
210
    error = HTTP_STATUS_NONE;
211
211
}
 
212
 
 
213
void
 
214
testHttpRequest::testParseRequestLine()
 
215
{
 
216
    MemBuf input;
 
217
    HttpParser output;
 
218
    input.init();
 
219
 
 
220
    // TEST: Do we comply with RFC 1945 section 5.1 ?
 
221
    // TEST: Do we comply with RFC 2616 section 5.1 ?
 
222
 
 
223
    // RFC 1945 : HTTP/0.9 simple-request
 
224
    input.append("GET /\r\n", 7);
 
225
    HttpParserInit(&output, input.content(), input.contentSize());
 
226
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
227
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
228
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
229
    CPPUNIT_ASSERT(memcmp("GET /\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
230
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
231
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
232
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start], (output.m_end-output.m_start+1)) == 0);
 
233
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
234
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
235
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start], (output.u_end-output.u_start+1)) == 0);
 
236
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
237
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
238
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
239
    CPPUNIT_ASSERT_EQUAL(9, output.v_min);
 
240
    input.reset();
 
241
 
 
242
    // RFC 1945 and 2616 : HTTP/1.0 full-request
 
243
    input.append("GET / HTTP/1.0\r\n", 16);
 
244
    HttpParserInit(&output, input.content(), input.contentSize());
 
245
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
246
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
247
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
248
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.0\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
249
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
250
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
251
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
252
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
253
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
254
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
255
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
256
    CPPUNIT_ASSERT_EQUAL(13, output.v_end);
 
257
    CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
258
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
259
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
260
    input.reset();
 
261
 
 
262
 
 
263
    // RFC 2616 : HTTP/1.1 full-request
 
264
    input.append("GET / HTTP/1.1\r\n", 16);
 
265
    HttpParserInit(&output, input.content(), input.contentSize());
 
266
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
267
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
268
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
269
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
270
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
271
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
272
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
273
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
274
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
275
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
276
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
277
    CPPUNIT_ASSERT_EQUAL(13, output.v_end);
 
278
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
279
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
280
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
281
    input.reset();
 
282
 
 
283
    // RFC 2616 : future version full-request
 
284
    input.append("GET / HTTP/10.12\r\n", 18);
 
285
    //printf("TEST: '%s'\n",input.content());
 
286
    HttpParserInit(&output, input.content(), input.contentSize());
 
287
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
288
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
289
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
290
    CPPUNIT_ASSERT(memcmp("GET / HTTP/10.12\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
291
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
292
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
293
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
294
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
295
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
296
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
297
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
298
    CPPUNIT_ASSERT_EQUAL(15, output.v_end);
 
299
    CPPUNIT_ASSERT(memcmp("HTTP/10.12", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
300
    CPPUNIT_ASSERT_EQUAL(10, output.v_maj);
 
301
    CPPUNIT_ASSERT_EQUAL(12, output.v_min);
 
302
    input.reset();
 
303
 
 
304
    // space padded URL
 
305
    input.append("GET  /     HTTP/1.1\r\n", 21);
 
306
    //printf("TEST: '%s'\n",input.content());
 
307
    HttpParserInit(&output, input.content(), input.contentSize());
 
308
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
309
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
310
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
311
    CPPUNIT_ASSERT(memcmp("GET  /     HTTP/1.1\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
312
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
313
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
314
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
315
    CPPUNIT_ASSERT_EQUAL(5, output.u_start);
 
316
    CPPUNIT_ASSERT_EQUAL(5, output.u_end);
 
317
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
318
    CPPUNIT_ASSERT_EQUAL(11, output.v_start);
 
319
    CPPUNIT_ASSERT_EQUAL(18, output.v_end);
 
320
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
321
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
322
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
323
    input.reset();
 
324
 
 
325
    // space padded version
 
326
    // RFC 1945 and 2616 specify version is followed by CRLF. No intermediary bytes.
 
327
    // NP: the terminal whitespace is a special case: invalid for even HTTP/0.9 with no version tag
 
328
    input.append("GET / HTTP/1.1 \n", 16);
 
329
    //printf("TEST: '%s'\n",input.content());
 
330
    HttpParserInit(&output, input.content(), input.contentSize());
 
331
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
332
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
333
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
334
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1 \n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
335
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
336
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
337
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
338
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
339
    CPPUNIT_ASSERT_EQUAL(13, output.u_end);
 
340
    CPPUNIT_ASSERT(memcmp("/ HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
341
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
342
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
343
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
344
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
345
    input.reset();
 
346
 
 
347
    // whitespace inside URI. (nasty but happens)
 
348
    input.append("GET /fo o/ HTTP/1.1\n", 20);
 
349
    //printf("TEST: '%s'\n",input.content());
 
350
    HttpParserInit(&output, input.content(), input.contentSize());
 
351
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
352
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
353
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
354
    CPPUNIT_ASSERT(memcmp("GET /fo o/ HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
355
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
356
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
357
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
358
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
359
    CPPUNIT_ASSERT_EQUAL(9, output.u_end);
 
360
    CPPUNIT_ASSERT(memcmp("/fo o/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
361
    CPPUNIT_ASSERT_EQUAL(11, output.v_start);
 
362
    CPPUNIT_ASSERT_EQUAL(18, output.v_end);
 
363
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
364
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
365
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
366
    input.reset();
 
367
 
 
368
    // additional data in buffer
 
369
    input.append("GET /     HTTP/1.1\nboo!", 23);
 
370
    //printf("TEST: '%s'\n",input.content());
 
371
    HttpParserInit(&output, input.content(), input.contentSize());
 
372
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
373
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
374
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-5, output.req_end);
 
375
    CPPUNIT_ASSERT(memcmp("GET /     HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
376
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
377
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
378
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
379
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
380
    CPPUNIT_ASSERT_EQUAL(4, output.u_end); // strangeness generated by following RFC
 
381
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
382
    CPPUNIT_ASSERT_EQUAL(10, output.v_start);
 
383
    CPPUNIT_ASSERT_EQUAL(17, output.v_end);
 
384
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
385
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
386
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
387
    input.reset();
 
388
 
 
389
    // alternative EOL sequence: NL-only
 
390
    input.append("GET / HTTP/1.1\n", 15);
 
391
    //printf("TEST: '%s'\n",input.content());
 
392
    HttpParserInit(&output, input.content(), input.contentSize());
 
393
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
394
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
395
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
396
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
397
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
398
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
399
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
400
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
401
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
402
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
403
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
404
    CPPUNIT_ASSERT_EQUAL(13, output.v_end);
 
405
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
406
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
407
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
408
    input.reset();
 
409
 
 
410
    // alternative EOL sequence: double-NL-only
 
411
    input.append("GET / HTTP/1.1\n\n", 16);
 
412
    //printf("TEST: '%s'\n",input.content());
 
413
    HttpParserInit(&output, input.content(), input.contentSize());
 
414
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
415
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
416
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-2, output.req_end);
 
417
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
418
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
419
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
420
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
421
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
422
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
423
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
424
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
425
    CPPUNIT_ASSERT_EQUAL(13, output.v_end);
 
426
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
427
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
428
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
429
    input.reset();
 
430
 
 
431
    // RELAXED alternative EOL sequence: multi-CR-NL
 
432
    input.append("GET / HTTP/1.1\r\r\r\n", 18);
 
433
    //printf("TEST: '%s'\n",input.content());
 
434
    HttpParserInit(&output, input.content(), input.contentSize());
 
435
    Config.onoff.relaxed_header_parser = 1;
 
436
    // Being tolerant we can ignore and elide these apparently benign CR
 
437
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
438
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
439
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
440
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\r\r\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
441
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
442
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
443
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
444
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
445
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
446
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
447
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
448
    CPPUNIT_ASSERT_EQUAL(13, output.v_end);
 
449
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
450
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
451
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
452
    input.reset();
 
453
 
 
454
    // STRICT alternative EOL sequence: multi-CR-NL
 
455
    input.append("GET / HTTP/1.1\r\r\r\n", 18);
 
456
    //printf("TEST: '%s'\n",input.content());
 
457
    HttpParserInit(&output, input.content(), input.contentSize());
 
458
    // strict mode treats these as several bare-CR in the request line which is explicitly invalid.
 
459
    Config.onoff.relaxed_header_parser = 0;
 
460
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
461
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
462
    CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
 
463
    CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
 
464
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
465
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
466
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
467
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
468
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
469
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
470
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
471
    input.reset();
 
472
 
 
473
    // RFC 2616 : . method
 
474
    input.append(". / HTTP/1.1\n", 13);
 
475
    //printf("TEST: '%s'\n",input.content());
 
476
    HttpParserInit(&output, input.content(), input.contentSize());
 
477
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
478
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
479
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
480
    CPPUNIT_ASSERT(memcmp(". / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
481
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
482
    CPPUNIT_ASSERT_EQUAL(0, output.m_end);
 
483
    CPPUNIT_ASSERT(memcmp(".", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
484
    CPPUNIT_ASSERT_EQUAL(2, output.u_start);
 
485
    CPPUNIT_ASSERT_EQUAL(2, output.u_end);
 
486
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
487
    CPPUNIT_ASSERT_EQUAL(4, output.v_start);
 
488
    CPPUNIT_ASSERT_EQUAL(11, output.v_end);
 
489
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
490
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
491
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
492
    input.reset();
 
493
 
 
494
    // OPTIONS with * URL
 
495
    input.append("OPTIONS * HTTP/1.1\n", 19);
 
496
    //printf("TEST: '%s'\n",input.content());
 
497
    HttpParserInit(&output, input.content(), input.contentSize());
 
498
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
499
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
500
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
501
    CPPUNIT_ASSERT(memcmp("OPTIONS * HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
502
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
503
    CPPUNIT_ASSERT_EQUAL(6, output.m_end);
 
504
    CPPUNIT_ASSERT(memcmp("OPTIONS", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
505
    CPPUNIT_ASSERT_EQUAL(8, output.u_start);
 
506
    CPPUNIT_ASSERT_EQUAL(8, output.u_end);
 
507
    CPPUNIT_ASSERT(memcmp("*", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
508
    CPPUNIT_ASSERT_EQUAL(10, output.v_start);
 
509
    CPPUNIT_ASSERT_EQUAL(17, output.v_end);
 
510
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
511
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
512
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
513
    input.reset();
 
514
 
 
515
    // unknown method
 
516
    input.append("HELLOWORLD / HTTP/1.1\n", 22);
 
517
    //printf("TEST: '%s'\n",input.content());
 
518
    HttpParserInit(&output, input.content(), input.contentSize());
 
519
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
520
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
521
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
522
    CPPUNIT_ASSERT(memcmp("HELLOWORLD / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
523
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
524
    CPPUNIT_ASSERT_EQUAL(9, output.m_end);
 
525
    CPPUNIT_ASSERT(memcmp("HELLOWORLD", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
526
    CPPUNIT_ASSERT_EQUAL(11, output.u_start);
 
527
    CPPUNIT_ASSERT_EQUAL(11, output.u_end);
 
528
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
529
    CPPUNIT_ASSERT_EQUAL(13, output.v_start);
 
530
    CPPUNIT_ASSERT_EQUAL(20, output.v_end);
 
531
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
532
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
533
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
534
    input.reset();
 
535
 
 
536
    // This stage of the parser does not yet accept non-HTTP protocol names.
 
537
    // violations mode treats them as HTTP/0.9 requests!
 
538
    input.append("GET / FOO/1.0\n", 14);
 
539
    //printf("TEST: '%s'\n",input.content());
 
540
    HttpParserInit(&output, input.content(), input.contentSize());
 
541
#if USE_HTTP_VIOLATIONS
 
542
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
543
    CPPUNIT_ASSERT_EQUAL(12, output.u_end);
 
544
    CPPUNIT_ASSERT(memcmp("/ FOO/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
545
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
546
    CPPUNIT_ASSERT_EQUAL(9, output.v_min);
 
547
#else
 
548
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
549
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
550
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
551
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
552
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
553
#endif
 
554
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
555
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
556
    CPPUNIT_ASSERT(memcmp("GET / FOO/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
557
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
558
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
559
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
560
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
561
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
562
    CPPUNIT_ASSERT_EQUAL(12, output.v_end);
 
563
    CPPUNIT_ASSERT(memcmp("FOO/1.0", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
564
    input.reset();
 
565
 
 
566
    // RELAXED space padded method (in strict mode SP is reserved so invalid as a method byte)
 
567
    input.append(" GET / HTTP/1.1\n", 16);
 
568
    //printf("TEST: '%s'\n",input.content());
 
569
    HttpParserInit(&output, input.content(), input.contentSize());
 
570
    Config.onoff.relaxed_header_parser = 1;
 
571
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
572
    CPPUNIT_ASSERT_EQUAL(1, output.req_start);
 
573
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
574
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
575
    CPPUNIT_ASSERT_EQUAL(1, output.m_start);
 
576
    CPPUNIT_ASSERT_EQUAL(3, output.m_end);
 
577
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
578
    CPPUNIT_ASSERT_EQUAL(5, output.u_start);
 
579
    CPPUNIT_ASSERT_EQUAL(5, output.u_end);
 
580
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
581
    CPPUNIT_ASSERT_EQUAL(7, output.v_start);
 
582
    CPPUNIT_ASSERT_EQUAL(14, output.v_end);
 
583
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
584
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
585
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
586
    input.reset();
 
587
 
 
588
    // STRICT space padded method (in strict mode SP is reserved so invalid as a method byte)
 
589
    input.append(" GET / HTTP/1.1\n", 16);
 
590
    //printf("TEST: '%s'\n",input.content());
 
591
    HttpParserInit(&output, input.content(), input.contentSize());
 
592
    Config.onoff.relaxed_header_parser = 0;
 
593
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
594
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
595
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
596
    CPPUNIT_ASSERT(memcmp(" GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
597
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
598
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
599
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
600
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
601
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
602
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
603
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
604
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
605
    input.reset();
 
606
 
 
607
    // tab padded method (NP: tab is not SP so treated as any other binary)
 
608
    input.append("\tGET / HTTP/1.1\n", 16);
 
609
    //printf("TEST: '%s'\n",input.content());
 
610
    HttpParserInit(&output, input.content(), input.contentSize());
 
611
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
612
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
613
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
614
    CPPUNIT_ASSERT(memcmp("\tGET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
615
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
616
    CPPUNIT_ASSERT_EQUAL(3, output.m_end);
 
617
    CPPUNIT_ASSERT(memcmp("\tGET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
618
    CPPUNIT_ASSERT_EQUAL(5, output.u_start);
 
619
    CPPUNIT_ASSERT_EQUAL(5, output.u_end);
 
620
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
621
    CPPUNIT_ASSERT_EQUAL(7, output.v_start);
 
622
    CPPUNIT_ASSERT_EQUAL(14, output.v_end);
 
623
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
624
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
625
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
626
    input.reset();
 
627
 
 
628
    input.append("GET", 3);
 
629
    //printf("TEST: '%s'\n",input.content());
 
630
    HttpParserInit(&output, input.content(), input.contentSize());
 
631
    CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
 
632
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
633
    CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
 
634
    CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
 
635
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
636
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
637
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
638
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
639
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
640
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
641
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
642
    input.reset();
 
643
 
 
644
    input.append("GET ", 4);
 
645
    //printf("TEST: '%s'\n",input.content());
 
646
    HttpParserInit(&output, input.content(), input.contentSize());
 
647
    CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
 
648
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
649
    CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
 
650
    CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
 
651
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
652
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
653
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
654
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
655
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
656
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
657
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
658
    input.reset();
 
659
 
 
660
    input.append("GET / HT", 8);
 
661
    //printf("TEST: '%s'\n",input.content());
 
662
    HttpParserInit(&output, input.content(), input.contentSize());
 
663
    CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
 
664
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
665
    CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
 
666
    CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
 
667
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
668
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
669
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
670
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
671
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
672
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
673
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
674
    input.reset();
 
675
 
 
676
    input.append("GET / HTTP/1.1", 14);
 
677
    //printf("TEST: '%s'\n",input.content());
 
678
    HttpParserInit(&output, input.content(), input.contentSize());
 
679
    CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
 
680
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
681
    CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
 
682
    CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
 
683
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
684
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
685
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
686
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
687
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
688
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
689
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
690
    input.reset();
 
691
 
 
692
    // method-only
 
693
    input.append("A\n", 2);
 
694
    //printf("TEST: '%s'\n",input.content());
 
695
    HttpParserInit(&output, input.content(), input.contentSize());
 
696
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
697
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
698
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
699
    CPPUNIT_ASSERT(memcmp("A\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
700
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
701
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
702
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
703
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
704
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
705
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
706
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
707
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
708
    input.reset();
 
709
 
 
710
    // no method (but in a form which is ambiguous with HTTP/0.9 simple-request)
 
711
    input.append("/ HTTP/1.0\n", 11);
 
712
    //printf("TEST: '%s'\n",input.content());
 
713
    HttpParserInit(&output, input.content(), input.contentSize());
 
714
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
715
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
716
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
717
    CPPUNIT_ASSERT(memcmp("/ HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
718
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
719
    CPPUNIT_ASSERT_EQUAL(0, output.m_end);
 
720
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
721
    CPPUNIT_ASSERT_EQUAL(2, output.u_start);
 
722
    CPPUNIT_ASSERT_EQUAL(9, output.u_end);
 
723
    CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
724
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
725
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
726
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
727
    CPPUNIT_ASSERT_EQUAL(9, output.v_min);
 
728
    input.reset();
 
729
 
 
730
    // RELAXED no method (an invalid format)
 
731
    input.append(" / HTTP/1.0\n", 12);
 
732
    //printf("TEST: '%s'\n",input.content());
 
733
    HttpParserInit(&output, input.content(), input.contentSize());
 
734
    // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
 
735
    Config.onoff.relaxed_header_parser = 1;
 
736
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
737
    CPPUNIT_ASSERT_EQUAL(1, output.req_start);
 
738
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
739
    CPPUNIT_ASSERT(memcmp("/ HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
740
    CPPUNIT_ASSERT_EQUAL(1, output.m_start);
 
741
    CPPUNIT_ASSERT_EQUAL(1, output.m_end);
 
742
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
743
    CPPUNIT_ASSERT_EQUAL(3, output.u_start);
 
744
    CPPUNIT_ASSERT_EQUAL(10, output.u_end);
 
745
    CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
746
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
747
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
748
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
749
    CPPUNIT_ASSERT_EQUAL(9, output.v_min);
 
750
    input.reset();
 
751
 
 
752
    // STRICT no method (an invalid format)
 
753
    input.append(" / HTTP/1.0\n", 12);
 
754
    //printf("TEST: '%s'\n",input.content());
 
755
    HttpParserInit(&output, input.content(), input.contentSize());
 
756
    // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
 
757
    Config.onoff.relaxed_header_parser = 0;
 
758
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
759
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
760
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
761
    CPPUNIT_ASSERT(memcmp(" / HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
762
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
763
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
764
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
765
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
766
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
767
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
768
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
769
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
770
    input.reset();
 
771
 
 
772
    // binary code in method (strange but ...)
 
773
    input.append("GET\x0B / HTTP/1.1\n", 16);
 
774
    //printf("TEST: %d-%d/%d '%.*s'\n", output.req_start, output.req_end, input.contentSize(), 16, input.content());
 
775
    HttpParserInit(&output, input.content(), input.contentSize());
 
776
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
777
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
778
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
779
    CPPUNIT_ASSERT(memcmp("GET\x0B / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
780
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
781
    CPPUNIT_ASSERT_EQUAL(3, output.m_end);
 
782
    CPPUNIT_ASSERT(memcmp("GET\x0B", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
783
    CPPUNIT_ASSERT_EQUAL(5, output.u_start);
 
784
    CPPUNIT_ASSERT_EQUAL(5, output.u_end);
 
785
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
786
    CPPUNIT_ASSERT_EQUAL(7, output.v_start);
 
787
    CPPUNIT_ASSERT_EQUAL(14, output.v_end);
 
788
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
789
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
790
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
791
    input.reset();
 
792
 
 
793
    // CR in method
 
794
    // RFC 2616 sec 5.1 prohibits CR other than in terminator.
 
795
    input.append("GET\r / HTTP/1.1\r\n", 16);
 
796
    //printf("TEST: '%s'\n",input.content());
 
797
    HttpParserInit(&output, input.content(), input.contentSize());
 
798
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
799
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
800
    CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
 
801
    CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
 
802
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
803
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
804
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
805
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
806
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
807
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
808
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
809
    input.reset();
 
810
 
 
811
    // binary code NUL! in method (strange but ...)
 
812
    input.append("GET\0 / HTTP/1.1\n", 16);
 
813
    //printf("TEST: %d-%d/%d '%.*s'\n", output.req_start, output.req_end, input.contentSize(), 16, input.content());
 
814
    HttpParserInit(&output, input.content(), input.contentSize());
 
815
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
816
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
817
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
818
    CPPUNIT_ASSERT(memcmp("GET\0 / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
819
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
820
    CPPUNIT_ASSERT_EQUAL(3, output.m_end);
 
821
    CPPUNIT_ASSERT(memcmp("GET\0", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
822
    CPPUNIT_ASSERT_EQUAL(5, output.u_start);
 
823
    CPPUNIT_ASSERT_EQUAL(5, output.u_end);
 
824
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
825
    CPPUNIT_ASSERT_EQUAL(7, output.v_start);
 
826
    CPPUNIT_ASSERT_EQUAL(14, output.v_end);
 
827
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
828
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
829
    CPPUNIT_ASSERT_EQUAL(1, output.v_min);
 
830
    input.reset();
 
831
 
 
832
    // no URL (grammer otherwise correct)
 
833
    input.append("GET  HTTP/1.1\n", 14);
 
834
    //printf("TEST: '%s'\n",input.content());
 
835
    HttpParserInit(&output, input.content(), input.contentSize());
 
836
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
837
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
838
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
839
    CPPUNIT_ASSERT(memcmp("GET  HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
840
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
841
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
842
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
843
    CPPUNIT_ASSERT_EQUAL(5, output.u_start);
 
844
    CPPUNIT_ASSERT_EQUAL(12, output.u_end);
 
845
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
846
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
847
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
848
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
849
    CPPUNIT_ASSERT_EQUAL(9, output.v_min);
 
850
    input.reset();
 
851
 
 
852
    // no URL (grammer invalid, ambiguous with RFC 1945 HTTP/0.9 simple-request)
 
853
    input.append("GET HTTP/1.1\n", 13);
 
854
    //printf("TEST: '%s'\n",input.content());
 
855
    HttpParserInit(&output, input.content(), input.contentSize());
 
856
    CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
 
857
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
858
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
859
    CPPUNIT_ASSERT(memcmp("GET HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
860
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
861
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
862
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
863
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
864
    CPPUNIT_ASSERT_EQUAL(11, output.u_end);
 
865
    CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
866
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
867
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
868
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
869
    CPPUNIT_ASSERT_EQUAL(9, output.v_min);
 
870
    input.reset();
 
871
 
 
872
    // no version
 
873
    input.append("GET / HTTP/\n", 12);
 
874
    //printf("TEST: '%s'\n",input.content());
 
875
    HttpParserInit(&output, input.content(), input.contentSize());
 
876
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
877
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
878
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
879
    CPPUNIT_ASSERT(memcmp("GET / HTTP/\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
880
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
881
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
882
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
883
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
884
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
885
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
886
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
887
    CPPUNIT_ASSERT_EQUAL(10, output.v_end);
 
888
    CPPUNIT_ASSERT(memcmp("HTTP/", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
889
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
890
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
891
    input.reset();
 
892
 
 
893
    // no major version
 
894
    input.append("GET / HTTP/.1\n", 14);
 
895
    //printf("TEST: '%s'\n",input.content());
 
896
    HttpParserInit(&output, input.content(), input.contentSize());
 
897
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
898
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
899
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
900
    CPPUNIT_ASSERT(memcmp("GET / HTTP/.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
901
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
902
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
903
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
904
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
905
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
906
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
907
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
908
    CPPUNIT_ASSERT_EQUAL(12, output.v_end);
 
909
    CPPUNIT_ASSERT(memcmp("HTTP/.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
910
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
911
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
912
    input.reset();
 
913
 
 
914
    // no version dot
 
915
    input.append("GET / HTTP/11\n", 14);
 
916
    //printf("TEST: '%s'\n",input.content());
 
917
    HttpParserInit(&output, input.content(), input.contentSize());
 
918
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
919
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
920
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
921
    CPPUNIT_ASSERT(memcmp("GET / HTTP/11\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
922
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
923
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
924
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
925
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
926
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
927
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
928
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
929
    CPPUNIT_ASSERT_EQUAL(12, output.v_end);
 
930
    CPPUNIT_ASSERT(memcmp("HTTP/11", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
931
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
932
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
933
    input.reset();
 
934
 
 
935
    // negative major version (bug 3062)
 
936
    input.append("GET / HTTP/-999999.1\n", 21);
 
937
    //printf("TEST: '%s'\n",input.content());
 
938
    HttpParserInit(&output, input.content(), input.contentSize());
 
939
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
940
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
941
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
942
    CPPUNIT_ASSERT(memcmp("GET / HTTP/-999999.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
943
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
944
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
945
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
946
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
947
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
948
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
949
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
950
    CPPUNIT_ASSERT_EQUAL(19, output.v_end);
 
951
    CPPUNIT_ASSERT(memcmp("HTTP/-999999.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
952
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
953
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
954
    input.reset();
 
955
 
 
956
    // no minor version
 
957
    input.append("GET / HTTP/1.\n", 14);
 
958
    //printf("TEST: '%s'\n",input.content());
 
959
    HttpParserInit(&output, input.content(), input.contentSize());
 
960
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
961
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
962
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
963
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
964
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
965
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
966
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
967
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
968
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
969
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
970
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
971
    CPPUNIT_ASSERT_EQUAL(12, output.v_end);
 
972
    CPPUNIT_ASSERT(memcmp("HTTP/1.", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
973
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
974
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
975
    input.reset();
 
976
 
 
977
    // negative major version (bug 3062 corollary)
 
978
    input.append("GET / HTTP/1.-999999\n", 21);
 
979
    //printf("TEST: '%s'\n",input.content());
 
980
    HttpParserInit(&output, input.content(), input.contentSize());
 
981
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
982
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
983
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
984
    CPPUNIT_ASSERT(memcmp("GET / HTTP/1.-999999\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
985
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
986
    CPPUNIT_ASSERT_EQUAL(2, output.m_end);
 
987
    CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
988
    CPPUNIT_ASSERT_EQUAL(4, output.u_start);
 
989
    CPPUNIT_ASSERT_EQUAL(4, output.u_end);
 
990
    CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
 
991
    CPPUNIT_ASSERT_EQUAL(6, output.v_start);
 
992
    CPPUNIT_ASSERT_EQUAL(19, output.v_end);
 
993
    CPPUNIT_ASSERT(memcmp("HTTP/1.-999999", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
 
994
    CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
 
995
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
996
    input.reset();
 
997
 
 
998
    // binary line
 
999
    input.append("\xB\xC\xE\xF\n", 5);
 
1000
    //printf("TEST: binary-line\n");
 
1001
    HttpParserInit(&output, input.content(), input.contentSize());
 
1002
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
1003
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
1004
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
1005
    CPPUNIT_ASSERT(memcmp("\xB\xC\xE\xF\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
1006
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
1007
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
1008
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
1009
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
1010
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
1011
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
1012
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
1013
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
1014
    input.reset();
 
1015
 
 
1016
    // mixed whitespace line
 
1017
    // We accept non-space binary bytes for method so first \t shows up as that
 
1018
    // but remaining space and tabs are skipped searching for URI-start
 
1019
    input.append("\t \t \t\n", 6);
 
1020
    //printf("TEST: mixed whitespace\n");
 
1021
    HttpParserInit(&output, input.content(), input.contentSize());
 
1022
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
1023
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
1024
    CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
 
1025
    CPPUNIT_ASSERT(memcmp("\t \t \t\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
 
1026
    CPPUNIT_ASSERT_EQUAL(0, output.m_start);
 
1027
    CPPUNIT_ASSERT_EQUAL(0, output.m_end);
 
1028
    CPPUNIT_ASSERT(memcmp("\t", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
 
1029
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
1030
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
1031
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
1032
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
1033
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
1034
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
1035
    input.reset();
 
1036
 
 
1037
    // mixed whitespace line with CR middle
 
1038
    // CR aborts on sight, so even initial \t method is not marked as above
 
1039
    // (not when parsing clean with whole line available anyway)
 
1040
    input.append("\t  \r \n", 6);
 
1041
    //printf("TEST: mixed whitespace with CR\n");
 
1042
    HttpParserInit(&output, input.content(), input.contentSize());
 
1043
    CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
 
1044
    CPPUNIT_ASSERT_EQUAL(0, output.req_start);
 
1045
    CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
 
1046
    CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
 
1047
    CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
 
1048
    CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
 
1049
    CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
 
1050
    CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
 
1051
    CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
 
1052
    CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
 
1053
    CPPUNIT_ASSERT_EQUAL(0, output.v_min);
 
1054
    input.reset();
 
1055
}