xref: /unit/test/test_java_application.py (revision 1596:b7e2d4d92624)
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