I'm trying to create a Python web server that can receive files. So someone can vist the website, click the upload button on the form, then the file will be sent to the server and stored locally on the server.
Here is the contents of index.html
<form enctype="multipart/form-data" action="" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="8000000" />
<input name="uploadedfile" type="file" /><br />
<input type="submit" value="Upload File" />
</form>
Contents of Server.py
import socket
class server():
def __init__(self):
self.host_ip = socket.gethostbyname(socket.gethostname())
self.host_port = 81
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.data_recv_size = 1024
def get_data(self, conn):
""" gets the data from client """
data = b""
while b"\r\n\r\n" not in data:
data += conn.recv(self.data_recv_size)
return data
def server(self):
""" main method starts the server """
print(f"[+] Server started listening on port {self.host_port}!")
print(f"[+] Server Ip: {self.host_ip}")
self.s.bind((self.host_ip, self.host_port))
self.s.listen()
while True:
conn, addr = self.s.accept()
with conn:
data = self.get_data(conn)
# GET request
if data[0:5] == b"GET /":
index = open("index.html", "rb").read()
conn.sendall(b"HTTP/1.0 200 OK\nContent-Type: text/html\n\n" + index)
print("[+] Responded to GET request")
# POST request
elif data[0:4] == b"POST":
with open("output.txt", "ab") as file:
file.write(data)
print(f"{len(data)} bytes received from post!")
conn.sendall(b"HTTP/1.0 200 OK\r\nContent-Type: text/html")
s = server()
s.server()
The GET part of the server works correctly, when I visit the website the index.html file is display in my web browser and I can see the file upload form.
EDIT: I updated the form to max file size 8 million name="MAX_FILE_SIZE" value="8000000", The POST response the server receives is much bigger (I updated it below), but it still doesn't look like it contains the file contents.
POST / HTTP/1.1
Host: 169.254.126.211:81
Connection: keep-alive
Content-Length: 2857323
Cache-Control: max-age=0
Origin: http://169.254.126.211:81
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjbf7KaGShYBQ75wT
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://169.254.126.211:81/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,ru;q=0.7
------WebKitFormBoundaryjbf7KaGShYBQ75wT
Content-Disposition: form-data; name="MAX_FILE_SIZE"
8000000
------WebKitFormBoundaryjbf7KaGShYBQ75wT
Content-Disposition: form-data; name="uploadedfile"; filename="IMG_20210131_165637.jpg"
Content-Type: image/jpeg
ÿØÿá„ÙExif MM * @
° ö ¶ ¾POST / HTTP/1.1
Host: 169.254.126.211:81
Connection: keep-alive
Content-Length: 2857323
Cache-Control: max-age=0
Origin: http://169.254.126.211:81
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjbf7KaGShYBQ75wT
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://169.254.126.211:81/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,ru;q=0.7
Screenshot showing the output in Python IDLE when I run the script.
Edit: It only says 1024 bytes received from post!, so it looks like the full file isn't being sent.
How do I sent a file from a web browser via POST, and receive the file on the server?



2804304 bytes? When I run the script it prints674 bytes received from post!Content-Length: 2804304). Is the file you are attempting to upload approximately 2.8 MB?