Skip to content

Commit a3afa4a

Browse files
committed
Better handling of large files
1 parent 8d47caa commit a3afa4a

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Relatively simple Python server that accepts POST and PUT requests and saves the
44

55
If a path is specified in the request, the part after the final `/` (minus any URL parameters or such) will be treated as the filename that it should be saved to. For example:
66
```
7-
POST http://1.2.3.4:8123/stuff/myFile.txt?hello=garbage
7+
POST http://1.2.3.4:8123/stuff/myFile.txt?param=anything
88
```
99
will cause the file to be saved to `myFile.txt`.
1010

@@ -43,7 +43,7 @@ Invoke-WebRequest -Uri http://1.2.3.4:8080/differentName.bin?mySecretParam -Meth
4343

4444
Send a file to the server using curl:
4545
```bash
46-
curl -T ./myFile.bin http://1.2.3.4:8080/differentName.bin?mySecretParam
46+
curl -T ./myFile.bin 1.2.3.4:8080/differentName.bin?mySecretParam
4747
```
4848
- Also works with `curl.exe` on recent versions of Windows
4949

upload-server.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@
77
from urllib.parse import urlparse, parse_qs
88
from http.server import HTTPServer, BaseHTTPRequestHandler, SimpleHTTPRequestHandler
99

10+
# SECRET is set dynamically at runtime with -s
1011
SECRET = None
1112

13+
# PART_SIZE is hardcoded; writes out larger files in chunks of this size to limit memory usage
14+
# This also significantly speeds up large transfers, but idk why
15+
PART_SIZE = 256 * 1024 * 1024 #256MB
16+
1217
class CustomHTTPRequestHandler(SimpleHTTPRequestHandler):
1318

1419
# Ignore all GETs
@@ -54,13 +59,24 @@ def do_POST(self):
5459
else:
5560
filePath = f"{filePath}_{i}"
5661

57-
# Write the request body
62+
# Write the request body to a file
5863
with open(filePath, 'wb') as output_file:
59-
output_file.write(self.rfile.read(file_length))
64+
print(f"Recieving file '{filename}' with size {file_length} from {self.client_address[0]}")
65+
66+
numParts = file_length // PART_SIZE
67+
if file_length % PART_SIZE != 0:
68+
numParts += 1
69+
70+
for i in range(numParts):
71+
print(f"Writing part {i+1} of {numParts}")
72+
remainingSize = file_length - (i * PART_SIZE)
73+
output_file.write(self.rfile.read(min(PART_SIZE, remainingSize)))
74+
6075
self.send_response(201, 'Created')
6176
self.end_headers()
6277

6378
print(f"File of size {file_length} bytes saved to {filePath}")
79+
print()
6480

6581
# Treat PUT just like POST
6682
def do_PUT(self):

0 commit comments

Comments
 (0)