Add new upload mode

This commit is contained in:
Rnhmjoj 2015-03-28 18:39:08 +01:00
parent b36366b3f9
commit 49b0e153e4

72
hyp.py
View File

@ -1,15 +1,56 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import sys import sys
import os.path
import http.server
import ssl import ssl
import cgi
import os
import os.path as path
import http.server as http
upload_page = '''
<form method="POST" enctype="multipart/form-data">
File to upload: <input type="file" name="upfile"><br>
<input type="submit" value="Send">
</form>
'''
class UploadHandler(http.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('content-type', 'text/html')
self.end_headers()
self.wfile.write(upload_page.encode('utf-8'))
def do_POST(self):
self.send_response(200)
self.end_headers()
form = cgi.FieldStorage(
environ={
'REQUEST_METHOD':'POST',
'CONTENT_TYPE': self.headers['content-type']},
fp=self.rfile,
headers=self.headers)
for field in form.keys():
item = form[field]
name = path.join(os.getcwd(), item.filename)
if path.exists(name):
self.wfile.write('{} failed: already exists\n'.format(
item.filename).encode('utf-8'))
continue
with open(name, 'wb') as file:
file.write(item.file.read())
self.wfile.write('{} has been uploaded\n'.format(
item.filename).encode('utf-8'))
def check_cert(dir): def check_cert(dir):
try: try:
for i in 'cert', 'key': for i in 'cert', 'key':
open(os.path.join(dir, 'https-%s.pem' % i)).close() open(path.join(dir, 'https-%s.pem' % i)).close()
except (FileNotFoundError, PermissionError) as e: except (FileNotFoundError, PermissionError) as e:
print('Could not use %s: %s. Using http only.' % (dir, e.args[1])) print('Could not use %s: %s. Using http only.' % (dir, e.args[1]))
return False return False
@ -19,16 +60,20 @@ def check_cert(dir):
return True return True
def main(address, port, tls_dir): def main(address, port, tls_dir, upload):
use_tls = check_cert(tls_dir) use_tls = check_cert(tls_dir)
port = 80 if port == 443 and not use_tls else port port = 80 if port == 443 and not use_tls else port
bind = (address, port)
try: try:
server = http.server.HTTPServer((address, port), if upload:
http.server.SimpleHTTPRequestHandler) server = http.HTTPServer(bind, UploadHandler)
else:
server = http.HTTPServer(bind, http.SimpleHTTPRequestHandler)
if use_tls: if use_tls:
tls_socket = ssl.wrap_socket(server.socket, server_side=True, tls_socket = ssl.wrap_socket(server.socket, server_side=True,
certfile=os.path.join(tls_dir, 'https-cert.pem'), certfile=path.join(tls_dir, 'https-cert.pem'),
keyfile=os.path.join(tls_dir,'https-key.pem'), keyfile=path.join(tls_dir,'https-key.pem'),
ssl_version=ssl.PROTOCOL_TLSv1_2) ssl_version=ssl.PROTOCOL_TLSv1_2)
server.socket = tls_socket server.socket = tls_socket
except Exception as e: except Exception as e:
@ -52,10 +97,13 @@ if __name__ == '__main__':
parser.add_argument('port', nargs='?', parser.add_argument('port', nargs='?',
type=int, default=443, type=int, default=443,
help='bind port number (default: 80 or 443)') help='bind port number (default: 80 or 443)')
parser.add_argument('-t', '--tls', type=str, parser.add_argument('-u', '--upload', action='store_true',
help='only accept and save file as POST requests')
parser.add_argument('-t', '--tls',
type=str, dest='tls_dir', metavar='DIR',
default='/usr/local/etc/openssl', default='/usr/local/etc/openssl',
help='cert/key couple directory. Must be PEM' help='cert/key couple directory. Must be PEM '
'formatted and named https-key.pem, https-cert.pem' 'formatted and named https-key.pem, https-cert.pem '
'(default: /usr/local/etc/openssl)') '(default: /usr/local/etc/openssl)')
args = parser.parse_args() args = parser.parse_args()
main(args.address, args.port, args.tls) main(**vars(args))