8 WWWROOT
= "tmp.httpd.tests"
13 self
.s
= socket
.socket()
14 self
.s
.connect(("0.0.0.0", self
.port
))
15 # connect throws socket.error on connection refused
17 def get(self
, url
, http_ver
="1.0", endl
="\n", req_hdrs
={}):
19 if http_ver
is not None:
20 req
+= " HTTP/"+http_ver
22 if http_ver
is not None:
23 req_hdrs
["User-Agent"] = "test.py"
24 req_hdrs
["Connection"] = "close"
25 for k
,v
in req_hdrs
.items():
27 req
+= endl
# end of request
31 signal
.alarm(1) # don't wait forever
32 r
= self
.s
.recv(65536)
42 Parse response into status line, headers and body.
44 pos
= resp
.index("\r\n\r\n") # throws exception on failure
47 status
,head
= head
.split("\r\n", 1)
49 for line
in head
.split("\r\n"):
50 k
, v
= line
.split(": ", 1)
52 return (status
, hdrs
, body
)
54 class TestCases(unittest
.TestCase
):
55 def assertContains(self
, body
, *strings
):
57 self
.assertTrue(s
in body
,
58 msg
="expected %s in %s"%(repr(s
), repr(body
)))
60 def assertIsIndex(self
, body
, path
):
61 self
.assertContains(body
,
62 "<title>%s</title>\n"%path
,
64 '<a href="..">..</a>/',
65 'Generated by darkhttpd')
67 def assertIsInvalid(self
, body
, path
):
68 self
.assertContains(body
,
69 "<title>400 Bad Request</title>",
70 "<h1>Bad Request</h1>\n",
71 "You requested an invalid URL: %s\n"%path
,
72 'Generated by darkhttpd')
74 def test_dirlist_escape(self
):
75 fn
= WWWROOT
+"/escape#this"
76 open(fn
, "w").write("x"*12345)
78 resp
= Conn().get("/")
81 status
, hdrs
, body
= parse(resp
)
82 self
.assertEquals(ord("#"), 0x23)
83 self
.assertContains(body
, "escape%23this", "12345")
86 return re
.sub("[^a-zA-Z0-9]", "_", s
)
88 def makeCase(name
, url
, hdr_checker
=None, body_checker
=None,
89 req_hdrs
={"User-Agent": "test.py"},
90 http_ver
=None, endl
="\n"):
92 resp
= Conn().get(url
, http_ver
, endl
, req_hdrs
)
98 status
, hdrs
, body
= parse(resp
)
100 if hdr_checker
is not None and http_ver
is not None:
101 hdr_checker(self
, hdrs
)
103 if body_checker
is not None:
104 body_checker(self
, body
)
106 # FIXME: check status
107 if http_ver
is not None:
108 prefix
= "HTTP/1.1 " # should 1.0 stay 1.0?
109 self
.assertTrue(status
.startswith(prefix
),
110 msg
="%s at start of %s"%(repr(prefix
), repr(status
)))
115 test_name
= "_".join([
119 {"\n":"LF", "\r\n":"CRLF"}[endl
],
121 do_test
.__name
__ = test_name
# hax
122 setattr(TestCases
, test_name
, do_test
)
124 def makeCases(name
, url
, hdr_checker
=None, body_checker
=None,
125 req_hdrs
={"User-Agent": "test.py"}):
126 # FIXME: 0.9 is broken
127 for http_ver
in [None, "1.0", "1.1"]:
128 #for http_ver in ["1.0", "1.1"]:
129 for endl
in ["\n", "\r\n"]:
130 makeCase(name
, url
, hdr_checker
, body_checker
,
131 req_hdrs
, http_ver
, endl
)
133 def makeSimpleCases(name
, url
, assert_name
):
134 makeCases(name
, url
, None,
135 lambda self
,body
: getattr(self
, assert_name
)(body
, url
))
139 ["index", "/", "assertIsIndex"],
140 ["up dir", "/dir/../", "assertIsIndex"],
141 ["extra slashes", "//dir///..////", "assertIsIndex"],
142 ["no trailing slash", "/dir/..", "assertIsIndex"],
143 ["no leading slash", "dir/../", "assertIsInvalid"],
144 ["invalid up dir", "/../", "assertIsInvalid"],
145 ["fancy invalid up dir", "/./dir/./../../", "assertIsInvalid"],
147 makeSimpleCases(*args
)
149 if __name__
== '__main__':
152 #x = Conn().get("/xyz/../", "1.0")
156 # vim:set ts=4 sw=4 et: