forked from emikulic/darkhttpd
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Custom headers with the CLI option
--header
(emikulic#28)
These changes add a command-line option --header, e.g. --header 'Access-Control-Allow-Origin: *'. Basic tests are included for this option. When accepting the argument, a very simple sanitization is made, the string is required to contain ": ", and can’t contain a '\n' character. These checks are far from what is required to truly validate a HTTP header, but will at least detect simple mistakes and forbid the abuse of having arguments that include more than one header, or, worse, that include a body for the response (after "\r\n\r\n"). This should also close the Issue emikulic#16 and PR emikulic#27, I think, since CORS functionality can be obtained by specifying a custom header.
- Loading branch information
Showing
4 changed files
with
151 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#!/usr/bin/env python3 | ||
# This is run by the "run-tests" script. | ||
import unittest | ||
import os | ||
from test import WWWROOT, TestHelper, parse, random_bytes | ||
|
||
class TestCustomHeaders(TestHelper): | ||
def setUp(self): | ||
self.datalen = 2345 | ||
self.data = random_bytes(self.datalen) | ||
self.url = '/data.jpeg' | ||
self.not_found = '/not_found.jpeg' | ||
self.fn = WWWROOT + self.url | ||
with open(self.fn, 'wb') as f: | ||
f.write(self.data) | ||
|
||
def tearDown(self): | ||
os.unlink(self.fn) | ||
|
||
def test_custom_headers(self): | ||
resp = self.get(self.url) | ||
status, hdrs, body = parse(resp) | ||
self.assertContains(status, '200 OK') | ||
self.assertEqual(hdrs["Accept-Ranges"], "bytes") | ||
self.assertEqual(hdrs["Content-Length"], str(self.datalen)) | ||
self.assertEqual(hdrs["Content-Type"], "image/jpeg") | ||
self.assertEqual(hdrs["X-Header-A"], "First Value") | ||
self.assertEqual(hdrs["X-Header-B"], "Second Value") | ||
self.assertContains(hdrs["Server"], "darkhttpd/") | ||
assert body == self.data, [self.url, resp, status, hdrs, body] | ||
self.assertEqual(body, self.data) | ||
|
||
def test_custom_headers_not_found(self): | ||
resp = self.get(self.not_found) | ||
status, hdrs, body = parse(resp) | ||
self.assertContains(status, '404 Not Found') | ||
self.assertContains(hdrs["Server"], "darkhttpd/") | ||
self.assertEqual(hdrs["X-Header-A"], "First Value") | ||
self.assertEqual(hdrs["X-Header-B"], "Second Value") | ||
|
||
def test_custom_headers_listing(self): | ||
resp = self.get("/") | ||
status, hdrs, body = parse(resp) | ||
self.assertContains(status, '200 OK') | ||
self.assertContains(body, '<a href="data.jpeg">data.jpeg</a>') | ||
self.assertContains(body, 'Generated by darkhttpd/') | ||
self.assertEqual(hdrs["Accept-Ranges"], "bytes") | ||
self.assertEqual(hdrs["Content-Type"], "text/html; charset=UTF-8") | ||
self.assertEqual(hdrs["X-Header-A"], "First Value") | ||
self.assertEqual(hdrs["X-Header-B"], "Second Value") | ||
self.assertContains(hdrs["Server"], "darkhttpd/") | ||
|
||
def test_custom_headers_range(self): | ||
resp = self.get(self.url, req_hdrs={'Range': 'bytes=0-99'}) | ||
status, hdrs, body = parse(resp) | ||
self.assertContains(status, '206 Partial Content') | ||
self.assertEqual(hdrs["Accept-Ranges"], "bytes") | ||
self.assertEqual(hdrs["Content-Length"], '100') | ||
self.assertEqual(hdrs["Content-Type"], "image/jpeg") | ||
self.assertEqual(hdrs["X-Header-A"], "First Value") | ||
self.assertEqual(hdrs["X-Header-B"], "Second Value") | ||
self.assertContains(hdrs["Server"], "darkhttpd/") | ||
assert body == self.data[0:100], [self.url, resp, status, hdrs, body] | ||
self.assertEqual(body, self.data[0:100]) | ||
|
||
def test_custom_header_if_modified_since(self): | ||
resp1 = self.get(self.url, method="HEAD") | ||
status, hdrs, body = parse(resp1) | ||
lastmod = hdrs["Last-Modified"] | ||
|
||
resp2 = self.get(self.url, method="GET", req_hdrs= | ||
{"If-Modified-Since": lastmod }) | ||
status, hdrs, body = parse(resp2) | ||
self.assertContains(status, "304 Not Modified") | ||
self.assertEqual(hdrs["Accept-Ranges"], "bytes") | ||
self.assertFalse("Last-Modified" in hdrs) | ||
self.assertFalse("Content-Length" in hdrs) | ||
self.assertFalse("Content-Type" in hdrs) | ||
self.assertEqual(hdrs["X-Header-A"], "First Value") | ||
self.assertEqual(hdrs["X-Header-B"], "Second Value") | ||
|
||
def test_custom_header_forward(self): | ||
resp = self.get('/', req_hdrs={'Host': 'example.com'}) | ||
status, hdrs, body = parse(resp) | ||
self.assertEqual(hdrs["X-Header-A"], "First Value") | ||
self.assertEqual(hdrs["X-Header-B"], "Second Value") | ||
self.assertContains(status, "301 Moved Permanently") | ||
expect = "http://www.example.com/" | ||
self.assertEqual(hdrs["Location"], expect) | ||
self.assertContains(body, expect) | ||
|
||
if __name__ == '__main__': | ||
unittest.main() | ||
|
||
# vim:set ts=4 sw=4 et: |