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