【问题标题】:Write proxy web server using socket in python在 python 中使用套接字编写代理 Web 服务器
【发布时间】:2021-01-03 07:41:38
【问题描述】:

这是我在大学计算机网络课程研讨会上的代码。

要求:编写一个代理网络服务器。从浏览器端口 8888 接收 HTTP 请求,并将 HTTP 请求发送到 Web 服务器端口 80。似乎我向 Web 服务器发送请求时遇到了问题。

你能告诉我在这种情况下我的错误吗?

非常感谢

import socket
import sys
import _thread
import traceback
import ssl
def CreateServer(host, port): 
    Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    Server.bind((host,port))
    Server.listen(5)
    return Server

def ReadRequest(Client):
    re = ""
    Client.settimeout(10.0)
try:
    re = Client.recv(1024).decode()
    while (re):
        re = re + Client.recv(1024).decode()
except socket.timeout: # fail after 1 second of no activity
    if not re:
        print("Didn't receive data! [Timeout]")
finally:
    return re

#2. Client connect Server + 3. Read HTTP Request
def ReadHTTPRequest(Server): 
    re = ""
    while (re == ""):
        Client, address = Server.accept()
        print("Client: ", address," da ket noi toi Server")
        re = ReadRequest(Client)
    return Client,address, re

def proxy_server(webserver, port, conn, data, addr):
    print("{} {} {} {}".format(webserver, port, conn, addr))
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(10.0)
        s.connect((webserver, port))
        s.sendall(data)
        while 1:
            reply = s.recv(1024)
            if len(reply) > 0:
                conn.send(reply)
                print("[*] Request sent: {} > {}".format(addr[0],webserver))
            else:
                break        
    
        s.close()
        conn.close()
    
    except Exception as e:
        print(e)
        traceback.print_exc()
        s.close()
        conn.close()
        sys.exit(1)

def conn_string(Client,Request,addr):
    try:
        #print(addr)
        first_line=Request.split('\n')[0]
        url=first_line.split(" ")[1]
        http_pos=url.find("://")
        if http_pos==-1:
            temp=url
        else:
            temp=url[(http_pos+3):]
        port_pos=temp.find(":")
        webserver_pos=temp.find("/")
        if webserver_pos == -1:
            webserver_pos = len(temp)
        webserver = ""
        port = -1
        if port_pos == -1 or webserver_pos < port_pos:
            port = 80
            webserver = temp[:webserver_pos]
        else:
            port = 80
            #port = int(temp[(port_pos + 1):][:webserver_pos - port_pos -1])
            webserver = temp[:port_pos]
        proxy_server(webserver,port,Client,Request.encode(),addr)
    except Exception as e:
        print (e)
        traceback.print_exc()



if __name__=="__main__":
    try:
        Server=CreateServer("",8888)
        print("[*] Intializing socket. Done.")
        print("[*] Socket binded successfully...")
        print("[*] Server started successfully [{}]".format(8888))
    except Exception as e:
        print(e)
        sys.exit(2)
    while True:
        try:
             Client,addr,Request=ReadHTTPRequest(Server)
             print("---------HTTP request: ")
             print(Request)
             _thread.start_new_thread(conn_string,(Client,Request,addr))
        except KeyboardInterrupt:
            Server.close()
            print("\n[*] Shutting down..")
            sys.exit()
    Server.close()


  [1]: https://i.stack.imgur.com/216ZO.png

【问题讨论】:

    标签: python sockets web proxy


    【解决方案1】:

    您只是将原始请求转发到服务器,即请求中包含完整的 URL:

    GET http://ktdbcl.hcmus.edu.vn/ HTTP/1.1
    Host: ktdbcl.hcmus.edu.vn
    ...
    

    应该只转发路径:

    GET / HTTP/1.1
    Host: ktdbcl.hcmus.edu.vn
    ...
    

    除此之外,请求和响应的读取被严重破坏。您没有正确解析 HTTP 协议,而是简单地等待一些时间并将几秒钟内没有数据视为消息结束。由于今天多个请求和响应将通过同一连接完成,因此您的代码将严重减慢任何浏览速度。

    您应该正确解析 HTTP 协议并等待由 HTTP 标准定义的适当的请求结束标记,而不是等待数秒没有数据作为请求/响应结束的标记 - 请参阅 RFC 7230

    【讨论】:

    • 对不起,如果它打扰你,但我是新手,我不知道如何解析 http url 来转发它,你能详细告诉我吗? @Steffen Ullrich
    • @ChâuTrinh:新手不是让别人做工作的借口,而是学习的动力。请让自己熟悉 HTTP 的工作原理 - 您可以在我链接到的标准中找到信息,也可以在 Wikipedia 中找到信息。剩下的就是编码,你也应该学习 - 特别是如果这是一个研讨会的代码,可能期望工作是你自己的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    相关资源
    最近更新 更多