天天看點

Web伺服器的底層原理與實作

import socket, threading, time

from Http.HttpResponse import HttpResponse

from WebFrame.WebFrame import handler_request

class HttpWebServer(object):

__run = True
def __init__(self, ip_address:str,listen_port: int):
    self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # Set socket reuse ->  True   default:False
    self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    self.server_socket.bind(
        (ip_address, listen_port)
    )
    self.server_socket.listen(128)
@staticmethod
def handler_http_request(new_socket: socket.socket):
    """
    :param new_socket:
    :return:
    """
    rec_data = new_socket.recv(4096)
    if len(rec_data) == 0:
        return
    content = rec_data.decode("utf-8")
    request_path = content.split(" ", maxsplit=2)[1]
    if request_path == '/':
        request_path = '/index.html'
    if request_path.endswith(".html"):
        """ ----------------  dynamic  request   ----------------"""
        http_response = handler_request(
            {"request_path": request_path}
        )
        new_socket.send(http_response)
    else:
        """ ----------------  static   request   --------------- """
        response_headers, response_body, response_length = None, None, 0
        response_status = ''
        try:
            with open("../static" + request_path, 'rb') as f:
                response_body = f.read()
                response_length: int = len(response_body)
                response_status = HttpResponse.RESPONSE_STATUS_OK
        except BaseException as e:
            with open('../static/html/404.html', 'rb') as f:
                response_body = f.read()
                response_length: int = len(response_body)
                response_status = HttpResponse.RESPONSE_STATUS_NOT_FOUND
        finally:
            local_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            response_headers = f'HTTP/1.1 {response_status}\r\nContent-Length:{response_length}\r\nDate:{local_time}\r\nServer: Pagche\r\n'
            response = response_headers.encode("utf-8") + "\r\n".encode("utf-8") + response_body
            new_socket.send(response)
    new_socket.close()

def start(self) -> None:
    print("Server Start Successful!")
    while self.__run:
        new_socket, address_info = self.server_socket.accept()
        print(f"[+] client {address_info[0]} send request")
        sub_thread = threading.Thread(target=HttpWebServer.handler_http_request, args=(new_socket,))
        sub_thread.setDaemon(True)
        sub_thread.start()

def stop(self) -> None:
    self.__run = False
    print("Server Stop Successful!")
           

if name == '__main__':

server=HttpWebServer('',8888)
server.start()