0

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)
Amir
  • 10,600
  • 9
  • 48
  • 75
Aditya
  • 1,240
  • 2
  • 14
  • 38
  • Is this Python 2? I assume you're running as root / admin, since you're using port 80; have you tried another port eg, 8080? How about sending a Content-Length header? – PM 2Ring Jan 02 '16 at 01:58
  • Also, if you're simply trying to send files over HTTP, you may be better off letting `# python -m SimpleHTTPServer 80` (`# python3 -m http.server 80` in Python 3) handle that task for you – asamarin Jan 02 '16 at 02:02
  • Sending content-length solved the problem @PM2Ring. However the file name is still some arbitary thing in firefox and in chrome it's still download.png. – Aditya Jan 02 '16 at 02:11
  • The filename in your disposition needs double-quotes: `\"s.png\"`. See http://stackoverflow.com/q/13307499/4014959 – PM 2Ring Jan 02 '16 at 02:34
  • @PM2Ring Really? [RFC 6266](http://www.ietf.org/rfc/rfc6266.txt) has an example without quotes. – MikeCAT Jan 02 '16 at 02:39

1 Answers1

2
  • 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()
MikeCAT
  • 73,922
  • 11
  • 45
  • 70