Send text "http" over python socket

13,073

You are not returning a correctly formed HTTP response. Your line

connectionSocket.send('HTTP/1.1 200 OK text/html') ## this is not working

is not even terminated by a newline, then immediately followed by the content of your file. Protocols like HTTP specify fairly rigorously what must be sent, and I find it little short of miraculous that you saw anything at all in your browser.

Try something like:

connectionSocket.send('HTTP/1.1 200 OK\nContent-Type: text/html\n\n')

This is the start of a correctly-formed HTTP 1.1 response with a primary response line and a single header. The double newline terminates the headers, preparing the client to read the content that follows.

http://www.jmarshall.com/easy/http/ is one of many approachable ways to learn a bit more about the protocol you have chosen to use. Good luck!

Share:
13,073
Gopikrishna S
Author by

Gopikrishna S

Updated on June 05, 2022

Comments

  • Gopikrishna S
    Gopikrishna S almost 2 years

    I am trying to create a HTTP server using python. The thing is I am getting everything to work except for sending a response message; if the message has a text http, the send() doesn't work.

    Here is the snippet of the code:

    connectionSocket.send('HTTP/1.1 200 OK text/html')
    

    Here are the others I tried:

    connectionSocket.send(''.join('%s 200 OK text/html' % ('HTTP/1.1')))
    connectionSocket.send('%s 200 OK text/html' % ('HTTP/1.1'))
    msg = 'HTTP/1.1 200 OK text/html'
    for i in range(0, len(msg))
        connectionSocket.send(msg[i])
    

    The only thing that seems to work is entity-fying the any of the character in HTTP, like

    connectionSocket.send('HTTP/1.1 200 OK text/html')
    

    Where H is equivalent to H. Otherwise the browser doesn't display the header received from the python server socket.

    The problem also goes when I am trying to send a 404 Message down the socket. The other contents are displayed, however, like a html file sent through the socket.

    I want to know is there a proper way to do it? Because, if the client is not a browser, the html entity will not be understood.

    Thanks in advance

    Update:

    Code:

    from socket import *
    serverSocket = socket(AF_INET, SOCK_STREAM)
    
    serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    serverSocket.bind(('127.0.0.1', 1240))
    serverSocket.listen(1);
    
    while True:
      print 'Ready to serve...'
      connectionSocket, addr = serverSocket.accept()
      try:
        message = connectionSocket.recv(1024)
        filename = message.split()[1]
        f = open(filename[1:])
        outputdata = f.read()
    
        #Send one HTTP header line into socket
        connectionSocket.send('HTTP/1.1 200 OK text/html') ## this is not working
    
        #Send the content of the requested file to the client
        for i in range(0, len(outputdata)):
            connectionSocket.send(outputdata[i])
        connectionSocket.close()
    
      except IOError:
        connectionSocket.send('HTTP/1.1 404 File not found') ## this is not working
        connectionSocket.close();
    

    serverSocket.close()

    Screenshots:

    Text as 'HTTP/1.1 ...'

    enter image description here

    enter image description here

    Text as 'HTTP/1.1 ...'

    enter image description here

    enter image description here

    HTML Code of hello.html

    <html>
      <head>
        <title>Test Python</title>
      </head>
      <body>
        <h1>Hello World!</h1>
      </body>
    </html>
    
  • Gopikrishna S
    Gopikrishna S about 10 years
    The library is socket. from socket import *. And can you be more clear please, I can't understand whether you are saying the format is correct or not. "The quoted version (&#72;TTP...) probably is not recognized by the HTTP protocol in the browser" -- the quoted version is what works. Others dont.
  • holdenweb
    holdenweb about 10 years
    connection_socket is the socket returned by an accept() call in the code. This is not the issue.
  • Alfe
    Alfe about 10 years
    Yeah, my idea was wrong, obviously, if you are using socket.socket directly. I thought giving the HTTP explicitly additionally to an implicit HTTP the presumed underlying library produces automatically (which is of course not the case with socket.socket) would lead to a doubling and thus to a problem. Then giving it in a quoted form explicitly would have left the implicit part intact and thus cloaked the problem. You didn't say so right away, but now I guess that without the quoted version (i.e. also without an unquoted version) it also doesn't work. Am I right?
  • Gopikrishna S
    Gopikrishna S about 10 years
    Thanks, that worked pretty well. I used connectionSocket.send('HTTP/1.1\n\n 200 OK Content-Type: text/html'); and it displayed everything from 200 to text/html. However, it didn't display the HTTP/1.1, as you guys said, it is stripped out.
  • holdenweb
    holdenweb about 10 years
    The "\n\n" is terminating the HTTP response early. Take a look at tcpipguide.com/free/t_HTTPResponseMessageFormat.htm to discover what you should be sending - it's very important to stick to the correct format here, you cannot just make it up as you go along, and a little reading will save you a lot of time.