-1

Trying to convert some old code from python 2.x to 3.9. Building a simple web server, works as far as going to localhost:8000 and showing the 404 intended. But when I actually try to access localhost:8000/file.html with it then I get an error.

Error:

line 17, in <module>
connectionSocket.send(outputdata[i])
TypeError: a bytes-like object is required, not 'str'

Whole code:

from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
serverPort = 8000
serverSocket.bind(('', serverPort))
serverSocket.listen(1)

while True:
    print('Ready to serve...')

    connectionSocket, addr = serverSocket.accept()
    try:
        message = connectionSocket.recv(1500)
        filepath = message.split()[1]
        f = open(filepath[1:])
        outputdata = f.read()
        for i in range(0, len(outputdata)):
            connectionSocket.send(outputdata[i])
        connectionSocket.send("\r\n")

        connectionSocket.close()

    except IOError:
        bytes('', 'UTF-8')
        connectionSocket.send(bytes("HTTP/1.1 404 Not Found\r\n\r\n", "UTF-8"))
        connectionSocket.send(bytes("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n", "UTF-8"))

        connectionSocket.close()
serverSocket.close()

Would really appreciate some help.

1 Answers1

-1

The error is saying you can't send text over a binary socket.

You're opening the file without a mode set, so it defaults to rt (read text).

with open(filepath[1:], "rb") as f:
    outputdata = f.read()
    connectionSocket.sendall(outputdata)
connectionSocket.sendall(b"\r\n")

would be the efficient way to send the file over (so long as it fits in memory, since .read() reads it all first).

The same stands for the final b"\r\n" -- that too needs to be binary.

AKX
  • 152,115
  • 15
  • 115
  • 172
  • My browser is saying "ERR_INVALID_HTTP_RESPONSE". But at least the server didn't crash – SilverGear64 Sep 06 '21 at 17:38
  • Yeah, you're not sending any HTTP response headers, so you're not talking valid HTTP. – AKX Sep 06 '21 at 17:39
  • I see. How would I fix it? Something I need to add to add the start of the code I'm guessing? – SilverGear64 Sep 06 '21 at 17:41
  • You'd study the HTTP spec to see what a response message looks like. You're already sending one as the 404 message - for a "here's a file" response, you'd start with `b'HTTP/1.1 200 OK\r\n\r\n'` and then send some data... – AKX Sep 06 '21 at 17:42