Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would I create a Python web server that downloads a file on any GET request?

I am attempting to create an easy solution to file sharing across computers in my local network. I used to execute python -m SimpleHTTPServer in bash whenever I wanted to share a directory, but I wanted a way to share only one specific file. Can anyone point me in the right direction for how I might create a web server, and then have it download a file for each GET request. For example, someone on my network could go to my IP and have the file download.

P.S. What would be even cooler is if there was a way to password protect a file! Also, I have Python 2.7.2, if that matters. Anyway, As you have probably noticed, I know almost nothing about Python, but I learn by example so I am hoping this will help me some as well.

Thanks a bunch in advance!

like image 253
russellsayshi Avatar asked Jan 13 '23 12:01

russellsayshi


1 Answers

Try following:

try:
    import http.server as BaseHTTPServer  # Python 3.x
except ImportError:
    import BaseHTTPServer  # Python 2.x
import os
import shutil
import sys

FILEPATH = sys.argv[1] if sys.argv[1:] else __file__

class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        with open(FILEPATH, 'rb') as f:
            self.send_response(200)
            self.send_header("Content-Type", 'application/octet-stream')
            self.send_header("Content-Disposition", 'attachment; filename="{}"'.format(os.path.basename(FILEPATH)))
            fs = os.fstat(f.fileno())
            self.send_header("Content-Length", str(fs.st_size))
            self.end_headers()
            shutil.copyfileobj(f, self.wfile)

def test(HandlerClass=SimpleHTTPRequestHandler,
         ServerClass=BaseHTTPServer.HTTPServer,
         protocol="HTTP/1.0"):
    if sys.argv[2:]:
        port = int(sys.argv[2])
    else:
        port = 8000
    server_address = ('', port)

    HandlerClass.protocol_version = protocol
    httpd = BaseHTTPServer.HTTPServer(server_address, HandlerClass)

    sa = httpd.socket.getsockname()
    print("Serving HTTP on {0[0]} port {0[1]} ... {1}".format(sa, FILEPATH))
    httpd.serve_forever()

if __name__ == '__main__':
    test()

Usage: python script_path [filepath_to_serve [port]]

UPDATE code works for Python 2.x / 3.x

like image 156
falsetru Avatar answered Jan 17 '23 17:01

falsetru