Priyansh Gupta
Priyansh Gupta

Reputation: 99

How to send an HTTP Response for an incoming request using python sockets

I have the a python server coded to work on http://127.0.0.1:9999/. The server prints out the incoming http request. I have also coded on what headers to be sent during the response and also the content. Here is the code:

import socket
from time import sleep
c = None #Client socket1
addr = None #Client address1
    
server_socket1 = socket.socket() #by default it is SOCK_STREAM (TCP) and has porotocal AF_INET (IPv4) 

server_socket1.bind(('127.0.0.1',9999)) #server machine's ip and port on which it will send and recieve connections from

server_socket1.listen(2) #We will only accept two connections as of now , one for each client
print("Server started successfully!!!")
print("Waiting for connections...\n\n")

while (((c is None)and(addr is None))):
    if((c is None) and (addr is None)):
        c,addr = server_socket1.accept()
        print("User connected to client1 socket!!")
        c.send(bytes("Connected to the apps server!!!","utf-8"))
        print("Client connected ip address "+str(addr))
        

        
while True:
    msg = c.recv(4096)
    if(msg!=None):
            #print(msg)
            headers, sep, body = msg.partition(b'\r\n\r\n')
            headers = headers.decode('utf-8') 
            print(headers)

            html_body = "<html><body><h1>This is a test</h1><p>More content here</p></body></html>"
            response_headers = {
            'Content-Type': 'text/html; encoding=utf8',
            'Content-Length': len(html_body),
            'Connection': 'close',
            }

            response_headers_raw = ''.join('%s: %s\r\n' % (k, v) for k, v in response_headers.items())
            response_proto = 'HTTP/1.1'
            response_status = '200'
            response_status_text = 'OK' # this can be random

            # sending all this stuff
            r = '%s %s %s\r\n' % (response_proto, response_status, response_status_text)
            c.sendall(r.encode())
            c.sendall(response_headers_raw.encode())
            c.sendall(b'\r\n') # to separate headers from body
            c.send(html_body.encode(encoding="utf-8"))

            sleep(5)

The code works without compilation errors, starts the server and captures the request i send from the browser intended. But, while sending the response, the socket connection closes with an error as [WinError 10053] An established connection was aborted by the software in your host machine.

Request sent from the browser :

enter image description here

The Output in the terminal :

Error while sending response to the browser

The error displayed in browser :

Browser window

What may be causing this error? Previously python prompted me with an error that the object must be a byte type and not type 'str' while sending response_headers_raw variable. Hence I used the encode() function to convert it to a byte type object which has led me to this error.

Any solutions would be greatly appreciated!

~regards

Upvotes: 0

Views: 2638

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123320

    c,addr = server_socket1.accept()
    print("User connected to client1 socket!!")
    c.send(bytes("Connected to the apps server!!!","utf-8"))

You send "Connected to the apps server!!!" to the client immediately after connect. The client is expecting a HTTP response though. Since it gets your non-HTTP data the client closes the connection. Later c.sendall will write to a socket closed by the peer which results in "An established connection was aborted".

In addition to this ...

msg = c.recv(4096)
if(msg!=None):
        #print(msg)
        headers, sep, body = msg.partition(b'\r\n\r\n')

Your expectation seems to be that c.recv will return None when the socket is closed. This is not true, it will return '' instead. This means that even after the first error is fixed your code will again run into a similar problem if the peer has closed the connection after successfully reading the request and sending the response.

Upvotes: 1

Related Questions