Search code examples
python-3.xsocketshttptcp

My HTTP response from custom web server doesn't get recognized as a HTTP message


I was learning about sockets and socket programming from a book and I wanted to experiment by creating a simple web server. Here's the code:

import socket

welcomingSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
welcomingSocket.bind(('', 80))

welcomingSocket.listen(1)

while True:
    connectionSocket, addr = welcomingSocket.accept()

    request = connectionSocket.recv(1024)

    #Doesn't get recognised as an http message by wireshark
    response = "HTTP/1.1 200 OK\r\n\
Date: Mon, 27 Jul 2009 12:28:53 GMT\r\n\
Server: Apache/2.2.14 (Win32)\r\n\
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT\r\n\
Content-Length: 88\r\n\
Content-Type: text/html\r\n\
Connection: Closed\r\n\
\r\n\
<html>\r\n\
<body>\r\n\
<h1>Hello, World!</h1>\r\n\
</body>\r\n\
</html>\r\n\
\r\n"

    connectionSocket.send(response.encode())
    connectionSocket.close()

Everything works okay except that when I access my IP through a browser, I can't see the website. Moreover, I used Wireshark to see what's going on and saw that my response is not recognized by Wireshark as an HTTP message, only as a TCP segment.

I really want to know why it doesn't work. Is it because the dates I send are not correct or maybe the formatting of the message is off?

Btw. I copied this HTTP response message from a webpage.


Solution

  • I could get it to work with this (port changed such that it runs as a regular user under Linux :) )

    import socket
    
    welcomingSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    welcomingSocket.bind(('127.0.0.1', 8196))
    
    welcomingSocket.listen(1)
    
    while True:
        connectionSocket, addr = welcomingSocket.accept()
    
        request = connectionSocket.recv(1024)
    
        response = "HTTP/1.1 200 OK\r\n\
    Date: Mon, 27 Jul 2009 12:28:53 GMT\r\n\
    Server: Apache/2.2.14 (Win32)\r\n\
    Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT\r\n\
    Content-Length: 60\r\n\
    Content-Type: text/html\r\n\
    Connection: Closed\r\n\
    \r\n\
    <html>\r\n\
    <body>\r\n\
    <h1>Hello, World!</h1>\r\n\
    </body>\r\n\
    </html>\r\n\
    \r\n"
    
        connectionSocket.send(response.encode())
        connectionSocket.close()
    

    Basically, the error was in the line

    Content-Length: 88

    That needs to be 60.

    It is the wrong length causing Chromium to refuse the page (it tells you about it in it's web developer tools including a specific and helpful error message). Interestingly, Firefox displays the original variant (with the wrong content length) without issues here.

    Having changed the content length, Wireshark also accepts it as HTTP :)