Search code examples
pythonfilesizemaxbasehttpserver

python BaseHTTPServer file upload with maxfile-size


If the file is to big i dont want to download it to my server and then delete it, I just want to tell the user that the file is to big. this code almost accomplish this. if the file is smaller than 10 mb it get upload and the user get a response that the file has been uploaded. but if the file is larger than 10 mb the user dont get any response, the browser just says that it has lost the connection with the server.

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler

import cgi

class StoreHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        if int(self.headers['content-length']) > 10000000:
            print "file to big"
            self.send_response("file to big")
            return

        else:
            form = cgi.FieldStorage(
                fp=self.rfile,
                headers=self.headers,
                environ={'REQUEST_METHOD':'POST',
                         'CONTENT_TYPE':self.headers['Content-Type'],
                         })
            filename = form['file'].filename
            data = form['file'].file.read()
            open("/tmp/%s"%filename, "wb").write(data)
            print self.headers['content-length']
            self.respond("uploaded %s, thanks")

    def do_GET(self):
        response = """
        <html><body>
        <form enctype="multipart/form-data" method="post">
        <p>File: <input type="file" name="file"></p>
        <p><input type="submit" value="Upload"></p>
        </form>
        </body></html>
        """        

        self.respond(response)

    def respond(self, response, status=200):
        self.send_response(status)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-length", len(response))
        self.end_headers()
        self.wfile.write(response)  


server = HTTPServer(('', 8080), StoreHandler)
server.serve_forever()

Solution

  • You have got to read all request data in any case. Otherwise HTTP client (browser) just don't get it.

    In first case when file is too big, you can just read and ignore data.

    Here is updated StoreHandler:

    class StoreHandler(BaseHTTPRequestHandler):
        def do_POST(self):
            length = int(self.headers['content-length'])
            print length
            if length > 10000000:
                print "file to big"
                read = 0
                while read < length:
                    read += len(self.rfile.read(min(66556, length - read)))
                self.respond("file to big")
                return
            else:
                form = cgi.FieldStorage(
                    fp=self.rfile,
                    headers=self.headers,
                    environ={'REQUEST_METHOD':'POST',
                             'CONTENT_TYPE':self.headers['Content-Type'],
                             })
                filename = form['file'].filename
                data = form['file'].file.read()
                open("/tmp/%s"%filename, "wb").write(data)
                print self.headers['content-length']
                self.respond("uploaded %s, thanks")