def handle_client_quest(new_socket): # 代码执行到此,说明连接建立成功 recv_client_data = new_socket.recv(4096) if len(recv_client_data) == 0: print("Browser is close, socket close.") # 关闭服务与客户端的套接字 new_socket.close() return # 对二进制数据进行解码 recv_client_content = recv_client_data.decode("utf-8") # print(recv_client_content) # 输出原始请求数据 # 根据指定字符串进行分割, 最大分割次数指定2,目的是得到请求行 request_list = recv_client_content.split(" ", maxsplit=2) # 获取请求资源路径 request_path = request_list[1] # 判断请求的是否是根目录,如果条件成立,指定首页数据返回 if request_path == "/": request_path = "/index.html" # 打印请求路径 print("request path: %s" % request_path) # 判断是否是动态资源请求,请求路径结尾是 .html if request_path.endswith(".html"): """这里是动态资源请求,把请求信息交给框架处理""" logging.info("dynamic request:" + request_path) # 字典存储用户的请求信息 env = {"request_path": request_path} # 获取处理结果 status, headers, response_body = framework.handle_request(env) # 打印处理状态码 print("response: status(%s)" % status) # 使用框架处理的数据拼接响应报文 # 响应行 response_line = "HTTP/1.1 %s\r\n" % status # 响应头 response_header = "" # 遍历头部信息 for header in headers: # 拼接多个响应头 response_header += "%s: %s\r\n" % header response_data = (response_line + response_header + "\r\n" + response_body).encode("utf-8") # 发送数据 new_socket.send(response_data) # 关闭socket new_socket.close() else: """这里是静态资源请求""" logging.info("static request: " + request_path) try: # 动态打开指定文件 with open("../static" + request_path, "rb") as file: # 读取文件数据 file_data = file.read() except Exception as e: # 请求资源不存在,返回404数据 # 响应行 response_line = "HTTP/1.1 404 Not Found\r\n" # 响应头 response_header = "Server: PWS1.0\r\n" # 读取响应模板 with open("../template/404.html", "rb") as file: file_data = file.read() # 响应体 response_body = file_data # 拼接响应报文 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送数据 new_socket.send(response_data) else: # 响应行 response_line = "HTTP/1.1 200 OK\r\n" # 响应头 response_header = "Server: PWS1.0\r\n" # 响应体 try执行-file_data为静态资源,except执行,file_data为404页面 response_body = file_data # 拼接响应报文 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送数据 new_socket.send(response_data) finally: # 关闭服务与客户端的套接字 new_socket.close()
def handle_client_request(new_socket): # 接收客户端的请求信息 recv_data = new_socket.recv(4096) # 判断接收的数据长度是否为0 if len(recv_data) == 0: new_socket.close() return # 对二进制数据进行解码 recv_content = recv_data.decode("utf-8") print(recv_content) # 对数据按照空格进行分割 request_list = recv_content.split(" ", maxsplit=2) # 获取请求的资源路径 request_path = request_list[1] print(request_path) # 判断请求的是否是根目录,如果是根目录设置返回的信息 if request_path == "/": request_path = "/index.html" # 判断是否是动态资源请求,以后把后缀是.html的请求任务是动态资源请求 if request_path.endswith(".html"): """动态资源请求""" logging.info("动态资源请求地址:" + request_path) # 动态资源请求找web框架进行处理,需要把请求参数给web框架 # 准备给web框架的参数信息,都要放到字典里面 env = { "request_path": request_path, # 传入请求头信息,额外的参数可以在字典里面在进行添加 } # 使用框架处理动态资源请求, # 1. web框架需要把处理结果返回给web服务器, # 2. web服务器负责把返回的结果封装成响应报文发送给浏览器 status, headers, response_body = framework.handle_request(env) print(status, headers, response_body) # 响应行 response_line = "HTTP/1.1 %s\r\n" % status # 响应头 response_header = "" for header in headers: response_header += "%s: %s\r\n" % header # 响应报文 response_data = (response_line + response_header + "\r\n" + response_body).encode("utf-8") # 发送响应报文数据给浏览器 new_socket.send(response_data) # 关闭连接 new_socket.close() else: """静态资源请求""" logging.info("静态资源请求地址:" + request_path) # 1. os.path.exits # os.path.exists("static/" + request_path) # 2. try-except try: # 打开文件读取文件中的数据, 提示:这里使用rb模式,兼容打开图片文件 with open("static" + request_path, "rb") as file: # 这里的file表示打开文件的对象 file_data = file.read() # 提示: with open 关闭文件这步操作不用程序员来完成,系统帮我们来完成 except Exception as e: # 代码执行到此,说明没有请求的该文件,返回404状态信息 # 响应行 response_line = "HTTP/1.1 404 Not Found\r\n" # 响应头 response_header = "Server: PWS/1.0\r\n" # 读取404页面数据 with open("static/error.html", "rb") as file: file_data = file.read() # 响应体 response_body = file_data # 把数据封装成http 响应报文格式的数据 response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送给浏览器的响应报文数据 new_socket.send(response) else: # 代码执行到此,说明文件存在,返回200状态信息 # 响应行 response_line = "HTTP/1.1 200 OK\r\n" # 响应头 response_header = "Server: PWS/1.0\r\n" # 响应体 response_body = file_data # 把数据封装成http 响应报文格式的数据 response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送给浏览器的响应报文数据 new_socket.send(response) finally: # 关闭服务于客户端的套接字 new_socket.close()
def handle_client_request(new_socket): # 代码执行到此,说明连接建立成功 recv_client_data = new_socket.recv(4096) if len(recv_client_data) == 0: print("关闭浏览器了") new_socket.close() return # 对二进制数据进行解码 recv_client_content = recv_client_data.decode("utf-8") print(recv_client_content) # 根据指定字符串进行分割, 最大分割次数指定2 request_list = recv_client_content.split(" ", maxsplit=2) # 获取请求资源路径 request_path = request_list[1] print(request_path) # 判断请求的是否是根目录,如果条件成立,指定首页数据返回 if request_path == "/": request_path = "/index.html" # 判断请求的资源路径的后缀是否是.html # 如果是.html那么就是动态资源请求 # 如果不是.html那么就任务是静态资源请求 if request_path.endswith(".html"): """动态资源请求""" # 动态资源请求交给web框架处理 # 准备给web框架程序的数据, 最主要的是请求路径,后续框架有可能还需要请求头信息 env = { "request_path": request_path, # 假如框架需要请求头信息信息,可以在额外增加对应的键值对信息即可 } # 处理结果应该返回的信息有: # 1.状态信息status 2. 响应头信息headers 3. 处理结果(响应体)response_data status, headers, data = framework.handle_request(env) # 响应行 response_line = "HTTP/1.1 %s\r\n" % status # 遍历响应头信息[("Server", "PWS5.0")] response_header = "" for header in headers: # header是一个元组,格式化占位符要是有多个,可以使用元组方式进行传参 # “%s %s” % ('ab', 'bc') response_header += "%s: %s\r\n" % header # web服务器把处理后的结果拼接程一个http的响应报文发送给浏览器 response_data = (response_line + response_header + "\r\n" + data).encode("utf-8") # 把服务器发送的数据发给浏览器 new_socket.send(response_data) # 关闭套接字 new_socket.close() else: """静态资源请求""" try: # 动态打开指定文件 with open("static" + request_path, "rb") as file: # 读取文件数据 file_data = file.read() except Exception as e: # 请求资源不存在,返回404数据 # 响应行 response_line = "HTTP/1.1 404 Not Found\r\n" # 响应头 response_header = "Server: HJ1.0\r\n" with open("../template/error.html", "rb") as file: file_data = file.read() # 响应体 response_body = file_data # 拼接响应报文 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送数据 new_socket.send(response_data) else: # 响应行 response_line = "HTTP/1.1 200 OK\r\n" # 响应头 response_header = "Server: HJ1.0\r\n" # 响应体 response_body = file_data # 拼接响应报文 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送数据 new_socket.send(response_data) finally: # 关闭服务与客户端的套接字 new_socket.close()
def handle_client_quest(new_socket): # 代码执行到此,说明连接建立成功 recv_client_data = new_socket.recv(4096) if len(recv_client_data) == 0: print("关闭浏览器了") # 关闭服务与客户端的套接字 new_socket.close() return # 对二进制数据进行解码 recv_client_content = recv_client_data.decode("utf-8") print(recv_client_content) # 根据指定字符串进行分割, 最大分割次数指定2 request_list = recv_client_content.split(" ", maxsplit=2) # 获取请求资源路径 request_path = request_list[1] print(request_path) # 判断请求的是否是根目录,如果条件成立,指定首页数据返回 if request_path == "/": request_path = "/index.html" # 判断是否是动态资源请求 if request_path.endswith(".py"): """这里是动态资源请求,把请求信息交给框架处理""" # 字典存储用户的请求信息 env = {"request_path": request_path} # 获取处理结果 status, headers, response_body = framework.handle_request(env) # 使用框架处理的数据拼接响应报文 # 响应行 response_line = "HTTP/1.1 %s\r\n" % status # 响应头 response_header = "" # 遍历头部信息 for header in headers: # 拼接多个响应头 response_header += "%s: %s\r\n" % header response_data = (response_line + response_header + "\r\n" + response_body).encode("utf-8") # 发送数据 new_socket.send(response_data) # 关闭socket new_socket.close() else: """这里是静态资源请求""" try: # 动态打开指定文件 with open("static" + request_path, "rb") as file: # 读取文件数据 file_data = file.read() except Exception as e: # 请求资源不存在,返回404数据 # 响应行 response_line = "HTTP/1.1 404 Not Found\r\n" # 响应头 response_header = "Server: FoxServ1.0\r\n" with open("static/error.html", "rb") as file: file_data = file.read() # 响应体 response_body = file_data # 拼接响应报文 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送数据 new_socket.send(response_data) else: # 响应行 response_line = "HTTP/1.1 200 OK\r\n" # 响应头 response_header = "Server: FoxServ1.0\r\n" # 响应体 response_body = file_data # 拼接响应报文 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送数据 new_socket.send(response_data) finally: # 关闭服务与客户端的套接字 new_socket.close()
def handle_client_requset(new_socket): # 等待接收数据 recv_data = new_socket.recv(4096) # 判断接收的数据长度,客户端是否关闭 if len(recv_data) == 0: print("浏览器已关闭") new_socket.close() return # 把接收到的数据解码,按空格分隔,取出浏览器请求的页面路径 request_path = (recv_data.decode("utf-8").split(" ", 2))[1] # 如果请求的页面为"/",返回首页 if request_path == "/": request_path = "/index.html" # 判断路径是".html",为动态请求,交给web框架处理 if request_path.endswith(".html"): # 给web框架传参,格式为字典 env = {"request_path": request_path} status, headers, response_body = framework.handle_request(env) # 响应行 response_line = f"HTTP/1.1 {status}\r\n" # 响应头 response_header = "" # 遍历得到的响应头信息 for header in headers: response_header += f"{header}\r\n" # 响应报文 response = (response_line + response_header + "\r\n" + response_body).encode("utf-8") else: # 判断请求的页面是否存在 if os.path.exists("static/" + request_path): # 文件存在 # 按照响应报文格式,返回给浏览器数据 # 响应行 response_line = "HTTP/1.1 200 OK\r\n" # 响应头 response_header = "Server: PWS/1.0\r\n" # 响应体 with open("static" + request_path, "rb") as file: response_body = file.read() # 响应报文 response = (response_line + response_header + "\r\n").encode("utf-8") + response_body else: # 文件不存在 # 响应行 response_line = "HTTP/1.1 404 Not Found\r\n" # 响应头 response_header = "Server: PWS/1.0\r\n" # 响应体 with open("static/error.html", "rb") as file: response_body = file.read() # 响应报文 response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 发送数据到客户端 new_socket.send(response) # 关闭服务客户端的套接字 new_socket.close()
def handle_client_request(new_socket): # 接受客户端请求信息 recv_data = new_socket.recv(4096) # 判断请求数据是否为空,为空退出函数 if len(recv_data) == 0: new_socket.close() return # 对接受数据进行二进制解码 recv_content = recv_data.decode("utf-8") # 对数据进行分割 request_list = recv_content.split(" ", maxsplit=2) # 获取请求的资源路径 request_path = request_list[1] print(request_path) if request_path == "/": request_path = "/index.html" # 判断是否是动态资源请求,判断后缀.html为动态资源请求 if request_path.endswith(".html"): """动态资源请求""" logging.info("动态资源请求" + request_path) # 动态资源请求交由web框架处理,需要把请求参数传给web框架 # 准备给web框架的参数信息都要放到字典里 env = { "request_path": request_path, # 传入请求头信息,额外信息可以在字典里添加 } # 使用框架处理动态资源请求 # 1.web框架需要把处理结果返回给web服务器 # 2.web服务器需要将返回结果封装成响应报文后返回给浏览器,包括status, headers, response_body # 元组拆包 status, headers, response_body = framework.handle_request(env) print(status, headers, response_body) # 响应行 response_line = "HTTP/1.1 %s/r/n" % status # 响应头 response_header = "" for header in headers: # 元组拆包,header是包含两个值的元组 response_header += "%s: %s\r\n" % header # 响应报文 response_data = (response_line + response_header + "\r\n" + response_body).encode("utf-8") print(response_data) # 发送响应报文给浏览器 new_socket.send(response_data) # 关闭连接 new_socket.close() else: """静态资源请求""" logging.info("静态资源请求" + request_path) # 判断文件是否存在 # 1.os.path.exits # if not os.path.exists("static"+request_path): # print("static"+request_path+"not exist") # return # 2.try-except try: # 打开文件读取数据 提示,这里使用rb模式,兼容打开图片文件 with open("static" + request_path, "rb") as file: file_data = file.read() except Exception as e: # 代码执行到此,说明没有请求的文件,返回404 # 响应行 response_line = "HTTP/1.1 404 Not Found\r\n" # 响应头 response_header = "Server: LRY/1.0\r\n" # 空行 # 响应体 with open("static/error.html", "rb") as file: file_data = file.read() response_body = file_data response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # response已经是二进制数据,不用再编码 # # 把数据编码成二进制 # response_data = response.encode("utf-8") # 发送http响应格式数据 new_socket.send(response) else: # 代码执行到此,说明找到了请求文件,返回200 # 将数据封装成http响应报文发送给浏览器客户端 # 响应行 response_line = "HTTP/1.1 200 OK\r\n" # 响应头 response_header = "Server: LRY/1.0\r\n" # 空行 # 响应体 response_body = file_data # 此时response_body是二进制,不能和字符串拼接,将前面字符串编码为二进制 response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # response已经是二进制数据,不用再编码 # # 把数据编码成二进制 # response_data = response.encode("utf-8") # 发送http响应格式数据 new_socket.send(response) finally: # 关闭服务端套接字服务 new_socket.close()
def handle_client_quest(new_socket): recv_client_data = new_socket.recv(4096) if len(recv_client_data) == 0: print("关闭浏览器了") new_socket.close() return recv_client_content = recv_client_data.decode() print(recv_client_content) request_list = recv_client_content.split(" ", maxsplit=2) request_path = request_list[1] print(request_path) if request_path == "/": request_path = "/index.html" if request_path.endswith(".html"): env = {"request_path": request_path} status, headers, response_body = framework.handle_request(env) response_line = "HTTP/1.1 %s\r\n" % status response_header = "" for header in headers: response_header += "%s: %s\r\n" % header response_data = (response_line + response_header + "\r\n" + response_body).encode() new_socket.send(response_data) new_socket.close() else: try: with open("static" + request_path, "rb") as file: file_data = file.read() except Exception as e: response_line = "HTTP/1.1 404 Not Found\r\n" response_header = "Server: PWS1.0\r\n" with open("static/error.html", "rb") as file: file_data = file.read() response_body = file_data response_data = (response_line + response_header + "\r\n").encode() + response_body new_socket.send(response_data) else: response_line = "HTTP/1.1 200 OK\r\n" response_header = "Server: PWS1.0\r\n" response_body = file_data response_data = (response_line + response_header + "\r\n").encode() + response_body new_socket.send(response_data) finally: new_socket.close()
def handle_client_request(new_socket): # 代碼執行到此 建立成功 # 接收客戶端的請求信息 可以設置接收4KB資料 recv_data = new_socket.recv(4096) # 判斷接收的數據長度是否為0 if len(recv_data) == 0: new_socket.close() return # 對二進制數據進行解碼 recv_content = recv_data.decode("utf-8") print(recv_content) # 對數據按照空格進行分割 request_list = recv_content.split(" ", maxsplit=2) # 獲取請求的資源路徑 request_path = request_list[1] print(request_path) # 判斷請求的是否是根目錄,如果是根目錄設置返回的信息 if request_path == "/": request_path = "/index.html" if request_path.endswith(".html"): """動態資源請求""" logging.info("動態資源請求的地址:" + request_path) #動態資源請求找web框架進行處理,需要把請求參數給web框架 # 準備給web框架的參數信息,都要放到字典裡 env = { "request_path": request_path, # 傳入請求頭信息,額外的參數可以在字典中添加 } # 使用框架處理動態資源請求 # 1.web框架需要把處理結果返回給web服務器, # 2.web服務區負責把返回的結果封裝成響應報文發給瀏覽器 status, headers, response_body = framework.handle_request(env) print(status, headers, response_body) # 響應行 response_line = "HTTP/1.1 %s\r\n" % status # 響應頭 response_header = "" for header in headers: response_header += "%s: %s\r\n" % header #響應報文 response_data = (response_line + response_header + "\r\n" + response_body).encode("utf-8") #發送響應報文給瀏覽器 new_socket.send(response_data) # 關閉連結 new_socket.close else: """靜態資源請求""" logging.info("靜態資源請求的地址:" + request_path) # 判斷是否是動態資源請求,以後把後綴是.html的請求任務是動態資源請求 # 1. os.path.exists 如果路径 path 存在,返回 True;如果路径 path 不存在,返回 False。 # os.path.exists("static/" + request_path) # 2.try-except # print(recv_data) # 打開文件讀取文件中的數據 # 原本寫法 # file = open("static/index.html") # file.close() # 新的寫法 # 提示, with open關閉文件這 步操作不用程序員來完成,系統幫我們來完成| # 打開文件讀取文件中的數據,提示:這裡使用rb模式,兼容打開圖片文件 # 代碼執行到此,說明沒有請求的該文件,返回404狀態信息 try: with open("static/" + request_path, "rb") as file: # 這裡的file表示打開文件的對象. file_data = file.read() except Exception as e: # 響應行 response_line = "HTTP/1.1 404 Not Fount\r\n" # 響應頭 response_header = "Server: PWS/1.0\r\n" with open("static/error.html", "rb") as file: file_data = file.read() response_body = file_data # 把數據封裝成http響應報文格式的數據 response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 發送給瀏覽器的響應報文數據 new_socket.send(response) # 代碼執行到此,說明文件存在,返回200狀態信息| else: # 把數據封裝成http響應報文格式的數據 不能直接發給瀏覽器 # 響應行 response_line = "HTTP/1.1 200 OK\r\n" # 響應頭 response_header = "Server: PWS/1.0\r\n" # 空行 # 響應體 response_body = file_data # 把數據封裝成http響應報文格式的數據 response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 發送給瀏覽器的響應報文數據 new_socket.send(response) finally: # 關閉服務於客戶端的套接字 new_socket.close()
def handle_client(new_socket): # 新定义的套接字所能接受的数据大小 recv_info = new_socket.recv(4096) print(recv_info.decode('utf-8')) # 对这个接受信息进行判断客户在线否 if not recv_info: print("客户关闭了浏览器") return # 将收到的信息进行以空格分割,第二个就是客户需要的页面路径 recv_list = recv_info.split(" ", maxsplit=2) # 将接受数据第二个数据传给变量recv_path recv_path = recv_list[1] # 对用户输入进行判断,若输入为空,则返回给客户首页页面 if recv_path == "": recv_path = "/index.html" '''判断是动态资源请求还是静态''' if recv_path.endswith(".html"): '''这里是动态资源请求,交给框架处理''' # 通过日志记录客户端请求的页面路径 logging.info("客户请求的动态页面路径是:", recv_path) # 将客户端请求的页面路径用字典的方式装起来,进行包间传参 env = {"recv_path": recv_path} # 从框架的路由中获取处理函数获取响应状态、响应头、响应体传参使用 status, heads, response_body = framework.handle_request(env) # 响应行拼接响应状态 response_line = "HTTP/1.1 %s\r\n" % status # 响应头 response_head = "" # 因为页面的响应头不止一个数据, for head in heads: response_head += "%s: %s\r\n" % head # 将响应数据进行整合并且编码 response_data = (response_line + response_head + "\r\n" + response_body).encode("utf-8") # 通过新的套接字向客户端发送给响应报文 new_socket.send(response_data) # 发送完了需将新创建的套接字关闭 new_socket.close() else: '''这里是静态资源请求''' logging.info("客户端请求的静态页面路径是:", recv_path) try: # 静态请求判断,防止用户输入的路径不存在 with open("static" + recv_path, "rb") as file: file_content = file.read() # 对用户输入错误进行解决办法 except Exception as e: # 错误的响应行 response_line = "HTTP/1.1 404 not found\r\n" # 错误的响应头 response_head = "Server: HjjW/9.0\r\n" # 错误的响应体,需要通过打开错误页面数据返回 with open("static/error.html", "rb") as er_file: er_file_content = er_file.read() # 进行赋值给response_body美观一点 response_body = er_file_content # 将错误响应数据整合并且编码 response_data = (response_line + response_head + "\r\n").encode("utf-8") + response_body # 新的套接字发送给客户端 new_socket.send(response_data) # 关闭新的套接字 new_socket.close() else: # 正确响应行 response_line = "HTTP/1.1 200 ok\r\n" # 正确的响应头数据 response_head = "Server: HjjW/9.0\r\n" # 直接打开了正确的数据赋值给response_body response_body = file_content # 正确页面的响应报文整合并且编码 response_data = (response_line + response_head + "\r\n").encode("utf-8") + response_body # 新的套接字向客户端发送数据 new_socket.send(response_data) # 关闭新的套接字 new_socket.close()