MeatBALL
MeatBALL

Reputation: 65

HTTP Server with python sockets

I wrote a code of a Server that uses HTTP protocol to communicate with chrome browser, and for some reason I am getting an Exception.

the exception is an index out of bound exception but the server still gives a response to chrome and I can see the answer on the html file displayed on the screen. (the exception is in recv in the function get_clients_req()).

I would be happy if someone could explain me why.

import socket

IP = '127.0.0.1'
PORT = 80


def get_clients_req(client):
    recv = client.recv(2 ** 16).decode()
    recv = recv.split('\n')[0].split('/')
    recv = recv[1].split(' ')[0].split('?')
    return recv[0], recv[1].split('&')


def clean_data(request, params):
    valid = False
    clean_params = []
    error_msg = 'Not Valid Request'
    if request == 'calculate-area' and len(params) == 2:
        if 'height' in params[0] and 'width' in params[1]:
            print(params[0], params[1])
            valid = True
            error_msg = 'Everything is just Fine <3<3'
            clean_params.append(params[0].replace('height=', ''))
            clean_params.append(params[1].replace('width=', ''))
            print(clean_params[0], clean_params[1])
        else:
            valid = False
            error_msg = 'Parameters are not valid'
            clean_params = []
    else:
        valid = False
        error_msg = 'Request is not valid'
        clean_params = []
    return (valid, error_msg, clean_params)


def handle_request(client, clean_params):
    area = int(clean_params[0]) * int(clean_params[1]) / 2
    data = 'HTTP/1.1 200 OK \r\n'
    data = 'HTTP/1.1 200 OK \r\n'
    data += 'Connect-Type: text/html; charset=utf-8\r\n'
    data += '\r\n'
    data += f'<html><body>{area}</body></html>\r\n\r\n'
    client.sendall(data.encode())
    client.shutdown(socket.SHUT_WR)


server = socket.socket()
server.bind((IP, PORT))
server.listen()

print(f'URL: {IP}:{PORT}')

while 1:
    client, client_add = server.accept()
    request, params = get_clients_req(client)
    (valid, error_msg, clean_params) = clean_data(request, params)
    handle_request(client, clean_params)

the exception:

Traceback (most recent call last):
  File "C:/Users/orlav/PycharmProjects/networks_book/chapter_4/e4.8.py", line 56, in <module>
    request, params = get_clients_req(client)
  File "C:/Users/orlav/PycharmProjects/networks_book/chapter_4/e4.8.py", line 11, in get_clients_req
    return recv[0], recv[1].split('&')
IndexError: list index out of range

Upvotes: 1

Views: 608

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123320

recv = recv[1].split(' ')[0].split('?')
return recv[0], recv[1].split('&')

There is no recv[1] in the last line if there is no ? in the original request, which causes the stack trace you see. While you don't show the original request you intended to send, the browser will often try to access some /facicon.ico by itself and this request has no ?.

Upvotes: 1

Related Questions