lundi 7 juin 2021

Web server Python testing

I have this simple Python script that allows to create a web proxy multithreaded server. This can accept HTTP requests from multiple clients (one thread for every client). My question is: How can I test this proxy server on Google Chrome? I get ERR_PROXY_CONNECTION_FAILED when i try to setup the proxy connection on Chrome, so I don't know what to do.

import sys, time, re, threading
from socket import *

if len(sys.argv)==2:
    server_port=int(sys.argv[1])
else:
    server_port=8080
logger_file_name="log.txt"

class Server:
    def __init__(self):
        try:
            self.server_socket=socket(AF_INET, SOCK_STREAM) 
            self.server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        except error as e:
            print ('Unable to create/re-use the socket. Error: %s' % e)
            message='Unable to create/re-use the socket. Error: %s ' % e
            self.log_info(message)
        self.server_socket.bind(('', server_port))
        self.server_socket.listen(5)
        message="Host Name : Localhost and Host address: 127.0.0.1 and Host port: " + str(server_port)+ "\n"
        self.log_info(message)
        print ("Server is ready to listen for clients")



    def listen_to_client(self):
        while True:
            client_connection_socket, client_address=self.server_socket.accept()
            client_details_log= "Client details: \n"
            client_details_log+= "Client host name: "+ str(client_address[0]) +"\nClient port number: "+ str(client_address[1]) + "\n"
            client_details_log+="Timeout: "+str(client_connection_socket.gettimeout())+"\n"
            self.log_info(client_details_log)

            d=threading.Thread(name=str(client_address), target=self.proxy_thread, args=(client_connection_socket, client_address))

            d.daemon=True
            d.start()
        self.server_socket.close()
    def proxy_thread(self, client_connection_socket, client_address):

        start_time=time.time() 
        client_request=client_connection_socket.recv(1024)
        if client_request:
            request_length=len(client_request)
            message="Client with port: "+str(client_address[1]) +" request length is"+str(request_length)+" bytes \n"
            self.log_info(message)

            message="Client with port: "+str(client_address[1])+ " generated request: "+ str(client_request).splitlines()[0]+ "\n"
            self.log_info(message)
            resp_part=client_request.split(' ')[0] 
            if resp_part=="GET":
                http_part=client_request.split(' ')[1]
                double_slash_pos=str(http_part).find("//") 
                url_connect=""
                url_slash_check=list()
                url_slash=str()
                if double_slash_pos == -1:
                    url_part=http_part#[1:]
                    url_connect=url_part.split('/')[0]
                else:
                    if http_part.split('//')[1][-1]=="/":
                        url_part=http_part.split('//')[1][:-1]
                        url_connect=url_part.split('/')[0]

                url_slash_check=url_part.split('/')[1:]
                url_slash=""
                if url_slash_check:
                    for path in url_slash_check:
                        url_slash+="/"
                        url_slash+=path
                client_request_port_start=str(url_part).find(":")
                port_number=80
                url_file_name=re.sub('[^0-9a-zA-Z]+', '_', url_part)
                if client_request_port_start ==-1:
                    pass
                else:
                    port_number=int(url_part.split(':')[1])
                self.find_file(url_file_name, client_connection_socket, port_number, client_address, start_time, url_connect, url_slash)
            else:
                message="Client with port: "+str(client_address[1])+" generated a call other than GET: "+ resp_part + " \n"
                client_connection_socket.send("HTTP/1.1 405 Method Not Allowed\r\n\r\n")#fine dell'header http
                client_connection_socket.close()
                self.log_info(message)
                message="HTTP/1.1 405 Method Not Allowed\r\n\r\n"
                self.log_info(message)
        else:
            client_connection_socket.send("")
            client_connection_socket.close()
            message="Client with port: "+str(client_address[1])+ " connection closed \n"
            self.log_info(message)
    def find_file(self, url_file_name, client_connection_socket, port_number, client_address, start_time, url_connect, url_slash):
        try:
            cached_file=open(url_file_name, "r")
            message="Client with port: " + str(client_address[1]) +": Cache hit occurred for the request. Reading from file \n"
            self.log_info(message)
            server_details_message="<body> Cached server details:- <br>"#modificato
            server_details_message+="Server host name: localhost <br> Server port number: "+ str(port_number) +" <br>"
            server_details_message+="Timeout: "+str(client_connection_socket.gettimeout())+"<br> </body>"
            response_message=""
            with open(url_file_name) as f:
                for line in f:
                    response_message+=line
            response_message+=server_details_message
            cached_file.close()

            client_connection_socket.send(response_message)
            end_time=time.time()
            message="Client with port: "+ str(client_address[1])+": Response length: "+str(len(response_message))+" bytes\n"
            self.log_info(message)
            message="Client with port: "+str(client_address[1])+" Time elapsed(RTT): "+str(end_time-start_time)+" seconds \n"
            self.log_info(message)
        except IOError as e:
            message="Client with port: "+str(client_address[1])+" Cache miss occurred for the request. Htting web server \n"
            self.log_info(message)
            
            proxy_connection_socket=None
            try:
                
                proxy_connection_socket=socket(AF_INET, SOCK_STREAM)
                
            except error as e:
                print ('Unable to create the socket. Error: %s' % e)
                message='Unable to create the socket. Error: %s' % e
                self.log_info(message)
            try:
                proxy_connection_socket.settimeout(2)
                
                proxy_connection_socket.connect((url_connect, port_number))
               
                web_request=str()
                if url_slash:
                    web_request=b"GET /" + url_slash[1:] + " HTTP/1.1\nHost: " + url_connect + "\n\n"#stringa di byte
                else:
                    web_request=b"GET / HTTP/1.1\nHost: " + url_connect + "\n\n"

                
                proxy_connection_socket.send(web_request)
                message="Client with port: "+str(client_address[1])+ " generated request of length to web server "+str(len(web_request))+" bytes \n"
                self.log_info(message)
                message="Client with port: "+str(client_address[1])+ " generated request to web server as: "+str(web_request)+" \n"
                self.log_info(message)
                
                server_details_message="<body> Web server details:- <br>"
                server_details_message+="Server host name: "+url_connect+" <br> Server port number: "+str(port_number)+" <br>"
                server_details_message+="Timeout: "+str(client_connection_socket.gettimeout())+"<br> </body>"
                web_server_response_append=""
                
                timeout_flag=False
                while True:
                    try:
                        web_server_response=proxy_connection_socket.recv(4096)
                    except timeout:
                        
                        if len(web_server_response_append)<=0:
                            timeout_flag=True
                        break
                    if len(web_server_response)>0:
                        web_server_response_append+=web_server_response
                    else:
                        
                        break
               
                response_to_file=web_server_response_append
                
                web_server_response_append+=server_details_message
                if timeout_flag:
                    
                    error_response="HTTP/1.1 408 Request timeout\r\n\r\n"
                    error_response+=server_details_message
                    client_connection_socket.send(error_response)
                else:
                    
                    client_connection_socket.send(web_server_response_append)
                end_time=time.time()
                message="Client with port: "+str(client_address[1])+" Time Elapsed(RTT): "+str(end_time-start_time) + " seconds \n"
               
                self.log_info(message)
                
                proxy_temp_file=open(url_file_name, "wb")#apro il file in modalità binaria e scrittura
                
                proxy_temp_file.write(response_to_file)
                proxy_temp_file.close()
                message="Client with port: "+str(client_address[1])+" got response of length "+str(len(response_to_file))+" bytes \n"
                self.log_info(message)
                
                proxy_connection_socket.close()
            except error as e:
                
                error_message="HTTP/1.1 404 Not Found\r\n\r\n"
                client_connection_socket.send('HTTP/1.1 404 Not Found\r\n\r\n')
                end_time=time.time()
                message="Client with port: "+str(client_address[1])+" Following error occureed : "+str(e)+"\n"
                self.log_info(message)
                message="Client with port: "+str(client_address[1])+" response sent: "+error_message+" \n"
                self.log_info(message)
                message="Client with port: "+str(client_address[1])+" Time elapsed(RTT): "+str(end_time-start_time)+" seconds \n"
                self.log_info(message)
  
        client_connection_socket.close()
        message="Client with port: "+str(client_address[1])+" connection closed \n"
        self.log_info(message)
    def log_info(self, message):
        logger_file=open(logger_file_name, "a")
        logger_file.write(message)
        logger_file.close()
if __name__ == "__main__":
    server=Server()
    server.listen_to_client()



Aucun commentaire:

Enregistrer un commentaire