Compare commits
2
Commits
ba9c2dff67
..
2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bab41a0084 | ||
|
|
cec8a80714 |
+11
-43
@@ -47,9 +47,8 @@ import threading
|
||||
import ssl
|
||||
import socket
|
||||
import signal
|
||||
# Experimental imports go here
|
||||
import select
|
||||
import subprocess
|
||||
# Experimental imports go here
|
||||
|
||||
try:
|
||||
if not os.getcwd() in sys.path:
|
||||
@@ -63,7 +62,7 @@ except ImportError:
|
||||
)
|
||||
# pass
|
||||
|
||||
AMETHYST_BUILD_NUMBER = "0.3.1-0130-mt-tryout2"
|
||||
AMETHYST_BUILD_NUMBER = "0.99.0-0134-ff"
|
||||
AMETHYST_REPO = "https://git.novacow.ch/Nova/PyWebServer/"
|
||||
|
||||
|
||||
@@ -115,7 +114,6 @@ class ConfigParser:
|
||||
if host:
|
||||
value = self.data["hosts"].get(host, {}).get(key)
|
||||
elif key == "hosts":
|
||||
print(f"\n\n\nHosts!\nHosts: {self.data['hosts']}\n\n\n")
|
||||
value = list(self.data["hosts"].keys())
|
||||
else:
|
||||
value = self.data["globals"].get(key)
|
||||
@@ -172,9 +170,6 @@ class FileHandler:
|
||||
return 0
|
||||
|
||||
def read_config(self, key, host_name=None):
|
||||
print(
|
||||
f"\n\n\nQuery!\nkey: {key}\nhost_name: {host_name}\nret: {self.cfg.query_config(key, host_name)}"
|
||||
)
|
||||
return self.cfg.query_config(key, host_name)
|
||||
|
||||
def autocert(self):
|
||||
@@ -190,7 +185,6 @@ class RequestParser:
|
||||
def __init__(self):
|
||||
self.file_handler = FileHandler()
|
||||
self.hosts = self.file_handler.read_config("hosts")
|
||||
print(f"Hosts: {self.hosts}")
|
||||
|
||||
def extract_header(self, header: str, request: bytes | str):
|
||||
if isinstance(request, bytes):
|
||||
@@ -260,7 +254,6 @@ class RequestParser:
|
||||
Mfw im in an ugly code writing contest and my opponent is nova while writing a side project
|
||||
"""
|
||||
host = f"{host}"
|
||||
print(f"hosts: {self.hosts}, host: {host}, split: {host.rsplit(':', 1)[0]}")
|
||||
if ":" in host:
|
||||
host = host.rsplit(":", 1)[0]
|
||||
host = host.lstrip()
|
||||
@@ -296,9 +289,7 @@ class ProxyServer:
|
||||
def try_connection(
|
||||
self, host: str, port: int, data: bytes, chost: str, force_tls: bool = None
|
||||
):
|
||||
print(f"\n\n\nchost: {chost}\n\n\n")
|
||||
nhost = self.file_handler.read_config("proxy", chost)
|
||||
print(f"\n\n\nnhost: {nhost}\n\n\n")
|
||||
# nhost will include http or https.
|
||||
if nhost.startswith("https"):
|
||||
nhost = nhost[6:-1]
|
||||
@@ -313,16 +304,13 @@ class ProxyServer:
|
||||
)
|
||||
if force_tls is True:
|
||||
do_tls = True
|
||||
print(f"\n\n\nnhost: {nhost}\n\n\n")
|
||||
if ":" in nhost:
|
||||
nport = int(nhost.split(":")[1])
|
||||
nhost = nhost.split(":")[0]
|
||||
else:
|
||||
nport = port
|
||||
print(f"{nhost}, {nport}, {data}")
|
||||
data = self.reset_host(nhost, nport, data)
|
||||
try:
|
||||
print("Waiting on TCP start.")
|
||||
return self.tcp_send(nhost, nport, data, do_tls)
|
||||
except Exception as e:
|
||||
raise Exception(f"Server replied unexpected. Reply from Python subsystem: {e}")
|
||||
@@ -378,7 +366,6 @@ class ProxyServer:
|
||||
raw_sock, server_hostname=server_hostname
|
||||
) as ssock:
|
||||
ssock.sendall(data)
|
||||
print("data reached")
|
||||
resp = self.recv_all(ssock)
|
||||
if self.rq.extract_header("Transfer-Encoding", resp) == "chunked":
|
||||
ssock.sendall(b"TRANSER-ENCODING IS NOT SUPPORTED")
|
||||
@@ -393,9 +380,7 @@ class ProxyServer:
|
||||
)
|
||||
return resp
|
||||
else:
|
||||
print(f"\n\n\nraw data: {data}\n\n\n")
|
||||
raw_sock.sendall(data)
|
||||
print("Waiting for response...")
|
||||
resp = self.recv_all(raw_sock)
|
||||
if self.rq.extract_header("Transfer-Encoding", resp) is not None:
|
||||
raw_sock.sendall(b"TRANSER-ENCODING IS NOT SUPPORTED")
|
||||
@@ -454,11 +439,9 @@ class WebServer:
|
||||
|
||||
self.http_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||
self.http_socket.bind(("::", self.http_port))
|
||||
# self.http_socket.settimeout(1)
|
||||
|
||||
self.https_socket_raw = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||
self.https_socket_raw.bind(("::", self.https_port))
|
||||
# self.https_socket_raw.settimeout(1)
|
||||
|
||||
self.proxy_handler = ProxyServer(self.file_handler)
|
||||
|
||||
@@ -493,20 +476,27 @@ class WebServer:
|
||||
def start(self, http, https):
|
||||
signal.signal(signal.SIGINT, self.shutdown)
|
||||
signal.signal(signal.SIGTERM, self.shutdown)
|
||||
|
||||
http_thread = threading.Thread(target=self.start_http, daemon=True)
|
||||
https_thread = threading.Thread(target=self.start_https, daemon=True)
|
||||
|
||||
if https is True:
|
||||
if self.skip_ssl is True:
|
||||
print("WARN: You have enabled HTTPS without SSL!!")
|
||||
yn = input("Is this intended behaviour? [y/N] ")
|
||||
if yn.lower() == "n":
|
||||
exit(1)
|
||||
self.start_https()
|
||||
https_thread.start()
|
||||
else:
|
||||
self.https_socket.close()
|
||||
if http is True:
|
||||
self.start_http()
|
||||
http_thread.start()
|
||||
else:
|
||||
self.http_socket.close()
|
||||
|
||||
http_thread.join()
|
||||
https_thread.join()
|
||||
|
||||
def start_http(self):
|
||||
self.http_socket.listen(5)
|
||||
print(f"HTTP server listening on port {self.http_port}...")
|
||||
@@ -535,7 +525,6 @@ class WebServer:
|
||||
except OSError as e:
|
||||
if not self.running:
|
||||
break
|
||||
print(f"OSError! {e}")
|
||||
continue
|
||||
except Exception as e:
|
||||
print(f"HTTP error: {e}")
|
||||
@@ -568,7 +557,6 @@ class WebServer:
|
||||
except OSError as e:
|
||||
if not self.running:
|
||||
break
|
||||
print(f"OSError! {e}")
|
||||
continue
|
||||
except Exception as e:
|
||||
print(f"HTTPS error: {e}")
|
||||
@@ -591,14 +579,10 @@ class WebServer:
|
||||
if line.lower().startswith(b"content-length:"):
|
||||
content_length = int(line.split(b":")[1].strip())
|
||||
|
||||
# print(f"Content-Length to server: {content_length}")
|
||||
|
||||
# Read body
|
||||
body = rest
|
||||
print(f"Rest length: {len(rest)}")
|
||||
while len(body) < content_length:
|
||||
chunk = conn.recv(4096)
|
||||
# print(f"\n\nrecv returned {len(chunk)}\n\n")
|
||||
if not chunk:
|
||||
print("\n\nsocket closed\n\n")
|
||||
break
|
||||
@@ -618,7 +602,6 @@ class WebServer:
|
||||
if isinstance(response, str):
|
||||
response = response.encode()
|
||||
|
||||
print(len(response))
|
||||
conn.sendall(response)
|
||||
except Exception as e:
|
||||
print(f"Error handling connection: {e}")
|
||||
@@ -633,10 +616,8 @@ class WebServer:
|
||||
conn.close()
|
||||
|
||||
def handle_request(self, data, addr):
|
||||
# print(f"data: {data}")
|
||||
request_line = data.splitlines()[0]
|
||||
|
||||
# Extract host from headers, never works though
|
||||
for line in data.splitlines():
|
||||
if "Host" in line:
|
||||
host = line.split(":", 1)[1].strip()
|
||||
@@ -735,7 +716,6 @@ class WebServer:
|
||||
file_content, mimetype = self.file_handler.read_file(path, directory)
|
||||
|
||||
if file_content == 403:
|
||||
print("WARN: Directory traversal attack prevented.") # look ma, security!!
|
||||
return self.build_response(403, self.http_403_html)
|
||||
if file_content == 404:
|
||||
return self.build_response(404, self.http_404_html)
|
||||
@@ -789,7 +769,6 @@ class WebServer:
|
||||
200: "OK",
|
||||
204: "No Content",
|
||||
302: "Found",
|
||||
304: "Not Modified", # TODO KEKL
|
||||
400: "Bad Request",
|
||||
403: "Forbidden",
|
||||
404: "Not Found",
|
||||
@@ -803,8 +782,6 @@ class WebServer:
|
||||
if isinstance(body, str):
|
||||
body = body.encode()
|
||||
|
||||
# TODO: dont encode yet, and i encode. awesome comments here.
|
||||
# Don't encode yet, if 302 status code we have to include location.
|
||||
headers = (
|
||||
f"HTTP/1.1 {status_code} {status_message}\r\n"
|
||||
f"Server: Amethyst/build-{AMETHYST_BUILD_NUMBER}\r\n"
|
||||
@@ -813,13 +790,6 @@ class WebServer:
|
||||
).encode()
|
||||
|
||||
if status_code == 302:
|
||||
# 302 currently only happens when the reload is triggered.
|
||||
# Why not 307, Moved Permanently? Because browsers will cache the
|
||||
# response and not send the reload command.
|
||||
# if port == 443:
|
||||
# host = f"https://{host}/"
|
||||
# else:
|
||||
# host = f"http://{host}/"
|
||||
headers = (
|
||||
f"HTTP/1.1 {status_code} {status_message}\r\n"
|
||||
f"Location: {host}\r\n"
|
||||
@@ -864,9 +834,7 @@ def main():
|
||||
http_port = file_handler.read_config("port")
|
||||
https_port = file_handler.read_config("https-port")
|
||||
http_enabled = bool(file_handler.read_config("http"))
|
||||
print(http_enabled)
|
||||
https_enabled = bool(file_handler.read_config("https"))
|
||||
print(https_enabled)
|
||||
server = WebServer(http_port=http_port, https_port=https_port)
|
||||
server.start(http_enabled, https_enabled)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user