diff options
Diffstat (limited to 'test/modules/http1/htdocs/cgi')
-rw-r--r-- | test/modules/http1/htdocs/cgi/files/empty.txt | 0 | ||||
-rwxr-xr-x | test/modules/http1/htdocs/cgi/hello.py | 15 | ||||
-rw-r--r-- | test/modules/http1/htdocs/cgi/requestparser.py | 57 | ||||
-rwxr-xr-x | test/modules/http1/htdocs/cgi/upload.py | 55 |
4 files changed, 127 insertions, 0 deletions
diff --git a/test/modules/http1/htdocs/cgi/files/empty.txt b/test/modules/http1/htdocs/cgi/files/empty.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/modules/http1/htdocs/cgi/files/empty.txt diff --git a/test/modules/http1/htdocs/cgi/hello.py b/test/modules/http1/htdocs/cgi/hello.py new file mode 100755 index 0000000..191acb2 --- /dev/null +++ b/test/modules/http1/htdocs/cgi/hello.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import os + +print("Content-Type: application/json") +print() +print("{") +print(" \"https\" : \"%s\"," % (os.getenv('HTTPS', ''))) +print(" \"host\" : \"%s\"," % (os.getenv('SERVER_NAME', ''))) +print(" \"protocol\" : \"%s\"," % (os.getenv('SERVER_PROTOCOL', ''))) +print(" \"ssl_protocol\" : \"%s\"," % (os.getenv('SSL_PROTOCOL', ''))) +print(" \"h2\" : \"%s\"," % (os.getenv('HTTP2', ''))) +print(" \"h2push\" : \"%s\"" % (os.getenv('H2PUSH', ''))) +print("}") + diff --git a/test/modules/http1/htdocs/cgi/requestparser.py b/test/modules/http1/htdocs/cgi/requestparser.py new file mode 100644 index 0000000..c7e0648 --- /dev/null +++ b/test/modules/http1/htdocs/cgi/requestparser.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +import os +import sys +from urllib import parse +import multipart # https://github.com/andrew-d/python-multipart (`apt install python3-multipart`) +import shutil + + +try: # Windows needs stdio set for binary mode. + import msvcrt + + msvcrt.setmode(0, os.O_BINARY) # stdin = 0 + msvcrt.setmode(1, os.O_BINARY) # stdout = 1 +except ImportError: + pass + + +class FileItem: + + def __init__(self, mparse_item): + self.item = mparse_item + + @property + def file_name(self): + return os.path.basename(self.item.file_name.decode()) + + def save_to(self, destpath: str): + fsrc = self.item.file_object + fsrc.seek(0) + with open(destpath, 'wb') as fd: + shutil.copyfileobj(fsrc, fd) + + +def get_request_params(): + oforms = {} + ofiles = {} + if "REQUEST_URI" in os.environ: + qforms = parse.parse_qs(parse.urlsplit(os.environ["REQUEST_URI"]).query) + for name, values in qforms.items(): + oforms[name] = values[0] + if "CONTENT_TYPE" in os.environ: + ctype = os.environ["CONTENT_TYPE"] + if ctype == "application/x-www-form-urlencoded": + s = sys.stdin.read() + qforms = parse.parse_qs(s) + for name, values in qforms.items(): + oforms[name] = values[0] + elif ctype.startswith("multipart/"): + def on_field(field): + oforms[field.field_name.decode()] = field.value.decode() + def on_file(file): + ofiles[file.field_name.decode()] = FileItem(file) + multipart.parse_form(headers={"Content-Type": ctype}, + input_stream=sys.stdin.buffer, + on_field=on_field, on_file=on_file) + return oforms, ofiles + diff --git a/test/modules/http1/htdocs/cgi/upload.py b/test/modules/http1/htdocs/cgi/upload.py new file mode 100755 index 0000000..632b7e9 --- /dev/null +++ b/test/modules/http1/htdocs/cgi/upload.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +import os +import sys +from requestparser import get_request_params + + +forms, files = get_request_params() + +status = '200 Ok' + +# Test if the file was uploaded +if 'file' in files: + fitem = files['file'] + # strip leading path from file name to avoid directory traversal attacks + fname = fitem.file_name + fpath = f'{os.environ["DOCUMENT_ROOT"]}/files/{fname}' + fitem.save_to(fpath) + message = "The file %s was uploaded successfully" % (fname) + print("Status: 201 Created") + print("Content-Type: text/html") + print("Location: %s://%s/files/%s" % (os.environ["REQUEST_SCHEME"], os.environ["HTTP_HOST"], fname)) + print("") + print("<html><body><p>%s</p></body></html>" % (message)) + +elif 'remove' in forms: + remove = forms['remove'] + try: + fname = os.path.basename(remove) + os.remove('./files/' + fname) + message = 'The file "' + fname + '" was removed successfully' + except OSError as e: + message = 'Error removing ' + fname + ': ' + e.strerror + status = '404 File Not Found' + print("Status: %s" % (status)) + print(""" +Content-Type: text/html + +<html><body> +<p>%s</p> +</body></html>""" % (message)) + +else: + message = '''\ + Upload File<form method="POST" enctype="multipart/form-data"> + <input type="file" name="file"> + <button type="submit">Upload</button></form> + ''' + print("Status: %s" % (status)) + print("""\ +Content-Type: text/html + +<html><body> +<p>%s</p> +</body></html>""" % (message)) + |