1+ import pytest
2+ import httplib as app
3+ import os
4+ import socket
5+ import types
6+
7+ @pytest .mark .asyncio
8+ async def test_normalize_path_variants ():
9+ assert await app ._normalize_path ('/' ) == 'static/index.html'
10+ assert await app ._normalize_path ('/about' ) == 'static/about.html'
11+ assert await app ._normalize_path ('/static/page.html' ) == 'static/page.html'
12+ # traversal should default to index
13+ assert await app ._normalize_path ('../etc/passwd' ) == 'static/index.html'
14+
15+ @pytest .mark .asyncio
16+ async def test_parsers ():
17+ headers = 'Host: example.com\n X-Test: value\n '
18+ parsed = await app ._parse_headers (headers )
19+ assert parsed ['Host' ] == 'example.com'
20+ assert parsed ['X-Test' ] == 'value'
21+
22+ params = await app ._parse_params ('a=1&b=two' )
23+ assert params ['a' ] == '1' and params ['b' ] == 'two'
24+
25+ cookies = await app ._parse_cookies ('a=1; b=2' )
26+ assert cookies ['a' ] == '1' and cookies ['b' ] == '2'
27+
28+ @pytest .mark .asyncio
29+ async def test_error_shorthand_and_content_type ():
30+ assert await app .get_error_shorthand (200 ) == 'OK'
31+ assert await app .get_error_shorthand (418 ) == "I'm a teapot"
32+ assert await app .get_error_shorthand (999 ) == 'Unknown Error'
33+
34+ assert await app .get_content_type ('index.html' ) == 'text/html'
35+ assert await app .get_content_type ('file.unknown' ) == 'text/plain'
36+
37+ def test_client_ip_and_request_context (monkeypatch ):
38+ # prepare request context
39+ req = app ._get_request ()
40+ req .client_ip = '1.2.3.4'
41+ assert app .get_client_ip () == '1.2.3.4'
42+ req .client_ip = ''
43+ req .headers ['X-Forwarded-For' ] = '5.6.7.8, 9.9.9.9'
44+ assert app .get_client_ip () == '5.6.7.8'
45+ req .headers .clear ()
46+
47+ def test_dos_and_blocking ():
48+ ip = '10.0.0.1'
49+ # ensure clean
50+ if ip in app .dos_ip_requests : del app .dos_ip_requests [ip ]
51+ if ip in app .dos_blocked_ips : del app .dos_blocked_ips [ip ]
52+
53+ # simulate many requests quickly to trigger block
54+ for _ in range (app .DOS_MAX_REQUESTS + 1 ):
55+ blocked = app .check_dos_protection (ip )
56+ assert app .is_ip_blocked (ip ) is True
57+ blocked_ips = app .get_blocked_ips ()
58+ assert ip in blocked_ips
59+ # unblock
60+ assert app .unblock_ip (ip ) is True
61+ assert app .is_ip_blocked (ip ) is False
62+
63+ def test_dos_stats_empty ():
64+ stats = app .get_dos_stats ()
65+ assert 'tracked_ips' in stats and 'blocked_ips' in stats
66+
67+ @pytest .mark .asyncio
68+ async def test_match_route_and_build_response ():
69+ vars = await app ._match_route ('/user/123' , '/user/<id>' )
70+ assert vars == {'id' : '123' }
71+ assert await app ._match_route ('/a/b' , '/a/b' ) == {}
72+ assert await app ._match_route ('/a/b' , '/a/c' ) is None
73+
74+ # test response building with cookies
75+ resp = app ._get_response ()
76+ resp .set_cookie ('s' , 'v' , max_age = 10 , httponly = True )
77+ header = await app ._build_response (200 , 'text/plain' )
78+ assert b'Set-Cookie' in header
79+
80+ def test_user_operations_and_sessions (tmp_path ):
81+ app .users .clear (); app .profiles .clear (); app .sessions .clear ()
82+ assert app .create_user ('x' , 'p' ) is True
83+ assert app .user_exists ('x' )
84+ assert app .login ('x' , 'p' ) is True
85+ assert app .edit_user ('x' , 'new' ) is True
86+ assert app .delete_user ('x' ) is True
87+
88+ app .create_user ('y' , 'p' )
89+ token = app .start_session ('y' )
90+ assert app .verify_session (token )
91+ assert app .get_username (token ) == 'y'
92+ app .end_session (token )
93+ assert not app .verify_session (token )
94+
95+ @pytest .mark .asyncio
96+ async def test_ratelimit_decorator_and_socket_mode (monkeypatch ):
97+ # Decorator mode: ensure it returns a callable
98+ dec = app .ratelimit (0.1 )
99+ @dec
100+ async def f ():
101+ return 'ok'
102+ assert callable (f )
103+
104+ # Socket mode: create a fake socket with getpeername
105+ class FakeSock :
106+ def getpeername (self ):
107+ return ('127.0.0.1' , 12345 )
108+ sock = FakeSock ()
109+ # delay-based: first call allowed, immediate second call should be rate-limited
110+ assert app .ratelimit (sock , 0.5 , 'test' ) is False
111+ assert app .ratelimit (sock , 0.5 , 'test' ) is True
112+
113+ * * * End Patch
0 commit comments