Web Proxy/WebProxy.py
def start_listen(tcp_socket, client_ip, client_port):
    """ Receive HTTP request message and retrieve the object from cache or server.

    This function could handle different HTTP request message. Especially for
    "Get" method type, proxy will firstly try to find the requested object from
    cache, if not found, proxy than forward the HTTP request message to server
    and then forward the HTTP response message to browser and store the message
    in the cache as well. In addition, "DELETE" method also need to whether the
    object in the cache or not.

    Be careful! The file should be opened in binary mode because we possibly need
    to write or read special type of object, for instance, .jpg, .svg, etc.

    Args:
        :param tcp_socket: the socket which is created from start_server function.
        :param client_ip: IP address of the client.
        :param client_port: Port number of the client.

    Raises:
        IOError, FileNotFoundError: file does not exist.
        ConnectionResetError: client refresh the browser while server still send message.
        TypeError: input format is wrong or empty.
        socket.gaierror: Host name might be wrong.
    """
    # 1. Receive request message from the client on connection socket.
    message = tcp_socket.recv(1024).decode()
    # Create new object (handle_str) from StrProcess class.
    handle_str = StrProcess(message)
    print("client is coming: {addr}:{port}".format(addr = client_ip, port = client_port))
    file_error = False
    global host
    try:
        command = handle_str.get_cmd_type()
        # 2. Extract the path of the requested object from the message (second part of the HTTP header).
        filename = handle_str.change_name()
        # 3. Find the specific method type and handle the request.
        if command == "DELETE" :
            # Delete the object if it exists in cache.
            os.remove("./Cache/" + filename)
            tcp_socket.send(b"HTTP/1.1 200 OK\r\n\r\n")
            print("File is removed.")
        elif command == "GET" or command == "HEAD":
            print("Client want to {c} the {o}.".format(c=command, o=filename))
            # Check whether the requested object exists or not.
            f = open("./Cache/" + filename, "rb")
            file_content = f.readlines()
            f.close()
            if command == "GET":
                print("File in cache!")
                # Find the corresponding file from disk if it exists.
                for i in range(0, len(file_content)):
                    tcp_socket.send(file_content[i])  # Send HTTP response message.
            else:  # "HEAD" method.
                list_to_str = ""
                for i in range(0, len(file_content)):
                    list_to_str += file_content[i].decode()
                HTTP_header_end = list_to_str.find("\r\n\r\n")
                # Only send HTTP response message header lines.
                tcp_socket.send(list_to_str[:HTTP_header_end + 4].encode())
        elif command == "PUT" or command == "POST":  # Only implement upload files.
            f = open("./Cache/" + filename, "ab")
            f.write(b"HTTP/1.1 200 OK\r\n\r\n" + handle_str.get_body().encode())
            f.close()
            print("Update successfully!")
            tcp_socket.send(b"HTTP/1.1 200 OK\r\n\r\n")
            body_re = b"true" if command == "PUT" else handle_str.get_body().encode()
            tcp_socket.send(body_re)
        else:
            tcp_socket.send(b"HTTP/1.1 400 Bad Request\r\n\r\n")
    # 4. If file doesn't exist in the cache, handle exceptions.
    except (IOError, FileNotFoundError):
        if command == "GET":
            # Create a socket on the proxy server.
            c = socket(AF_INET, SOCK_STREAM)
            hostname = handle_str.get_hostname()
            file = handle_str.split_str()[1]
            print("File isn't in the cache!")
            try:
                # Connect to the socket at port 80.
                c.connect((hostname, 80))
                host = hostname  # record the real hostname.
                request = "GET " + "http:/" + file + " HTTP/1.1\r\n\r\n"
            except:
                try:
                    # Need to use the global host or referer hostname.
                    new_host = handle_str.get_referer() if host == "" else host
                    c.connect((new_host, 80))
                    request = "GET " + "http://" + new_host + file + " HTTP/1.1\r\n\r\n"
                except:
                    tcp_socket.send(b"HTTP/1.1 404 Not Found\r\n\r\n")
                    with open("./Cache/NotFound.html", 'rb') as f:
                        file_content = f.readlines()
                    for strline in file_content:
                        tcp_socket.send(strline)
                    file_error = True
            if file_error is False:
                c.sendall(request.encode())
                # Read the response into buffer.
                print("proxyserver have found the host.")
                # Create a new file in the cache for the requested file.
                # Also send the response in the buffer to client socket
                # and the corresponding file in the cache.
                writeFile = open("./Cache/" + filename, "wb")
                print("Poxy server is receiving data...")
                # Receive HTTP response message until all messages are received.
                while True:
                    data = c.recv(4096)
                    if not data:
                        break
                    sys.stdout.write(">")
                    # Send the content of the file to the socket.
                    tcp_socket.sendall(data)
                    writeFile.write(data)
                writeFile.close()
                sys.stdout.write("100%\n")
            c.close()
        elif command == "DELETE":
            tcp_socket.send(b"HTTP/1.1 204 Not Content\r\n\r\n")
    except (ConnectionResetError, TypeError):
        print("Bye to client: {addr}:{port}".format(addr = client_ip, port = client_port))
    # Close the client socket.
    print("tcp socket closed\n")
    tcp_socket.close()
 Receive HTTP request message and retrieve the object from cache or server.

    This function could handle different HTTP request message. Especially for
    "Get" method type, proxy will firstly try to find the requested object from
    cache, if not found, proxy than forward the HTTP request message to server
    and then forward the HTTP response message to browser and store the message
    in the cache as well. In addition, "DELETE" method also need to whether the
    object in the cache or not.

    Be careful! The file should be opened in binary mode because we possibly need
    to write or read special type of object, for instance, .jpg, .svg, etc.

    Args:
        :param tcp_socket: the socket which is created from start_server function.
        :param client_ip: IP address of the client.
        :param client_port: Port number of the client.

    Raises:
        IOError, FileNotFoundError: file does not exist.
        ConnectionResetError: client refresh the browser while server still send message.
        TypeError: input format is wrong or empty.
        socket.gaierror: Host name might be wrong.
    
Receive HTTP request message and retrieve the object from cache or server.
This function could handle different HTTP request message. Especially for
"Get" method type, proxy will firstly try to find the requested object from
cache, if not found, proxy than forward the HTTP request message to server
and then forward the HTTP response message to browser and store the message
in the cache as well. In addition, "DELETE" method also need to whether the
object in the cache or not.

Be careful. The file should be opened in binary mode because we possibly need
to write or read special type of object, for instance, .jpg, .svg, etc.
Receive HTTP request message and retrieve the object from cache or server . This function could handle different HTTP request message . Especially for " Get " method type proxy will firstly try to find the requested object from cache if not found proxy than forward the HTTP request message to server and then forward the HTTP response message to browser and store the message in the cache as well . In addition " DELETE " method also need to whether the object in the cache or not . Be careful . The file should be opened in binary mode because we possibly need to write or read special type of object for instance . jpg . svg etc .
def start_listen(tcp_socket, client_ip, client_port):
    message = tcp_socket.recv(1024).decode()
    handle_str = StrProcess(message)
    print("client is coming: {addr}:{port}".format(addr = client_ip, port = client_port))
    file_error = False
    global host
    try:
        command = handle_str.get_cmd_type()
        filename = handle_str.change_name()
        if command == "DELETE" :
            os.remove("./Cache/" + filename)
            tcp_socket.send(b"HTTP/1.1 200 OK\r\n\r\n")
            print("File is removed.")
        elif command == "GET" or command == "HEAD":
            print("Client want to {c} the {o}.".format(c=command, o=filename))
            f = open("./Cache/" + filename, "rb")
            file_content = f.readlines()
            f.close()
            if command == "GET":
                print("File in cache!")
                for i in range(0, len(file_content)):
                    tcp_socket.send(file_content[i])  
            else:  
                list_to_str = ""
                for i in range(0, len(file_content)):
                    list_to_str += file_content[i].decode()
                HTTP_header_end = list_to_str.find("\r\n\r\n")
                tcp_socket.send(list_to_str[:HTTP_header_end + 4].encode())
        elif command == "PUT" or command == "POST":  
            f = open("./Cache/" + filename, "ab")
            f.write(b"HTTP/1.1 200 OK\r\n\r\n" + handle_str.get_body().encode())
            f.close()
            print("Update successfully!")
            tcp_socket.send(b"HTTP/1.1 200 OK\r\n\r\n")
            body_re = b"true" if command == "PUT" else handle_str.get_body().encode()
            tcp_socket.send(body_re)
        else:
            tcp_socket.send(b"HTTP/1.1 400 Bad Request\r\n\r\n")
    except (IOError, FileNotFoundError):
        if command == "GET":
            c = socket(AF_INET, SOCK_STREAM)
            hostname = handle_str.get_hostname()
            file = handle_str.split_str()[1]
            print("File isn't in the cache!")
            try:
                c.connect((hostname, 80))
                host = hostname  
                request = "GET " + "http:/" + file + " HTTP/1.1\r\n\r\n"
            except:
                try:
                    new_host = handle_str.get_referer() if host == "" else host
                    c.connect((new_host, 80))
                    request = "GET " + "http://" + new_host + file + " HTTP/1.1\r\n\r\n"
                except:
                    tcp_socket.send(b"HTTP/1.1 404 Not Found\r\n\r\n")
                    with open("./Cache/NotFound.html", 'rb') as f:
                        file_content = f.readlines()
                    for strline in file_content:
                        tcp_socket.send(strline)
                    file_error = True
            if file_error is False:
                c.sendall(request.encode())
                print("proxyserver have found the host.")
                writeFile = open("./Cache/" + filename, "wb")
                print("Poxy server is receiving data...")
                while True:
                    data = c.recv(4096)
                    if not data:
                        break
                    sys.stdout.write(">")
                    tcp_socket.sendall(data)
                    writeFile.write(data)
                writeFile.close()
                sys.stdout.write("100%\n")
            c.close()
        elif command == "DELETE":
            tcp_socket.send(b"HTTP/1.1 204 Not Content\r\n\r\n")
    except (ConnectionResetError, TypeError):
        print("Bye to client: {addr}:{port}".format(addr = client_ip, port = client_port))
    print("tcp socket closed\n")
    tcp_socket.close()
def start_listen ( tcp_socket , client_ip , client_port ) : message = tcp_socket . recv ( 1024 ) . decode ( ) handle_str = StrProcess ( message ) print ( "client is coming: {addr}:{port}" . format ( addr = client_ip , port = client_port ) ) file_error = False global host try : command = handle_str . get_cmd_type ( ) filename = handle_str . change_name ( ) if command == "DELETE" : os . remove ( "./Cache/" + filename ) tcp_socket . send ( b"HTTP/1.1 200 OK\r\n\r\n" ) print ( "File is removed." ) elif command == "GET" or command == "HEAD" : print ( "Client want to {c} the {o}." . format ( c = command , o = filename ) ) f = open ( "./Cache/" + filename , "rb" ) file_content = f . readlines ( ) f . close ( ) if command == "GET" : print ( "File in cache!" ) for i in range ( 0 , len ( file_content ) ) : tcp_socket . send ( file_content [ i ] ) else : list_to_str = "" for i in range ( 0 , len ( file_content ) ) : list_to_str += file_content [ i ] . decode ( ) HTTP_header_end = list_to_str . find ( "\r\n\r\n" ) tcp_socket . send ( list_to_str [ : HTTP_header_end + 4 ] . encode ( ) ) elif command == "PUT" or command == "POST" : f = open ( "./Cache/" + filename , "ab" ) f . write ( b"HTTP/1.1 200 OK\r\n\r\n" + handle_str . get_body ( ) . encode ( ) ) f . close ( ) print ( "Update successfully!" ) tcp_socket . send ( b"HTTP/1.1 200 OK\r\n\r\n" ) body_re = b"true" if command == "PUT" else handle_str . get_body ( ) . encode ( ) tcp_socket . send ( body_re ) else : tcp_socket . send ( b"HTTP/1.1 400 Bad Request\r\n\r\n" ) except ( IOError , FileNotFoundError ) : if command == "GET" : c = socket ( AF_INET , SOCK_STREAM ) hostname = handle_str . get_hostname ( ) file = handle_str . split_str ( ) [ 1 ] print ( "File isn't in the cache!" ) try : c . connect ( ( hostname , 80 ) ) host = hostname request = "GET " + "http:/" + file + " HTTP/1.1\r\n\r\n" except : try : new_host = handle_str . get_referer ( ) if host == "" else host c . connect ( ( new_host , 80 ) ) request = "GET " + "http://" + new_host + file + " HTTP/1.1\r\n\r\n" except : tcp_socket . send ( b"HTTP/1.1 404 Not Found\r\n\r\n" ) with open ( "./Cache/NotFound.html" , 'rb' ) as f : file_content = f . readlines ( ) for strline in file_content : tcp_socket . send ( strline ) file_error = True if file_error is False : c . sendall ( request . encode ( ) ) print ( "proxyserver have found the host." ) writeFile = open ( "./Cache/" + filename , "wb" ) print ( "Poxy server is receiving data..." ) while True : data = c . recv ( 4096 ) if not data : break sys . stdout . write ( ">" ) tcp_socket . sendall ( data ) writeFile . write ( data ) writeFile . close ( ) sys . stdout . write ( "100%\n" ) c . close ( ) elif command == "DELETE" : tcp_socket . send ( b"HTTP/1.1 204 Not Content\r\n\r\n" ) except ( ConnectionResetError , TypeError ) : print ( "Bye to client: {addr}:{port}" . format ( addr = client_ip , port = client_port ) ) print ( "tcp socket closed\n" ) tcp_socket . close ( )
Receive HTTP request message and retrieve the object from cache or server.
Receive HTTP request message and retrieve the object from cache or server .
""" Receive HTTP request message and retrieve the object from cache or server.

    This function could handle different HTTP request message. Especially for
    "Get" method type, proxy will firstly try to find the requested object from
    cache, if not found, proxy than forward the HTTP request message to server
    and then forward the HTTP response message to browser and store the message
    in the cache as well. In addition, "DELETE" method also need to whether the
    object in the cache or not.

    Be careful! The file should be opened in binary mode because we possibly need
    to write or read special type of object, for instance, .jpg, .svg, etc.

    Args:
        :param tcp_socket: the socket which is created from start_server function.
        :param client_ip: IP address of the client.
        :param client_port: Port number of the client.

    Raises:
        IOError, FileNotFoundError: file does not exist.
        ConnectionResetError: client refresh the browser while server still send message.
        TypeError: input format is wrong or empty.
        socket.gaierror: Host name might be wrong.
    """ # 1. Receive request message from the client on connection socket. # Create new object (handle_str) from StrProcess class. # 2. Extract the path of the requested object from the message (second part of the HTTP header). # 3. Find the specific method type and handle the request. # Delete the object if it exists in cache. # Check whether the requested object exists or not. # Find the corresponding file from disk if it exists. # Send HTTP response message. # "HEAD" method. # Only send HTTP response message header lines. # Only implement upload files. # 4. If file doesn't exist in the cache, handle exceptions. # Create a socket on the proxy server. # Connect to the socket at port 80. # record the real hostname. # Need to use the global host or referer hostname. # Read the response into buffer. # Create a new file in the cache for the requested file. # Also send the response in the buffer to client socket # and the corresponding file in the cache. # Receive HTTP response message until all messages are received. # Send the content of the file to the socket. # Close the client socket.
file does not exist.
file does not exist .
IOError, FileNotFoundError
client refresh the browser while server still send message.
client refresh the browser while server still send message .
ConnectionResetError
input format is wrong or empty.
input format is wrong or empty .
TypeError
Host name might be wrong.
Host name might be wrong .
socket.gaierror
tcp_socket
client_ip
client_port
param client_port: Port number of the client.
param client_port : Port number of the client .