18
18
19
19
from roundup .anypy .cgi_ import cgi
20
20
from roundup .cgi import client , actions , exceptions
21
- from roundup .cgi .exceptions import FormError , NotFound , Redirect
21
+ from roundup .cgi .exceptions import FormError , NotFound , Redirect , NotModified
22
22
from roundup .exceptions import UsageError , Reject
23
23
from roundup .cgi .templating import HTMLItem , HTMLRequest , NoTemplate
24
24
from roundup .cgi .templating import HTMLProperty , _HTMLItem , anti_csrf_nonce
@@ -1942,6 +1942,7 @@ def _make_client(self, form, classname='user', nodeid='1',
1942
1942
if nodeid is not None :
1943
1943
cl .nodeid = nodeid
1944
1944
cl .db = self .db
1945
+ cl .request = MockNull ()
1945
1946
cl .db .Otk = cl .db .getOTKManager ()
1946
1947
#cl.db.Otk = MockNull()
1947
1948
#cl.db.Otk.data = {}
@@ -2382,6 +2383,83 @@ def testRegisterActionUnusedUserCheck(self):
2382
2383
if os .path .exists (SENDMAILDEBUG ):
2383
2384
os .remove (SENDMAILDEBUG )
2384
2385
2386
+ def testserve_static_files_cache_headers (self ):
2387
+ """Note for headers the real headers class is case
2388
+ insensitive.
2389
+ """
2390
+ # make a client instance
2391
+ cl = self ._make_client ({})
2392
+ # Make local copy in cl to not modify value in class
2393
+ cl .Cache_Control = copy .copy (cl .Cache_Control )
2394
+
2395
+ # TEMPLATES dir is searched by default. So this file exists.
2396
+ # Check the returned values.
2397
+ cl .serve_static_file ("style.css" )
2398
+
2399
+ # gather the conditional request headers from the 200 response
2400
+ inm = cl .additional_headers ['ETag' ]
2401
+ ims = cl .additional_headers ['Last-Modified' ]
2402
+
2403
+
2404
+ # loop over all header value possibilities that will
2405
+ # result in not modified.
2406
+ for headers in [
2407
+ {'if-none-match' : inm },
2408
+ {'if-modified-since' : ims },
2409
+ {'if-none-match' : inm , 'if-modified-since' : ims },
2410
+ {'if-none-match' : inm , 'if-modified-since' : "fake" },
2411
+ {'if-none-match' : "fake" , 'if-modified-since' : ims },
2412
+ ]:
2413
+ print (headers )
2414
+
2415
+ # Request same file with if-modified-since header
2416
+ # expect NotModified with same ETag and Last-Modified headers.
2417
+ cl .request .headers = headers
2418
+ cl .response_code = None
2419
+ cl .additional_headers = {}
2420
+
2421
+ with self .assertRaises (NotModified ) as cm :
2422
+ cl .serve_static_file ("style.css" )
2423
+
2424
+ self .assertEqual (cm .exception .args , ())
2425
+
2426
+ self .assertEqual (cl .response_code , None )
2427
+ self .assertEqual (cl .additional_headers ['ETag' ], inm )
2428
+ self .assertEqual (cl .additional_headers ['Last-Modified' ], ims )
2429
+
2430
+
2431
+ ## run two cases that should not return NotModified
2432
+ for headers in [
2433
+ {},
2434
+ {'if-none-match' : "fake" , 'if-modified-since' : "fake" },
2435
+ ]:
2436
+ cl .request .headers = headers
2437
+ cl .response_code = None
2438
+ cl .additional_headers = {}
2439
+
2440
+ cl .serve_static_file ("style.css" )
2441
+
2442
+ self .assertEqual (cl .response_code , None )
2443
+ self .assertEqual (cl .additional_headers ['ETag' ], inm )
2444
+ self .assertEqual (cl .additional_headers ['Last-Modified' ], ims )
2445
+
2446
+ ## test pure cgi case
2447
+ # headers attribute does not exist
2448
+ cl .request = None
2449
+ cl .response_code = None
2450
+ cl .additional_headers = {}
2451
+
2452
+ cl .env ["HTTP_IF_MODIFIED_SINCE" ] = ims
2453
+
2454
+ with self .assertRaises (NotModified ) as cm :
2455
+ cl .serve_static_file ("style.css" )
2456
+
2457
+ self .assertEqual (cm .exception .args , ())
2458
+
2459
+ self .assertEqual (cl .response_code , None )
2460
+ self .assertEqual (cl .additional_headers ['ETag' ], inm )
2461
+ self .assertEqual (cl .additional_headers ['Last-Modified' ], ims )
2462
+
2385
2463
def testserve_static_files (self ):
2386
2464
# make a client instance
2387
2465
cl = self ._make_client ({})
@@ -2390,8 +2468,8 @@ def testserve_static_files(self):
2390
2468
2391
2469
# hijack _serve_file so I can see what is found
2392
2470
output = []
2393
- def my_serve_file (a , b , c , d ):
2394
- output .append ((a ,b ,c ,d ))
2471
+ def my_serve_file (a , b , c , d , e ):
2472
+ output .append ((a ,b ,c ,d , e ))
2395
2473
cl ._serve_file = my_serve_file
2396
2474
2397
2475
# check case where file is not found.
@@ -2401,8 +2479,9 @@ def my_serve_file(a, b, c, d):
2401
2479
# TEMPLATES dir is searched by default. So this file exists.
2402
2480
# Check the returned values.
2403
2481
cl .serve_static_file ("issue.index.html" )
2404
- self .assertEqual (output [0 ][1 ], "text/html" )
2405
- self .assertEqual (output [0 ][3 ],
2482
+ print (output )
2483
+ self .assertEqual (output [0 ][2 ], "text/html" )
2484
+ self .assertEqual (output [0 ][4 ],
2406
2485
normpath ('_test_cgi_form/html/issue.index.html' ))
2407
2486
del output [0 ] # reset output buffer
2408
2487
@@ -2415,8 +2494,8 @@ def my_serve_file(a, b, c, d):
2415
2494
# explicitly allow html directory
2416
2495
cl .instance .config ['STATIC_FILES' ] = 'html -'
2417
2496
cl .serve_static_file ("issue.index.html" )
2418
- self .assertEqual (output [0 ][1 ], "text/html" )
2419
- self .assertEqual (output [0 ][3 ],
2497
+ self .assertEqual (output [0 ][2 ], "text/html" )
2498
+ self .assertEqual (output [0 ][4 ],
2420
2499
normpath ('_test_cgi_form/html/issue.index.html' ))
2421
2500
del output [0 ] # reset output buffer
2422
2501
@@ -2425,15 +2504,15 @@ def my_serve_file(a, b, c, d):
2425
2504
2426
2505
# find file in first directory
2427
2506
cl .serve_static_file ("messagesummary.py" )
2428
- self .assertEqual (output [0 ][1 ], "text/x-python" )
2429
- self .assertEqual (output [0 ][3 ],
2507
+ self .assertEqual (output [0 ][2 ], "text/x-python" )
2508
+ self .assertEqual (output [0 ][4 ],
2430
2509
normpath ( "_test_cgi_form/detectors/messagesummary.py" ))
2431
2510
del output [0 ] # reset output buffer
2432
2511
2433
2512
# find file in second directory
2434
2513
cl .serve_static_file ("README.txt" )
2435
- self .assertEqual (output [0 ][1 ], "text/plain" )
2436
- self .assertEqual (output [0 ][3 ],
2514
+ self .assertEqual (output [0 ][2 ], "text/plain" )
2515
+ self .assertEqual (output [0 ][4 ],
2437
2516
normpath ("_test_cgi_form/extensions/README.txt" ))
2438
2517
del output [0 ] # reset output buffer
2439
2518
@@ -2448,25 +2527,25 @@ def my_serve_file(a, b, c, d):
2448
2527
f = open ('_test_cgi_form/detectors/README.txt' , 'a' ).close ()
2449
2528
# find file now in first directory
2450
2529
cl .serve_static_file ("README.txt" )
2451
- self .assertEqual (output [0 ][1 ], "text/plain" )
2452
- self .assertEqual (output [0 ][3 ],
2530
+ self .assertEqual (output [0 ][2 ], "text/plain" )
2531
+ self .assertEqual (output [0 ][4 ],
2453
2532
normpath ("_test_cgi_form/detectors/README.txt" ))
2454
2533
del output [0 ] # reset output buffer
2455
2534
2456
2535
cl .instance .config ['STATIC_FILES' ] = ' detectors extensions '
2457
2536
# make sure lack of trailing - allows searching TEMPLATES
2458
2537
cl .serve_static_file ("issue.index.html" )
2459
- self .assertEqual (output [0 ][1 ], "text/html" )
2460
- self .assertEqual (output [0 ][3 ],
2538
+ self .assertEqual (output [0 ][2 ], "text/html" )
2539
+ self .assertEqual (output [0 ][4 ],
2461
2540
normpath ("_test_cgi_form/html/issue.index.html" ))
2462
2541
del output [0 ] # reset output buffer
2463
2542
2464
2543
# Make STATIC_FILES a single element.
2465
2544
cl .instance .config ['STATIC_FILES' ] = 'detectors'
2466
2545
# find file now in first directory
2467
2546
cl .serve_static_file ("messagesummary.py" )
2468
- self .assertEqual (output [0 ][1 ], "text/x-python" )
2469
- self .assertEqual (output [0 ][3 ],
2547
+ self .assertEqual (output [0 ][2 ], "text/x-python" )
2548
+ self .assertEqual (output [0 ][4 ],
2470
2549
normpath ("_test_cgi_form/detectors/messagesummary.py" ))
2471
2550
del output [0 ] # reset output buffer
2472
2551
@@ -2475,8 +2554,8 @@ def my_serve_file(a, b, c, d):
2475
2554
f = open ('_test_cgi_form/detectors/css/README.css' , 'a' ).close ()
2476
2555
# use subdir in filename
2477
2556
cl .serve_static_file ("css/README.css" )
2478
- self .assertEqual (output [0 ][1 ], "text/css" )
2479
- self .assertEqual (output [0 ][3 ],
2557
+ self .assertEqual (output [0 ][2 ], "text/css" )
2558
+ self .assertEqual (output [0 ][4 ],
2480
2559
normpath ("_test_cgi_form/detectors/css/README.css" ))
2481
2560
del output [0 ] # reset output buffer
2482
2561
@@ -2486,18 +2565,19 @@ def my_serve_file(a, b, c, d):
2486
2565
os .mkdir ('_test_cgi_form/html/css' )
2487
2566
f = open ('_test_cgi_form/html/css/README1.css' , 'a' ).close ()
2488
2567
cl .serve_static_file ("README1.css" )
2489
- self .assertEqual (output [0 ][1 ], "text/css" )
2490
- self .assertEqual (output [0 ][3 ],
2568
+ self .assertEqual (output [0 ][2 ], "text/css" )
2569
+ self .assertEqual (output [0 ][4 ],
2491
2570
normpath ("_test_cgi_form/html/css/README1.css" ))
2492
2571
self .assertTrue ( "Cache-Control" in cl .additional_headers )
2493
2572
self .assertEqual ( cl .additional_headers ,
2494
2573
{'Cache-Control' : 'public, max-age=3600' } )
2574
+ print (cl .additional_headers )
2495
2575
del output [0 ] # reset output buffer
2496
2576
2497
2577
cl .Cache_Control ['README1.css' ] = 'public, max-age=60'
2498
2578
cl .serve_static_file ("README1.css" )
2499
- self .assertEqual (output [0 ][1 ], "text/css" )
2500
- self .assertEqual (output [0 ][3 ],
2579
+ self .assertEqual (output [0 ][2 ], "text/css" )
2580
+ self .assertEqual (output [0 ][4 ],
2501
2581
normpath ("_test_cgi_form/html/css/README1.css" ))
2502
2582
self .assertTrue ( "Cache-Control" in cl .additional_headers )
2503
2583
self .assertEqual ( cl .additional_headers ,
0 commit comments