http-upload-server/main.py

110 lines
3.7 KiB
Python
Raw Permalink Normal View History

2023-07-21 14:49:47 +03:00
'''
HTTP storage server - server for storing files.
Copyright (C) 2023 Dymik739
Email: user@109.86.70.81
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import socket
import datetime
import os
# storage setup
if not os.path.exists("storage/"):
os.mkdir("storage/")
# constant definitions
UNDEFINED_LENGTH = -1
# function definitions
def get_filename_from_type(file_type, file_id):
pass
# main code
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 5555))
s.listen(1000)
while True:
conn, addr = s.accept()
conn.settimeout(15)
print(f"Received connection from {addr[0]}:{addr[1]}")
left_to_read = UNDEFINED_LENGTH
last_read_length = 0
data_buffer = bytes()
request_head = {"method": None, "path": None, "headers": {}}
request_body = bytes()
initial_header_processed = False
reading_headers = True
while left_to_read:
if left_to_read == UNDEFINED_LENGTH:
data_buffer += conn.recv(1024)
else:
data_buffer += conn.recv(left_to_read)
raw_headers = data_buffer.split("\r\n".encode("UTF-8"))
if reading_headers:
for item in raw_headers[:-1]:
data_buffer = data_buffer[len(item) + 2:]
i = item.decode("UTF-8", errors = "ignore")
if i == "":
reading_headers = False
left_to_read = int(request_head['headers']['content-length'])
print("Switch!")
break
if initial_header_processed:
print(i, f"len = {len(i)}")
header = i.split(": ")
request_head['headers'].update({header[0].lower(): header[1]})
else:
header = i.split(" ")
request_head['method'] = i[0]
request_head['path'] = i[1]
initial_header_processed = True
else:
left_to_read -= len(data_buffer)
request_body += data_buffer
print(data_buffer)
data_buffer = bytes()
raw_items = request_body.split(("--" + request_head['headers']['content-type'].split("; ")[1].split("=")[1]).encode("UTF-8"))
new_folder = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
os.mkdir(f"storage/{new_folder}/")
for number, raw_i in enumerate(raw_items):
print("New file")
split_item = raw_i.split("\r\n\r\n".encode("UTF-8"))
if len(split_item) < 2:
continue
current_headers = {k.lower(): v for (k, v) in [x.split(": ") for x in split_item[0].decode("UTF-8").split("\r\n") if x != ""]}
if "content-disposition" in current_headers and "upload" in current_headers["content-disposition"]:
filename = dict([x.split("=") for x in current_headers["content-disposition"].split("; ") if "=" in x])["filename"][1:-1]
#filename = get_filename_from_type(current_headers["content-type"])
with open(f"storage/{new_folder}/{filename}", "wb") as f:
f.write(split_item[1])
conn.close()