Lets say we have an image in png format called image.png and we want to transfer it over http to a client (e.g. Webbrowser).
import socket
def getPic():
filebuffer = ""
header = "HTTP/1.1 200 OK\r\nContent-type: image/png\r\n\r\n"
sfile = open("image.png", "rb")
filebuffer = sfile.read()
sfile.close()
return header, filebuffer
def main():
sockobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockobj.bind(('localhost',8080))
sockobj.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sockobj.listen(1)
while True:
conn, address = sockobj.accept()
data = conn.recv(1024)
head, data = getPic()
if str(type(data)).find("str") > -1:
conn.sendall(bytes(head + data, "ASCII"))
#Since the most text files are in UTF-8 encoding, you can use the following instead:
#conn.sendall(bytes(head, "ASCII") + bytes(data, "UTF-8"))
else:
conn.sendall(bytes(head, "ASCII") + data)
conn.close()
main()
Please note the following codes cut out from above code:
header = "HTTP/1.1 200 OK\r\nContent-type: image/png\r\n\r\n"
sfile = open("image.png", "rb")
filebuffer = sfile.read()
sfile.close()
return header, filebuffer
head, data = getPic()
if str(type(data)).find("str") > -1:
conn.sendall(bytes(head + data, "ASCII"))
else:
conn.sendall(bytes(head, "ASCII") + data)
Why do you check, if the response body is in string or bytes?
Without that I get an error, if I open a text file with the code above. So I decided to encode all plain text to the ASCII character set.
Why are the http headers in ASCII coding?
Because it's specified in a W3C specification
Why takes the return statement two values
It cleans up the code when doing so and you can't combine strings with bytes together that would not work.
How to tell the client that I am going to send an image in png format?
The W3C has a solution for that called MIME types, these are a set of predefined and extensionable values for various file format. E.g. image/png says the browser that he gets a image file in .png format. For javascript it would be application/javascript and so on