12

Consider the following example:

import string,cgi,time
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

class MyHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        try:
            if self.path.endswith(".html"):
                f = open(curdir + sep + self.path) #self.path has /test.html
#note that this potentially makes every file on your computer readable by the internet

                self.send_response(200)
                self.send_header('Content-type',    'text/html')
                self.end_headers()
                self.wfile.write(f.read())
                f.close()
                return

        except IOError:
            self.send_error(404,'File Not Found: %s' % self.path)


def main():
    try:
        server = HTTPServer(('', 80), MyHandler)
        print 'started httpserver...'
        server.serve_forever()
    except KeyboardInterrupt:
        print '^C received, shutting down server'
        server.socket.close()

if __name__ == '__main__':
    main()

What if I want to server a ZIP file also... how would I do that? I don't think this line would work right?

self.wfile.write(f.read())
carrier
  • 32,209
  • 23
  • 76
  • 99
  • 1
    Can someone explain why the call to open() "potentially makes every file on your computer readable"? And how would you protect against this for serving files in this example? – brooksbp Oct 28 '11 at 23:42
  • @brooksbp I think he means that the user could type a path that would navigate into another directory on your computer, for example going up one or more directories. But only html files could be accessed using the above code. – Anthony Jan 25 '16 at 21:37

3 Answers3

10

Pass binary as a parameter to open(). This:

f = open(curdir + sep + self.path, 'rb')

Instead of this:

f = open(curdir + sep + self.path)

UNIX doesn't distinguish between binary and text, but windows does. But if the script executes on UNIX, the "b" will just be ignored so you're safe.

JosefAssad
  • 4,018
  • 28
  • 37
  • 2
    And in Python 3, Python makes a difference between binary and text files, so you might as well put the correct flag there already now. :) – Lennart Regebro Jul 07 '09 at 19:21
4

Your line would work just fine. The problem would be setting the Content-type appropriately. You'd want to set it to application/zip instead of text/html.

Eli Courtwright
  • 186,300
  • 67
  • 213
  • 256
  • 1
    that's true, but i had already done that. JosefAssad identified the problem i was having. But you're correct. – carrier Jul 07 '09 at 19:31
3

If you want to share files in a folder of any type, then you can also try typing the command

python -m SimpleHTTPServer

This will start the server at port 8000 and you can browse the files (via directory listing)

nibin012
  • 1,793
  • 2
  • 15
  • 14