Search code examples
pythonsocketsgoogle-chromefirefoxhttpserver

A simple HTTP server I built in Python works for Chrome but not in Firefox


So I built a very simple HTTP server in Python. It's purpose is to send a file when it gets a request.

This works in chrome but in Firefox it keeps downloading without making any progress. I also noticed that in Chrome, the name of the downloaded file is download.png where as the actual name of the file is s.png. Could someone tell me what is wrong with this code? Also I tried printing a message and sending html code too in firefox, it just keeps on showing the message "waiting on localhost" and does nothing.

import socket
serversocket = socket.socket()
serversocket.bind(("127.0.0.1", 80))
serversocket.listen(800)
msg = open("s.png", "r").read()
msg =  "HTTP/1.0 200 OK\r\nServer: ls\r\nContent-Type: image/png\r\nContent-Disposition: attachement\r\nfilename: s.png\r\n\r\n" + msg + "\r\n\r\n"
while 1:
    (clientsocket, address) = serversocket.accept()
    clientsocket.send(msg)

Solution

    • Do not insert newline between Content-Disposition and the name of the file.
    • Using : between filename and the name of the file is also wrong.
    • I think you shouldn't add useless newlines after the image data.
    • Using binary mode is good for reading binary files.
    • You should close the connection after sending the message. Otherwise, the client cannot tell where the end of file is because you didn't send Content-Length header.
    • It seems good for Firefox to read the request before sending the response.

    Try this (tested with Python 3.4.2 and Python 2.7.11):

    import socket
    serversocket = socket.socket()
    serversocket.bind(("127.0.0.1", 80))
    serversocket.listen(800)
    msg = open("s.png", "rb").read()
    msg = "HTTP/1.0 200 OK\r\nServer: ls\r\nContent-Type: image/png\r\nContent-Disposition: attachement; filename=s.png\r\n\r\n".encode('UTF-8') + msg
    while True:
        (clientsocket, address) = serversocket.accept()
        recvdata = ''.encode('UTF-8')
        while True:
            recvdata += clientsocket.recv(4096)
            if "\r\n\r\n".encode('UTF-8') in recvdata:
                break
        clientsocket.send(msg)
        clientsocket.close()