1#!/usr/bin/env perl 2BEGIN { 3 # add current source dir to the include-path 4 # we need this for make distcheck 5 (my $srcdir = $0) =~ s,/[^/]+$,/,; 6 unshift @INC, $srcdir; 7} 8 9use strict; 10use IO::Socket; 11use Test::More tests => 54; 12use LightyTest; 13 14my $tf = LightyTest->new(); 15my $t; 16 17ok($tf->start_proc == 0, "Starting lighttpd") or die(); 18 19## Basic Request-Handling 20 21$t->{REQUEST} = ( <<EOF 22GET /foobar HTTP/1.0 23EOF 24 ); 25$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; 26ok($tf->handle_http($t) == 0, 'file not found'); 27 28$t->{REQUEST} = ( <<EOF 29GET /foobar?foobar HTTP/1.0 30EOF 31 ); 32$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; 33ok($tf->handle_http($t) == 0, 'file not found + querystring'); 34 35$t->{REQUEST} = ( <<EOF 36GET /12345.txt HTTP/1.0 37Host: 123.example.org 38EOF 39 ); 40$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain' } ]; 41ok($tf->handle_http($t) == 0, 'GET, content == 12345, mimetype text/plain'); 42 43$t->{REQUEST} = ( <<EOF 44GET /12345.html HTTP/1.0 45Host: 123.example.org 46EOF 47 ); 48$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/html' } ]; 49ok($tf->handle_http($t) == 0, 'GET, content == 12345, mimetype text/html'); 50 51$t->{REQUEST} = ( <<EOF 52GET /dummyfile.bla HTTP/1.0 53Host: 123.example.org 54EOF 55 ); 56$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'application/octet-stream' } ]; 57ok($tf->handle_http($t) == 0, 'GET, content == 12345, mimetype application/octet-stream'); 58 59 60$t->{REQUEST} = ( <<EOF 61POST / HTTP/1.0 62Content-type: application/x-www-form-urlencoded 63Content-length: 0 64EOF 65 ); 66$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; 67ok($tf->handle_http($t) == 0, 'POST request, empty request-body'); 68 69$t->{REQUEST} = ( <<EOF 70HEAD / HTTP/1.0 71EOF 72 ); 73$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '-HTTP-Content' => ''} ]; 74ok($tf->handle_http($t) == 0, 'HEAD request, no content'); 75 76$t->{REQUEST} = ( <<EOF 77HEAD /12345.html HTTP/1.0 78Host: 123.example.org 79EOF 80 ); 81$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '-HTTP-Content' => '', 'Content-Type' => 'text/html', 'Content-Length' => '6'} ]; 82ok($tf->handle_http($t) == 0, 'HEAD request, mimetype text/html, content-length'); 83 84$t->{REQUEST} = ( <<EOF 85HEAD http://123.example.org/12345.html HTTP/1.1 86Connection: close 87EOF 88 ); 89$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, '-HTTP-Content' => '', 'Content-Type' => 'text/html', 'Content-Length' => '6'} ]; 90ok($tf->handle_http($t) == 0, 'Hostname in first line, HTTP/1.1'); 91 92$t->{REQUEST} = ( <<EOF 93HEAD https://123.example.org/12345.html HTTP/1.0 94EOF 95 ); 96$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '-HTTP-Content' => '', 'Content-Type' => 'text/html', 'Content-Length' => '6'} ]; 97ok($tf->handle_http($t) == 0, 'Hostname in first line as https url'); 98 99$t->{REQUEST} = ( <<EOF 100HEAD /foobar?foobar HTTP/1.0 101EOF 102 ); 103$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, '-HTTP-Content' => '' } ]; 104ok($tf->handle_http($t) == 0, 'HEAD request, file-not-found, query-string'); 105 106# (expect 200 OK instead of 100 Continue since request body sent with request) 107# (if we waited to send request body, would expect 100 Continue, first) 108$t->{REQUEST} = ( <<EOF 109POST /cgi.pl?post-len HTTP/1.1 110Host: www.example.org 111Connection: close 112Content-Type: application/x-www-form-urlencoded 113Content-Length: 4 114Expect: 100-continue 115 116123 117EOF 118 ); 119$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; 120ok($tf->handle_http($t) == 0, 'Continue, Expect'); 121 122# note Transfer-Encoding: chunked tests will fail with 411 Length Required if 123# server.stream-request-body != 0 in lighttpd.conf 124$t->{REQUEST} = ( <<EOF 125POST /cgi.pl?post-len HTTP/1.1 126Host: www.example.org 127Connection: close 128Content-Type: application/x-www-form-urlencoded 129Transfer-Encoding: chunked 130 131a 1320123456789 1330 134 135EOF 136 ); 137$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; 138ok($tf->handle_http($t) == 0, 'POST via Transfer-Encoding: chunked, lc hex'); 139 140$t->{REQUEST} = ( <<EOF 141POST /cgi.pl?post-len HTTP/1.1 142Host: www.example.org 143Connection: close 144Content-Type: application/x-www-form-urlencoded 145Transfer-Encoding: chunked 146 147A 1480123456789 1490 150 151EOF 152 ); 153$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; 154ok($tf->handle_http($t) == 0, 'POST via Transfer-Encoding: chunked, uc hex'); 155 156$t->{REQUEST} = ( <<EOF 157POST /cgi.pl?post-len HTTP/1.1 158Host: www.example.org 159Connection: close 160Content-Type: application/x-www-form-urlencoded 161Transfer-Encoding: chunked 162 16310 1640123456789abcdef 1650 166 167EOF 168 ); 169$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; 170ok($tf->handle_http($t) == 0, 'POST via Transfer-Encoding: chunked, two hex'); 171 172$t->{REQUEST} = ( <<EOF 173POST /cgi.pl?post-len HTTP/1.1 174Host: www.example.org 175Connection: close 176Content-Type: application/x-www-form-urlencoded 177Transfer-Encoding: chunked 178 179a 1800123456789 1810 182Test-Trailer: testing 183 184EOF 185 ); 186$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; 187ok($tf->handle_http($t) == 0, 'POST via Transfer-Encoding: chunked, with trailer'); 188 189$t->{REQUEST} = ( <<EOF 190POST /cgi.pl?post-len HTTP/1.1 191Host: www.example.org 192Connection: close 193Content-Type: application/x-www-form-urlencoded 194Transfer-Encoding: chunked 195 196a; comment 1970123456789 1980 199 200EOF 201 ); 202$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; 203ok($tf->handle_http($t) == 0, 'POST via Transfer-Encoding: chunked, chunked header comment'); 204 205$t->{REQUEST} = ( <<EOF 206POST /cgi.pl?post-len HTTP/1.1 207Host: www.example.org 208Connection: close 209Content-Type: application/x-www-form-urlencoded 210Transfer-Encoding: chunked 211 212az 2130123456789 2140 215 216EOF 217 ); 218$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 400 } ]; 219ok($tf->handle_http($t) == 0, 'POST via Transfer-Encoding: chunked; bad chunked header'); 220 221$t->{REQUEST} = ( <<EOF 222POST /cgi.pl?post-len HTTP/1.1 223Host: www.example.org 224Connection: close 225Content-Type: application/x-www-form-urlencoded 226Transfer-Encoding: chunked 227 228a 2290123456789xxxxxxxx 2300 231 232EOF 233 ); 234$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 400 } ]; 235ok($tf->handle_http($t) == 0, 'POST via Transfer-Encoding: chunked; mismatch chunked header size and chunked data size'); 236 237$t->{REQUEST} = ( <<EOF 238POST /cgi.pl?post-len HTTP/1.1 239Host: www.example.org 240Connection: close 241Content-Type: application/x-www-form-urlencoded 242Transfer-Encoding: chunked 243 244a ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 2450123456789 2460 247 248EOF 249 ); 250$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 400 } ]; 251ok($tf->handle_http($t) == 0, 'POST via Transfer-Encoding: chunked; chunked header too long'); 252 253## ranges 254 255$t->{REQUEST} = ( <<EOF 256GET /12345.txt HTTP/1.1 257Host: 123.example.org 258Connection: close 259Range: bytes=0-3 260EOF 261 ); 262$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 206, 'HTTP-Content' => '1234' } ]; 263ok($tf->handle_http($t) == 0, 'GET, Range 0-3'); 264 265$t->{REQUEST} = ( <<EOF 266GET /12345.txt HTTP/1.1 267Host: 123.example.org 268Connection: close 269Range: bytes=-3 270EOF 271 ); 272$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 206, 'HTTP-Content' => '45'."\n" } ]; 273ok($tf->handle_http($t) == 0, 'GET, Range -3'); 274 275$t->{REQUEST} = ( <<EOF 276GET /12345.txt HTTP/1.1 277Host: 123.example.org 278Connection: close 279Range: bytes=3- 280EOF 281 ); 282$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 206, 'HTTP-Content' => '45'."\n" } ]; 283ok($tf->handle_http($t) == 0, 'GET, Range 3-'); 284 285$t->{REQUEST} = ( <<EOF 286GET /12345.txt HTTP/1.1 287Host: 123.example.org 288Connection: close 289Range: bytes=0-1,3-4 290EOF 291 ); 292$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 206, 'HTTP-Content' => '12345' } ]; 293ok($tf->handle_http($t) == 0, 'GET, Range 0-1,3-4 (ranges merged)'); 294 295$t->{REQUEST} = ( <<EOF 296GET /100.txt HTTP/1.1 297Host: 123.example.org 298Connection: close 299Range: bytes=0-1,97-98 300EOF 301 ); 302$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 206, 'HTTP-Content' => <<EOF 303--fkj49sn38dcn3\r 304Content-Type: text/plain\r 305Content-Range: bytes 0-1/100\r 306\r 30712\r 308--fkj49sn38dcn3\r 309Content-Type: text/plain\r 310Content-Range: bytes 97-98/100\r 311\r 312hi\r 313--fkj49sn38dcn3--\r 314EOF 315 } ]; 316ok($tf->handle_http($t) == 0, 'GET, Range 0-1,97-98 (ranges not merged)'); 317 318$t->{REQUEST} = ( <<EOF 319GET /12345.txt HTTP/1.1 320Host: 123.example.org 321Connection: close 322Range: bytes=0- 323EOF 324 ); 325$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 206, 'Content-Range' => 'bytes 0-5/6' } ]; 326ok($tf->handle_http($t) == 0, 'GET, Range 0-'); 327 328$t->{REQUEST} = ( <<EOF 329GET /12345.txt HTTP/1.1 330Host: 123.example.org 331Connection: close 332Range: bytes=0-- 333EOF 334 ); 335$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 416 } ]; 336ok($tf->handle_http($t) == 0, 'GET, Range 0--'); 337 338$t->{REQUEST} = ( <<EOF 339GET /12345.txt HTTP/1.1 340Host: 123.example.org 341Connection: close 342Range: bytes=-2-3 343EOF 344 ); 345$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 416 } ]; 346ok($tf->handle_http($t) == 0, 'GET, Range -2-3'); 347 348$t->{REQUEST} = ( <<EOF 349GET /12345.txt HTTP/1.1 350Host: 123.example.org 351Connection: close 352Range: bytes=-0 353EOF 354 ); 355$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 416, 'HTTP-Content' => <<EOF 356<?xml version="1.0" encoding="iso-8859-1"?> 357<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 358 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 359<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 360 <head> 361 <title>416 Range Not Satisfiable</title> 362 </head> 363 <body> 364 <h1>416 Range Not Satisfiable</h1> 365 </body> 366</html> 367EOF 368 } ]; 369ok($tf->handle_http($t) == 0, 'GET, Range -0'); 370 371$t->{REQUEST} = ( <<EOF 372GET /12345.txt HTTP/1.1 373Host: 123.example.org 374Connection: close 375Range: bytes=25- 376EOF 377 ); 378$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 416, 'HTTP-Content' => <<EOF 379<?xml version="1.0" encoding="iso-8859-1"?> 380<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 381 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 382<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 383 <head> 384 <title>416 Range Not Satisfiable</title> 385 </head> 386 <body> 387 <h1>416 Range Not Satisfiable</h1> 388 </body> 389</html> 390EOF 391 } ]; 392 393ok($tf->handle_http($t) == 0, 'GET, Range start out of range'); 394 395 396$t->{REQUEST} = ( <<EOF 397GET / HTTP/1.0 398Hsgfsdjf: asdfhdf 399hdhd: shdfhfdasd 400hfhr: jfghsdfg 401jfuuehdmn: sfdgjfdg 402jvcbzufdg: sgfdfg 403hrnvcnd: jfjdfg 404jfusfdngmd: gfjgfdusdfg 405nfj: jgfdjdfg 406jfue: jfdfdg 407EOF 408 ); 409$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; 410ok($tf->handle_http($t) == 0, 'larger headers'); 411 412 413$t->{REQUEST} = ( <<EOF 414GET /range.pdf HTTP/1.1 415Host: 123.example.org 416Range: bytes=0- 417Connection: close 418EOF 419 ); 420$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200 } ]; 421ok($tf->handle_http($t) == 0, 'GET, Range with range-requests-disabled'); 422 423$t->{REQUEST} = ( <<EOF 424GET /12345.txt HTTP/1.1 425Host: 123.example.org 426Connection: close 427Range: 0 428Range: bytes=0-3 429EOF 430 ); 431$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, 'HTTP-Content' => "12345\n" } ]; 432ok($tf->handle_http($t) == 0, 'GET, Range invalid range-unit (first)'); 433 434$t->{REQUEST} = ( <<EOF 435GET /12345.txt HTTP/1.1 436Host: 123.example.org 437Connection: close 438Range: bytes=0-3 439Range: 0 440EOF 441 ); 442$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 206 } ]; 443ok($tf->handle_http($t) == 0, 'GET, Range ignore invalid range (second)'); 444 445$t->{REQUEST} = ( <<EOF 446OPTIONS / HTTP/1.0 447Content-Length: 4 448 4491234 450EOF 451 ); 452$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; 453ok($tf->handle_http($t) == 0, 'OPTIONS with Content-Length'); 454 455$t->{REQUEST} = ( <<EOF 456OPTIONS rtsp://221.192.134.146:80 RTSP/1.1 457Host: 221.192.134.146:80 458EOF 459 ); 460$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ]; 461ok($tf->handle_http($t) == 0, 'OPTIONS for RTSP'); 462 463$t->{REQUEST} = ( <<EOF 464GET /index.html HTTP/1.0 465If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT 466If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT 467EOF 468 ); 469$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ]; 470ok($tf->handle_http($t) == 0, 'Duplicate If-Mod-Since, with equal timestamps'); 471 472$t->{REQUEST} = ( "GET / HTTP/1.0\r\nIf-Modified-Since: \r\n\r\n" ); 473$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; 474ok($tf->handle_http($t) == 0, 'empty If-Modified-Since'); 475 476$t->{REQUEST} = ( "GET / HTTP/1.0\r\nIf-Modified-Since: foobar\r\n\r\n" ); 477$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; 478ok($tf->handle_http($t) == 0, 'broken If-Modified-Since'); 479 480$t->{REQUEST} = ( "GET / HTTP/1.0\r\nIf-Modified-Since: this string is too long to be a valid timestamp\r\n\r\n" ); 481$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ]; 482ok($tf->handle_http($t) == 0, 'broken If-Modified-Since'); 483 484 485$t->{REQUEST} = ( <<EOF 486GET /index.html HTTP/1.0 487If-Modified-Since2: Sun, 01 Jan 2036 00:00:03 GMT 488If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT 489EOF 490 ); 491$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ]; 492ok($tf->handle_http($t) == 0, 'Similar Headers (bug #1287)'); 493 494$t->{REQUEST} = ( <<EOF 495GET /index.html HTTP/1.0 496If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT 497EOF 498 ); 499$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304, 'Content-Type' => 'text/html' } ]; 500ok($tf->handle_http($t) == 0, 'If-Modified-Since'); 501 502$t->{REQUEST} = ( <<EOF 503GET /index.html HTTP/1.0 504If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT 505EOF 506 ); 507$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304, '-Content-Length' => '' } ]; 508ok($tf->handle_http($t) == 0, 'Status 304 has no Content-Length (#1002)'); 509 510$t->{REQUEST} = ( <<EOF 511GET /12345.txt HTTP/1.0 512Host: 123.example.org 513EOF 514 ); 515$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain' } ]; 516$t->{SLOWREQUEST} = 1; 517ok($tf->handle_http($t) == 0, 'GET, slow \\r\\n\\r\\n (#2105)'); 518undef $t->{SLOWREQUEST}; 519 520print "\nPathinfo for static files\n"; 521$t->{REQUEST} = ( <<EOF 522GET /image.jpg/index.php HTTP/1.0 523EOF 524 ); 525$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ]; 526ok($tf->handle_http($t) == 0, 'static file accepting pathinfo by default'); 527 528$t->{REQUEST} = ( <<EOF 529GET /image.jpg/index.php HTTP/1.0 530Host: zzz.example.org 531EOF 532 ); 533$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ]; 534ok($tf->handle_http($t) == 0, 'static file with forbidden pathinfo'); 535 536$t->{REQUEST} = ( <<EOF 537GET /www/abc/def HTTP/1.0 538EOF 539 ); 540$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404 } ]; 541ok($tf->handle_http($t) == 0, 'pathinfo on a directory'); 542 543 544$t->{REQUEST} = ( <<EOF 545GET /12345.txt HTTP/1.1 546Connection: ,close 547Host: 123.example.org 548EOF 549 ); 550$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain', 'Connection' => 'close' } ]; 551ok($tf->handle_http($t) == 0, 'Connection-header, leading comma'); 552 553$t->{REQUEST} = ( <<EOF 554GET /12345.txt HTTP/1.1 555Connection: close,,TE 556Host: 123.example.org 557EOF 558 ); 559$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain', 'Connection' => 'close' } ]; 560ok($tf->handle_http($t) == 0, 'Connection-header, no value between two commas'); 561 562$t->{REQUEST} = ( <<EOF 563GET /12345.txt HTTP/1.1 564Connection: close, ,TE 565Host: 123.example.org 566EOF 567 ); 568$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain', 'Connection' => 'close' } ]; 569ok($tf->handle_http($t) == 0, 'Connection-header, space between two commas'); 570 571$t->{REQUEST} = ( <<EOF 572GET /12345.txt HTTP/1.1 573Connection: close, 574Host: 123.example.org 575EOF 576 ); 577$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain', 'Connection' => 'close' } ]; 578ok($tf->handle_http($t) == 0, 'Connection-header, comma after value'); 579 580$t->{REQUEST} = ( <<EOF 581GET /12345.txt HTTP/1.1 582Connection: close, 583Host: 123.example.org 584EOF 585 ); 586$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.1', 'HTTP-Status' => 200, 'HTTP-Content' => '12345'."\n", 'Content-Type' => 'text/plain', 'Connection' => 'close' } ]; 587ok($tf->handle_http($t) == 0, 'Connection-header, comma and space after value'); 588 589ok($tf->stop_proc == 0, "Stopping lighttpd"); 590 591