1import io 2import re 3import time 4from pathlib import Path 5 6from unit.applications.lang.java import ApplicationJava 7from unit.option import option 8from unit.utils import public_dir 9 10prerequisites = {'modules': {'java': 'all'}} 11 12client = ApplicationJava() 13 14 15def test_java_conf_error(temp_dir, skip_alert): 16 skip_alert( 17 r'realpath.*failed', 18 r'failed to apply new conf', 19 r'application setup failed', 20 ) 21 assert 'error' in client.conf( 22 { 23 "listeners": {"*:8080": {"pass": "applications/app"}}, 24 "applications": { 25 "app": { 26 "type": client.get_application_type(), 27 "processes": 1, 28 "working_directory": f"{option.test_dir}/java/empty", 29 "webapp": f"{temp_dir}/java", 30 "unit_jars": f"{temp_dir}/no_such_dir", 31 } 32 }, 33 } 34 ), 'conf error' 35 36 37def test_java_war(temp_dir): 38 client.load('empty_war') 39 40 assert 'success' in client.conf( 41 f'"{temp_dir}/java/empty.war"', 42 '/config/applications/empty_war/webapp', 43 ), 'configure war' 44 45 assert client.get()['status'] == 200, 'war' 46 47 48def test_java_application_cookies(): 49 client.load('cookies') 50 51 headers = client.get( 52 headers={ 53 'Cookie': 'var1=val1; var2=val2', 54 'Host': 'localhost', 55 'Connection': 'close', 56 } 57 )['headers'] 58 59 assert headers['X-Cookie-1'] == 'val1', 'cookie 1' 60 assert headers['X-Cookie-2'] == 'val2', 'cookie 2' 61 62 63def test_java_application_filter(): 64 client.load('filter') 65 66 headers = client.get()['headers'] 67 68 assert headers['X-Filter-Before'] == '1', 'filter before' 69 assert headers['X-Filter-After'] == '1', 'filter after' 70 71 assert ( 72 client.get(url='/test')['headers']['X-Filter-After'] == '0' 73 ), 'filter after 2' 74 75 76def test_java_application_get_variables(): 77 client.load('get_params') 78 79 def check_header(header, expect): 80 values = header.split(' ')[:-1] 81 assert len(values) == len(expect) 82 assert set(values) == set(expect) 83 84 headers = client.get(url='/?var1=val1&var2=&var4=val4&var4=foo')['headers'] 85 86 assert headers['X-Var-1'] == 'val1', 'GET variables' 87 assert headers['X-Var-2'] == 'true', 'GET variables 2' 88 assert headers['X-Var-3'] == 'false', 'GET variables 3' 89 90 check_header(headers['X-Param-Names'], ['var4', 'var2', 'var1']) 91 check_header(headers['X-Param-Values'], ['val4', 'foo']) 92 check_header( 93 headers['X-Param-Map'], ['var2=', 'var1=val1', 'var4=val4,foo'] 94 ) 95 96 97def test_java_application_post_variables(): 98 client.load('post_params') 99 100 headers = client.post( 101 headers={ 102 'Content-Type': 'application/x-www-form-urlencoded', 103 'Host': 'localhost', 104 'Connection': 'close', 105 }, 106 body='var1=val1&var2=', 107 )['headers'] 108 109 assert headers['X-Var-1'] == 'val1', 'POST variables' 110 assert headers['X-Var-2'] == 'true', 'POST variables 2' 111 assert headers['X-Var-3'] == 'false', 'POST variables 3' 112 113 114def test_java_application_session(): 115 client.load('session') 116 117 headers = client.get(url='/?var1=val1')['headers'] 118 session_id = headers['X-Session-Id'] 119 120 assert headers['X-Var-1'] == 'null', 'variable empty' 121 assert headers['X-Session-New'] == 'true', 'session create' 122 123 headers = client.get( 124 headers={ 125 'Host': 'localhost', 126 'Cookie': f'JSESSIONID={session_id}', 127 'Connection': 'close', 128 }, 129 url='/?var1=val2', 130 )['headers'] 131 132 assert headers['X-Var-1'] == 'val1', 'variable' 133 assert headers['X-Session-New'] == 'false', 'session resume' 134 assert session_id == headers['X-Session-Id'], 'session same id' 135 136 137def test_java_application_session_active(date_to_sec_epoch, sec_epoch): 138 client.load('session_inactive') 139 140 resp = client.get( 141 headers={ 142 'X-Interval': '4', 143 'Host': 'localhost', 144 'Connection': 'close', 145 } 146 ) 147 session_id = resp['headers']['X-Session-Id'] 148 149 assert resp['status'] == 200, 'session init' 150 assert resp['headers']['X-Session-Interval'] == '4', 'session interval' 151 assert ( 152 abs( 153 date_to_sec_epoch(resp['headers']['X-Session-Last-Access-Time']) 154 - sec_epoch 155 ) 156 < 5 157 ), 'session last access time' 158 159 time.sleep(1) 160 161 resp = client.get( 162 headers={ 163 'Host': 'localhost', 164 'Cookie': f'JSESSIONID={session_id}', 165 'Connection': 'close', 166 } 167 ) 168 169 assert resp['headers']['X-Session-Id'] == session_id, 'session active' 170 171 session_id = resp['headers']['X-Session-Id'] 172 173 time.sleep(1) 174 175 resp = client.get( 176 headers={ 177 'Host': 'localhost', 178 'Cookie': f'JSESSIONID={session_id}', 179 'Connection': 'close', 180 } 181 ) 182 183 assert resp['headers']['X-Session-Id'] == session_id, 'session active 2' 184 185 time.sleep(2) 186 187 resp = client.get( 188 headers={ 189 'Host': 'localhost', 190 'Cookie': f'JSESSIONID={session_id}', 191 'Connection': 'close', 192 } 193 ) 194 195 assert resp['headers']['X-Session-Id'] == session_id, 'session active 3' 196 197 198def test_java_application_session_inactive(): 199 client.load('session_inactive') 200 201 resp = client.get( 202 headers={ 203 'X-Interval': '1', 204 'Host': 'localhost', 205 'Connection': 'close', 206 } 207 ) 208 session_id = resp['headers']['X-Session-Id'] 209 210 time.sleep(3) 211 212 resp = client.get( 213 headers={ 214 'Host': 'localhost', 215 'Cookie': f'JSESSIONID={session_id}', 216 'Connection': 'close', 217 } 218 ) 219 220 assert resp['headers']['X-Session-Id'] != session_id, 'session inactive' 221 222 223def test_java_application_session_invalidate(): 224 client.load('session_invalidate') 225 226 resp = client.get() 227 session_id = resp['headers']['X-Session-Id'] 228 229 resp = client.get( 230 headers={ 231 'Host': 'localhost', 232 'Cookie': f'JSESSIONID={session_id}', 233 'Connection': 'close', 234 } 235 ) 236 237 assert resp['headers']['X-Session-Id'] != session_id, 'session invalidate' 238 239 240def test_java_application_session_listeners(): 241 client.load('session_listeners') 242 243 headers = client.get(url='/test?var1=val1')['headers'] 244 session_id = headers['X-Session-Id'] 245 246 assert headers['X-Session-Created'] == session_id, 'session create' 247 assert headers['X-Attr-Added'] == 'var1=val1', 'attribute add' 248 249 headers = client.get( 250 headers={ 251 'Host': 'localhost', 252 'Cookie': f'JSESSIONID={session_id}', 253 'Connection': 'close', 254 }, 255 url='/?var1=val2', 256 )['headers'] 257 258 assert session_id == headers['X-Session-Id'], 'session same id' 259 assert headers['X-Attr-Replaced'] == 'var1=val1', 'attribute replace' 260 261 headers = client.get( 262 headers={ 263 'Host': 'localhost', 264 'Cookie': f'JSESSIONID={session_id}', 265 'Connection': 'close', 266 }, 267 url='/', 268 )['headers'] 269 270 assert session_id == headers['X-Session-Id'], 'session same id' 271 assert headers['X-Attr-Removed'] == 'var1=val2', 'attribute remove' 272 273 274def test_java_application_jsp(): 275 client.load('jsp') 276 277 headers = client.get(url='/index.jsp')['headers'] 278 279 assert headers['X-Unit-JSP'] == 'ok', 'JSP Ok header' 280 281 282def test_java_application_url_pattern(): 283 client.load('url_pattern') 284 285 headers = client.get(url='/foo/bar/index.html')['headers'] 286 287 assert headers['X-Id'] == 'servlet1', '#1 Servlet1 request' 288 assert headers['X-Request-URI'] == '/foo/bar/index.html', '#1 request URI' 289 assert headers['X-Servlet-Path'] == '/foo/bar', '#1 servlet path' 290 assert headers['X-Path-Info'] == '/index.html', '#1 path info' 291 292 headers = client.get(url='/foo/bar/index.bop')['headers'] 293 294 assert headers['X-Id'] == 'servlet1', '#2 Servlet1 request' 295 assert headers['X-Request-URI'] == '/foo/bar/index.bop', '#2 request URI' 296 assert headers['X-Servlet-Path'] == '/foo/bar', '#2 servlet path' 297 assert headers['X-Path-Info'] == '/index.bop', '#2 path info' 298 299 headers = client.get(url='/baz')['headers'] 300 301 assert headers['X-Id'] == 'servlet2', '#3 Servlet2 request' 302 assert headers['X-Request-URI'] == '/baz', '#3 request URI' 303 assert headers['X-Servlet-Path'] == '/baz', '#3 servlet path' 304 assert headers['X-Path-Info'] == 'null', '#3 path info' 305 306 headers = client.get(url='/baz/index.html')['headers'] 307 308 assert headers['X-Id'] == 'servlet2', '#4 Servlet2 request' 309 assert headers['X-Request-URI'] == '/baz/index.html', '#4 request URI' 310 assert headers['X-Servlet-Path'] == '/baz', '#4 servlet path' 311 assert headers['X-Path-Info'] == '/index.html', '#4 path info' 312 313 headers = client.get(url='/catalog')['headers'] 314 315 assert headers['X-Id'] == 'servlet3', '#5 Servlet3 request' 316 assert headers['X-Request-URI'] == '/catalog', '#5 request URI' 317 assert headers['X-Servlet-Path'] == '/catalog', '#5 servlet path' 318 assert headers['X-Path-Info'] == 'null', '#5 path info' 319 320 headers = client.get(url='/catalog/index.html')['headers'] 321 322 assert headers['X-Id'] == 'default', '#6 default request' 323 assert headers['X-Request-URI'] == '/catalog/index.html', '#6 request URI' 324 assert headers['X-Servlet-Path'] == '/catalog/index.html', '#6 servlet path' 325 assert headers['X-Path-Info'] == 'null', '#6 path info' 326 327 headers = client.get(url='/catalog/racecar.bop')['headers'] 328 329 assert headers['X-Id'] == 'servlet4', '#7 servlet4 request' 330 assert headers['X-Request-URI'] == '/catalog/racecar.bop', '#7 request URI' 331 assert ( 332 headers['X-Servlet-Path'] == '/catalog/racecar.bop' 333 ), '#7 servlet path' 334 assert headers['X-Path-Info'] == 'null', '#7 path info' 335 336 headers = client.get(url='/index.bop')['headers'] 337 338 assert headers['X-Id'] == 'servlet4', '#8 servlet4 request' 339 assert headers['X-Request-URI'] == '/index.bop', '#8 request URI' 340 assert headers['X-Servlet-Path'] == '/index.bop', '#8 servlet path' 341 assert headers['X-Path-Info'] == 'null', '#8 path info' 342 343 headers = client.get(url='/foo/baz')['headers'] 344 345 assert headers['X-Id'] == 'servlet0', '#9 servlet0 request' 346 assert headers['X-Request-URI'] == '/foo/baz', '#9 request URI' 347 assert headers['X-Servlet-Path'] == '/foo', '#9 servlet path' 348 assert headers['X-Path-Info'] == '/baz', '#9 path info' 349 350 headers = client.get()['headers'] 351 352 assert headers['X-Id'] == 'default', '#10 default request' 353 assert headers['X-Request-URI'] == '/', '#10 request URI' 354 assert headers['X-Servlet-Path'] == '/', '#10 servlet path' 355 assert headers['X-Path-Info'] == 'null', '#10 path info' 356 357 headers = client.get(url='/index.bop/')['headers'] 358 359 assert headers['X-Id'] == 'default', '#11 default request' 360 assert headers['X-Request-URI'] == '/index.bop/', '#11 request URI' 361 assert headers['X-Servlet-Path'] == '/index.bop/', '#11 servlet path' 362 assert headers['X-Path-Info'] == 'null', '#11 path info' 363 364 365def test_java_application_header(): 366 client.load('header') 367 368 headers = client.get()['headers'] 369 370 assert headers['X-Set-Utf8-Value'] == '????', 'set Utf8 header value' 371 assert headers['X-Set-Utf8-Name-???'] == 'x', 'set Utf8 header name' 372 assert headers['X-Add-Utf8-Value'] == '????', 'add Utf8 header value' 373 assert headers['X-Add-Utf8-Name-???'] == 'y', 'add Utf8 header name' 374 assert headers['X-Add-Test'] == 'v1', 'add null header' 375 assert 'X-Set-Test1' not in headers, 'set null header' 376 assert headers['X-Set-Test2'] == '', 'set empty header' 377 378 379def test_java_application_content_type(): 380 client.load('content_type') 381 382 headers = client.get(url='/1')['headers'] 383 384 assert ( 385 headers['Content-Type'] == 'text/plain;charset=utf-8' 386 ), '#1 Content-Type header' 387 assert ( 388 headers['X-Content-Type'] == 'text/plain;charset=utf-8' 389 ), '#1 response Content-Type' 390 assert headers['X-Character-Encoding'] == 'utf-8', '#1 response charset' 391 392 headers = client.get(url='/2')['headers'] 393 394 assert ( 395 headers['Content-Type'] == 'text/plain;charset=iso-8859-1' 396 ), '#2 Content-Type header' 397 assert ( 398 headers['X-Content-Type'] == 'text/plain;charset=iso-8859-1' 399 ), '#2 response Content-Type' 400 assert ( 401 headers['X-Character-Encoding'] == 'iso-8859-1' 402 ), '#2 response charset' 403 404 headers = client.get(url='/3')['headers'] 405 406 assert ( 407 headers['Content-Type'] == 'text/plain;charset=windows-1251' 408 ), '#3 Content-Type header' 409 assert ( 410 headers['X-Content-Type'] == 'text/plain;charset=windows-1251' 411 ), '#3 response Content-Type' 412 assert ( 413 headers['X-Character-Encoding'] == 'windows-1251' 414 ), '#3 response charset' 415 416 headers = client.get(url='/4')['headers'] 417 418 assert ( 419 headers['Content-Type'] == 'text/plain;charset=windows-1251' 420 ), '#4 Content-Type header' 421 assert ( 422 headers['X-Content-Type'] == 'text/plain;charset=windows-1251' 423 ), '#4 response Content-Type' 424 assert ( 425 headers['X-Character-Encoding'] == 'windows-1251' 426 ), '#4 response charset' 427 428 headers = client.get(url='/5')['headers'] 429 430 assert ( 431 headers['Content-Type'] == 'text/plain;charset=iso-8859-1' 432 ), '#5 Content-Type header' 433 assert ( 434 headers['X-Content-Type'] == 'text/plain;charset=iso-8859-1' 435 ), '#5 response Content-Type' 436 assert ( 437 headers['X-Character-Encoding'] == 'iso-8859-1' 438 ), '#5 response charset' 439 440 headers = client.get(url='/6')['headers'] 441 442 assert 'Content-Type' not in headers, '#6 no Content-Type header' 443 assert 'X-Content-Type' not in headers, '#6 no response Content-Type' 444 assert headers['X-Character-Encoding'] == 'utf-8', '#6 response charset' 445 446 headers = client.get(url='/7')['headers'] 447 448 assert ( 449 headers['Content-Type'] == 'text/plain;charset=utf-8' 450 ), '#7 Content-Type header' 451 assert ( 452 headers['X-Content-Type'] == 'text/plain;charset=utf-8' 453 ), '#7 response Content-Type' 454 assert headers['X-Character-Encoding'] == 'utf-8', '#7 response charset' 455 456 headers = client.get(url='/8')['headers'] 457 458 assert ( 459 headers['Content-Type'] == 'text/html;charset=utf-8' 460 ), '#8 Content-Type header' 461 assert ( 462 headers['X-Content-Type'] == 'text/html;charset=utf-8' 463 ), '#8 response Content-Type' 464 assert headers['X-Character-Encoding'] == 'utf-8', '#8 response charset' 465 466 467def test_java_application_welcome_files(): 468 client.load('welcome_files') 469 470 headers = client.get()['headers'] 471 472 resp = client.get(url='/dir1') 473 474 assert resp['status'] == 302, 'dir redirect expected' 475 476 resp = client.get(url='/dir1/') 477 478 assert 'This is index.txt.' in resp['body'], 'dir1 index body' 479 assert resp['headers']['X-TXT-Filter'] == '1', 'TXT Filter header' 480 481 headers = client.get(url='/dir2/')['headers'] 482 483 assert headers['X-Unit-JSP'] == 'ok', 'JSP Ok header' 484 assert headers['X-JSP-Filter'] == '1', 'JSP Filter header' 485 486 headers = client.get(url='/dir3/')['headers'] 487 488 assert headers['X-App-Servlet'] == '1', 'URL pattern overrides welcome file' 489 490 headers = client.get(url='/dir4/')['headers'] 491 492 assert 'X-App-Servlet' not in headers, 'Static welcome file served first' 493 494 headers = client.get(url='/dir5/')['headers'] 495 496 assert ( 497 headers['X-App-Servlet'] == '1' 498 ), 'Servlet for welcome file served when no static file found' 499 500 501def test_java_application_request_listeners(): 502 client.load('request_listeners') 503 504 headers = client.get(url='/test1')['headers'] 505 506 assert ( 507 headers['X-Request-Initialized'] == '/test1' 508 ), 'request initialized event' 509 assert headers['X-Request-Destroyed'] == '', 'request destroyed event' 510 assert headers['X-Attr-Added'] == '', 'attribute added event' 511 assert headers['X-Attr-Removed'] == '', 'attribute removed event' 512 assert headers['X-Attr-Replaced'] == '', 'attribute replaced event' 513 514 headers = client.get(url='/test2?var1=1')['headers'] 515 516 assert ( 517 headers['X-Request-Initialized'] == '/test2' 518 ), 'request initialized event' 519 assert headers['X-Request-Destroyed'] == '/test1', 'request destroyed event' 520 assert headers['X-Attr-Added'] == 'var=1;', 'attribute added event' 521 assert headers['X-Attr-Removed'] == 'var=1;', 'attribute removed event' 522 assert headers['X-Attr-Replaced'] == '', 'attribute replaced event' 523 524 headers = client.get(url='/test3?var1=1&var2=2')['headers'] 525 526 assert ( 527 headers['X-Request-Initialized'] == '/test3' 528 ), 'request initialized event' 529 assert headers['X-Request-Destroyed'] == '/test2', 'request destroyed event' 530 assert headers['X-Attr-Added'] == 'var=1;', 'attribute added event' 531 assert headers['X-Attr-Removed'] == 'var=2;', 'attribute removed event' 532 assert headers['X-Attr-Replaced'] == 'var=1;', 'attribute replaced event' 533 534 headers = client.get(url='/test4?var1=1&var2=2&var3=3')['headers'] 535 536 assert ( 537 headers['X-Request-Initialized'] == '/test4' 538 ), 'request initialized event' 539 assert headers['X-Request-Destroyed'] == '/test3', 'request destroyed event' 540 assert headers['X-Attr-Added'] == 'var=1;', 'attribute added event' 541 assert headers['X-Attr-Removed'] == '', 'attribute removed event' 542 assert ( 543 headers['X-Attr-Replaced'] == 'var=1;var=2;' 544 ), 'attribute replaced event' 545 546 547def test_java_application_request_uri_forward(): 548 client.load('forward') 549 550 resp = client.get( 551 url='/fwd?uri=%2Fdata%2Ftest%3Furi%3Dnew_uri%26a%3D2%26b%3D3&a=1&c=4' 552 ) 553 headers = resp['headers'] 554 555 assert headers['X-REQUEST-Id'] == 'fwd', 'initial request servlet mapping' 556 assert ( 557 headers['X-Forward-To'] == '/data/test?uri=new_uri&a=2&b=3' 558 ), 'forwarding triggered' 559 assert ( 560 headers['X-REQUEST-Param-uri'] == '/data/test?uri=new_uri&a=2&b=3' 561 ), 'original uri parameter' 562 assert headers['X-REQUEST-Param-a'] == '1', 'original a parameter' 563 assert headers['X-REQUEST-Param-c'] == '4', 'original c parameter' 564 565 assert headers['X-FORWARD-Id'] == 'data', 'forward request servlet mapping' 566 assert ( 567 headers['X-FORWARD-Request-URI'] == '/data/test' 568 ), 'forward request uri' 569 assert ( 570 headers['X-FORWARD-Servlet-Path'] == '/data' 571 ), 'forward request servlet path' 572 assert ( 573 headers['X-FORWARD-Path-Info'] == '/test' 574 ), 'forward request path info' 575 assert ( 576 headers['X-FORWARD-Query-String'] == 'uri=new_uri&a=2&b=3' 577 ), 'forward request query string' 578 assert ( 579 headers['X-FORWARD-Param-uri'] 580 == 'new_uri,/data/test?uri=new_uri&a=2&b=3' 581 ), 'forward uri parameter' 582 assert headers['X-FORWARD-Param-a'] == '2,1', 'forward a parameter' 583 assert headers['X-FORWARD-Param-b'] == '3', 'forward b parameter' 584 assert headers['X-FORWARD-Param-c'] == '4', 'forward c parameter' 585 586 assert ( 587 headers['X-javax.servlet.forward.request_uri'] == '/fwd' 588 ), 'original request uri' 589 assert ( 590 headers['X-javax.servlet.forward.context_path'] == '' 591 ), 'original request context path' 592 assert ( 593 headers['X-javax.servlet.forward.servlet_path'] == '/fwd' 594 ), 'original request servlet path' 595 assert ( 596 headers['X-javax.servlet.forward.path_info'] == 'null' 597 ), 'original request path info' 598 assert ( 599 headers['X-javax.servlet.forward.query_string'] 600 == 'uri=%2Fdata%2Ftest%3Furi%3Dnew_uri%26a%3D2%26b%3D3&a=1&c=4' 601 ), 'original request query' 602 603 assert ( 604 'Before forwarding' not in resp['body'] 605 ), 'discarded data added before forward() call' 606 assert ( 607 'X-After-Forwarding' not in headers 608 ), 'cannot add headers after forward() call' 609 assert ( 610 'After forwarding' not in resp['body'] 611 ), 'cannot add data after forward() call' 612 613 614def test_java_application_named_dispatcher_forward(): 615 client.load('forward') 616 617 resp = client.get(url='/fwd?disp=name&uri=data') 618 headers = resp['headers'] 619 620 assert headers['X-REQUEST-Id'] == 'fwd', 'initial request servlet mapping' 621 assert headers['X-Forward-To'] == 'data', 'forwarding triggered' 622 623 assert headers['X-FORWARD-Id'] == 'data', 'forward request servlet mapping' 624 assert headers['X-FORWARD-Request-URI'] == '/fwd', 'forward request uri' 625 assert ( 626 headers['X-FORWARD-Servlet-Path'] == '/fwd' 627 ), 'forward request servlet path' 628 assert headers['X-FORWARD-Path-Info'] == 'null', 'forward request path info' 629 assert ( 630 headers['X-FORWARD-Query-String'] == 'disp=name&uri=data' 631 ), 'forward request query string' 632 633 assert ( 634 headers['X-javax.servlet.forward.request_uri'] == 'null' 635 ), 'original request uri' 636 assert ( 637 headers['X-javax.servlet.forward.context_path'] == 'null' 638 ), 'original request context path' 639 assert ( 640 headers['X-javax.servlet.forward.servlet_path'] == 'null' 641 ), 'original request servlet path' 642 assert ( 643 headers['X-javax.servlet.forward.path_info'] == 'null' 644 ), 'original request path info' 645 assert ( 646 headers['X-javax.servlet.forward.query_string'] == 'null' 647 ), 'original request query' 648 649 assert ( 650 'Before forwarding' not in resp['body'] 651 ), 'discarded data added before forward() call' 652 assert ( 653 'X-After-Forwarding' not in headers 654 ), 'cannot add headers after forward() call' 655 assert ( 656 'After forwarding' not in resp['body'] 657 ), 'cannot add data after forward() call' 658 659 660def test_java_application_request_uri_include(): 661 client.load('include') 662 663 resp = client.get(url='/inc?uri=/data/test') 664 headers = resp['headers'] 665 body = resp['body'] 666 667 assert headers['X-REQUEST-Id'] == 'inc', 'initial request servlet mapping' 668 assert headers['X-Include'] == '/data/test', 'including triggered' 669 670 assert ( 671 'X-INCLUDE-Id' not in headers 672 ), 'unable to add headers in include request' 673 674 assert ( 675 'javax.servlet.include.request_uri: /data/test' in body 676 ), 'include request uri' 677 # assert ( 678 # 'javax.servlet.include.context_path: ' in body 679 # ) == True, 'include request context path' 680 assert ( 681 'javax.servlet.include.servlet_path: /data' in body 682 ), 'include request servlet path' 683 assert ( 684 'javax.servlet.include.path_info: /test' in body 685 ), 'include request path info' 686 assert ( 687 'javax.servlet.include.query_string: null' in body 688 ), 'include request query' 689 690 assert 'Before include' in body, 'preserve data added before include() call' 691 assert ( 692 headers['X-After-Include'] == 'you-should-see-this' 693 ), 'add headers after include() call' 694 assert 'After include' in body, 'add data after include() call' 695 696 697def test_java_application_named_dispatcher_include(): 698 client.load('include') 699 700 resp = client.get(url='/inc?disp=name&uri=data') 701 headers = resp['headers'] 702 body = resp['body'] 703 704 assert headers['X-REQUEST-Id'] == 'inc', 'initial request servlet mapping' 705 assert headers['X-Include'] == 'data', 'including triggered' 706 707 assert ( 708 'X-INCLUDE-Id' not in headers 709 ), 'unable to add headers in include request' 710 711 assert ( 712 'javax.servlet.include.request_uri: null' in body 713 ), 'include request uri' 714 # assert ( 715 # 'javax.servlet.include.context_path: null' in body 716 # ) == True, 'include request context path' 717 assert ( 718 'javax.servlet.include.servlet_path: null' in body 719 ), 'include request servlet path' 720 assert ( 721 'javax.servlet.include.path_info: null' in body 722 ), 'include request path info' 723 assert ( 724 'javax.servlet.include.query_string: null' in body 725 ), 'include request query' 726 727 assert 'Before include' in body, 'preserve data added before include() call' 728 assert ( 729 headers['X-After-Include'] == 'you-should-see-this' 730 ), 'add headers after include() call' 731 assert 'After include' in body, 'add data after include() call' 732 733 734def test_java_application_path_translation(): 735 client.load('path_translation') 736 737 headers = client.get(url='/pt/test?path=/')['headers'] 738 739 assert headers['X-Servlet-Path'] == '/pt', 'matched servlet path' 740 assert headers['X-Path-Info'] == '/test', 'the rest of the path' 741 assert ( 742 headers['X-Path-Translated'] 743 == f"{headers['X-Real-Path']}{headers['X-Path-Info']}" 744 ), 'translated path is the app root + path info' 745 assert headers['X-Resource-Paths'].endswith( 746 '/WEB-INF/, /index.html]' 747 ), 'app root directory content' 748 assert ( 749 headers['X-Resource-As-Stream'] == 'null' 750 ), 'no resource stream for root path' 751 752 headers = client.get(url='/test?path=/none')['headers'] 753 754 assert headers['X-Servlet-Path'] == '/test', 'matched whole path' 755 assert ( 756 headers['X-Path-Info'] == 'null' 757 ), 'the rest of the path is null, whole path matched' 758 assert ( 759 headers['X-Path-Translated'] == 'null' 760 ), 'translated path is null because path info is null' 761 assert headers['X-Real-Path'].endswith('/none'), 'read path is not null' 762 assert headers['X-Resource-Paths'] == 'null', 'no resource found' 763 assert headers['X-Resource-As-Stream'] == 'null', 'no resource stream' 764 765 766def test_java_application_query_string(): 767 client.load('query_string') 768 769 assert ( 770 client.get(url='/?a=b')['headers']['X-Query-String'] == 'a=b' 771 ), 'query string' 772 773 774def test_java_application_query_empty(): 775 client.load('query_string') 776 777 assert ( 778 client.get(url='/?')['headers']['X-Query-String'] == '' 779 ), 'query string empty' 780 781 782def test_java_application_query_absent(): 783 client.load('query_string') 784 785 assert ( 786 client.get()['headers']['X-Query-String'] == 'null' 787 ), 'query string absent' 788 789 790def test_java_application_empty(): 791 client.load('empty') 792 793 assert client.get()['status'] == 200, 'empty' 794 795 796def test_java_application_keepalive_body(): 797 client.load('mirror') 798 799 assert client.post()['status'] == 200, 'init' 800 801 body = '0123456789' * 500 802 (resp, sock) = client.post( 803 headers={ 804 'Connection': 'keep-alive', 805 'Content-Type': 'text/html', 806 'Host': 'localhost', 807 }, 808 start=True, 809 body=body, 810 read_timeout=1, 811 ) 812 813 assert resp['body'] == body, 'keep-alive 1' 814 815 body = '0123456789' 816 resp = client.post( 817 headers={ 818 'Connection': 'close', 819 'Content-Type': 'text/html', 820 'Host': 'localhost', 821 }, 822 sock=sock, 823 body=body, 824 ) 825 826 assert resp['body'] == body, 'keep-alive 2' 827 828 829def test_java_application_http_10(): 830 client.load('empty') 831 832 assert client.get(http_10=True)['status'] == 200, 'HTTP 1.0' 833 834 835def test_java_application_no_method(): 836 client.load('empty') 837 838 assert client.post()['status'] == 405, 'no method' 839 840 841def test_java_application_get_header(): 842 client.load('get_header') 843 844 assert ( 845 client.get( 846 headers={ 847 'X-Header': 'blah', 848 'Content-Type': 'text/html', 849 'Host': 'localhost', 850 'Connection': 'close', 851 } 852 )['headers']['X-Reply'] 853 == 'blah' 854 ), 'get header' 855 856 857def test_java_application_get_header_empty(): 858 client.load('get_header') 859 860 assert 'X-Reply' not in client.get()['headers'], 'get header empty' 861 862 863def test_java_application_get_headers(): 864 client.load('get_headers') 865 866 headers = client.get( 867 headers={ 868 'X-Header': ['blah', 'blah'], 869 'Content-Type': 'text/html', 870 'Host': 'localhost', 871 'Connection': 'close', 872 } 873 )['headers'] 874 875 assert headers['X-Reply-0'] == 'blah', 'get headers' 876 assert headers['X-Reply-1'] == 'blah', 'get headers 2' 877 878 879def test_java_application_many_headers(): 880 client.load('get_headers') 881 882 value = '0123456789' * 10 883 884 headers = client.get( 885 headers={ 886 'X-Header': [value] * 100, 887 'Content-Type': 'text/html', 888 'Host': 'localhost', 889 'Connection': 'close', 890 } 891 )['headers'] 892 893 for i in range(0, 99): 894 assert headers[f'X-Reply-{i}'] == value, 'many headers' 895 896 897def test_java_application_get_headers_empty(): 898 client.load('get_headers') 899 900 assert 'X-Reply-0' not in client.get()['headers'], 'get headers empty' 901 902 903def test_java_application_get_header_names(): 904 client.load('get_header_names') 905 906 headers = client.get()['headers'] 907 908 assert re.search( 909 r'(?:Host|Connection)', headers['X-Reply-0'] 910 ), 'get header names' 911 assert re.search( 912 r'(?:Host|Connection)', headers['X-Reply-1'] 913 ), 'get header names 2' 914 assert ( 915 headers['X-Reply-0'] != headers['X-Reply-1'] 916 ), 'get header names not equal' 917 918 919def test_java_application_header_int(): 920 client.load('header_int') 921 922 headers = client.get( 923 headers={ 924 'X-Header': '2', 925 'Content-Type': 'text/html', 926 'Host': 'localhost', 927 'Connection': 'close', 928 } 929 )['headers'] 930 931 assert headers['X-Set-Int'] == '1', 'set int header' 932 assert headers['X-Get-Int'] == '2', 'get int header' 933 934 935def test_java_application_header_date(): 936 client.load('header_date') 937 938 date = 'Fri, 15 Mar 2019 14:45:34 GMT' 939 940 headers = client.get( 941 headers={ 942 'X-Header': date, 943 'Content-Type': 'text/html', 944 'Host': 'localhost', 945 'Connection': 'close', 946 } 947 )['headers'] 948 949 assert ( 950 headers['X-Set-Date'] == 'Thu, 01 Jan 1970 00:00:01 GMT' 951 ), 'set date header' 952 assert headers['X-Get-Date'] == date, 'get date header' 953 954 955def test_java_application_multipart(search_in_file, temp_dir): 956 client.load('multipart') 957 958 reldst = '/uploads' 959 fulldst = f'{temp_dir}{reldst}' 960 Path(fulldst).mkdir(parents=True) 961 public_dir(fulldst) 962 963 fields = { 964 'file': { 965 'filename': 'sample.txt', 966 'type': 'text/plain', 967 'data': io.StringIO('Data from sample file'), 968 }, 969 'destination': fulldst, 970 'upload': 'Upload', 971 } 972 973 encoded, content_type = client.multipart_encode(fields) 974 975 preamble = 'Preamble. Should be ignored.' 976 epilogue = 'Epilogue. Should be ignored.' 977 body = f'{preamble}\r\n{encoded.decode()}\r\n{epilogue}' 978 979 resp = client.post( 980 headers={ 981 'Content-Type': content_type, 982 'Host': 'localhost', 983 'Connection': 'close', 984 }, 985 body=body, 986 ) 987 988 assert resp['status'] == 200, 'multipart status' 989 assert re.search(r'sample\.txt created', resp['body']), 'multipart body' 990 assert ( 991 search_in_file(r'^Data from sample file$', name=f'{reldst}/sample.txt') 992 is not None 993 ), 'file created' 994 995 996def test_java_application_threads(): 997 client.load('threads') 998 999 assert 'success' in client.conf( 1000 '4', 'applications/threads/threads' 1001 ), 'configure 4 threads' 1002 1003 socks = [] 1004 1005 for _ in range(4): 1006 sock = client.get( 1007 headers={ 1008 'Host': 'localhost', 1009 'X-Delay': '2', 1010 'Connection': 'close', 1011 }, 1012 no_recv=True, 1013 ) 1014 1015 socks.append(sock) 1016 1017 time.sleep(0.25) # required to avoid greedy request reading 1018 1019 threads = set() 1020 1021 for sock in socks: 1022 resp = client.recvall(sock).decode('utf-8') 1023 1024 client.log_in(resp) 1025 1026 resp = client._resp_to_dict(resp) 1027 1028 assert resp['status'] == 200, 'status' 1029 1030 threads.add(resp['headers']['X-Thread']) 1031 1032 sock.close() 1033 1034 assert len(socks) == len(threads), 'threads differs' 1035