Skip to content

Instantly share code, notes, and snippets.

@chengscott
Last active October 14, 2023 21:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chengscott/a3454a576472f5779fe66bc103ebca68 to your computer and use it in GitHub Desktop.
Save chengscott/a3454a576472f5779fe66bc103ebca68 to your computer and use it in GitHub Desktop.
#!/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.
"""
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)
filename = filename.replace('%20', '_')
# 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'])
with open(filename, 'wb') as output_file:
output_file.write(self.rfile.read(file_length))
self.send_response(201, 'Created')
self.end_headers()
reply_body = 'Saved "%s"\n' % filename
self.wfile.write(reply_body.encode('utf-8'))
if __name__ == '__main__':
server.test(HandlerClass=HTTPRequestHandler)
#!/usr/bin/env python
import os
import http.server 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.join(os.getcwd(), self.path[1:])
filename = filename.replace('%20', '_')
os.makedirs(os.path.dirname(filename), exist_ok=True)
# 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'])
with open(filename, 'wb') as output_file:
output_file.write(self.rfile.read(file_length))
self.send_response(201, 'Created')
self.end_headers()
reply_body = 'Saved "%s"\n' % filename
self.wfile.write(reply_body.encode('utf-8'))
if __name__ == '__main__':
server.run(server.ThreadingHTTPServer, HTTPRequestHandler)
from itertools import filterfalse, tee
import os
import requests
url = 'http://10.0.0.1:8000/'
def partition(pred, iterable):
t0, t1 = tee(iterable)
return filterfalse(pred, t0), filter(pred, t1)
def upload(fname):
with open(fname, 'rb') as f:
data = f.read()
return requests.put(url + fname, data=data)
def try_upload(fname):
try:
return upload(fname)
except:
return fname
def upload_dir(dname):
fs = [os.path.join(dp, f) for dp, dn, filenames in os.walk(dname) for f in filenames]
res = [try_upload(f) for f in fs]
return partition(res, lambda x: isinstance(x, str))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment