Last active
November 13, 2024 15:18
-
-
Save darkr4y/761d7536100d2124f5d0db36d4890109 to your computer and use it in GitHub Desktop.
python simple http server with upload & download
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
"""Extend Python's built in HTTP server to save files | |
curl or wget can be used to send files with options similar to the following | |
curl -X PUT --upload-file somefile.txt http://localhost:8000 | |
wget -O- --method=PUT --body-file=somefile.txt http://localhost:8000/somefile.txt | |
__Note__: curl automatically appends the filename onto the end of the URL so | |
the path can be omitted. | |
Windows upload & download | |
powershell -ep bypass -c "$wc=New-Object Net.WebClient;$wc.UploadFile('http://target.com/upload.bin', 'PUT', 'c:\\upload.bin');" | |
powershell -ep bypass -c "$wc=New-Object Net.WebClient;$wc.DownloadFile('http://target.com/download.bin','c:\\download.bin');" | |
Linux upload & download | |
curl -X PUT --upload-file upload.bin http://target.com/upload.bin | |
wget -O- --method=PUT --body-file=upload.bin http://target.com/upload.bin | |
wget http://target.com/download.bin -O /tmp/download.bin | |
curl http://target.com/download.bin -o /tmp/download.bin | |
""" | |
import os | |
try: | |
import http.server as server | |
except ImportError: | |
# Handle Python 2.x | |
import SimpleHTTPServer as server | |
class HTTPRequestHandler(server.SimpleHTTPRequestHandler): | |
"""Extend SimpleHTTPRequestHandler to handle PUT requests""" | |
def do_PUT(self): | |
"""Save a file following a HTTP PUT request""" | |
filename = os.path.basename(self.path) | |
# Don't overwrite files | |
if os.path.exists(filename): | |
self.send_response(409, 'Conflict') | |
self.end_headers() | |
reply_body = '"%s" already exists\n' % filename | |
self.wfile.write(reply_body.encode('utf-8')) | |
return | |
file_length = int(self.headers['Content-Length']) | |
read = 0 | |
with open(filename, 'wb+') as output_file: | |
while read < file_length: | |
new_read = self.rfile.read(min(66556, file_length - read)) | |
read += len(new_read) | |
output_file.write(new_read) | |
self.send_response(201, 'Created') | |
self.end_headers() | |
reply_body = 'Saved "%s"\n' % filename | |
self.wfile.write(reply_body.encode('utf-8')) | |
def do_GET(self): | |
self.send_response(404, 'Not Found') | |
self.end_headers() | |
self.wfile.write(b'') | |
if __name__ == '__main__': | |
server.test(HandlerClass=HTTPRequestHandler) |
change
with open(filename, 'wb+') as output_file:
while read < file_length:
to
read = 0
with open(filename, 'wb+') as output_file:
while read < file_length:
The rest is good
@baiwfg2 Thank you for comment. The script runs but when you open the link from browser exception happens:
TypeError: a bytes-like object is required, not 'str'
works fine on my pc
$ python3 -V
Python 3.9.9
$ python3 httpsrv.py
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
need more information to debug
@darkr4y It happens when you open the browser
@MChelik updated.
The modified code may break python2
compatibility, and I need to improve it further when I have time.
$ curl -v localhost:8000
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.80.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 404 Not Found
< Server: SimpleHTTP/0.6 Python/3.9.9
< Date: Wed, 05 Jan 2022 09:12:42 GMT
<
* Closing connection 0
$ python3 httpsrv.py
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
::ffff:127.0.0.1 - - [05/Jan/2022 17:12:42] "GET / HTTP/1.1" 404 -
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It has errors with Python3