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