用Python创建代理Web服务器S1

与c相比, python中的套接字编程非常用户友好。程序员不必担心套接字的详细信息。在python中, 用户有更多机会专注于应用程序层而不是网络层。在本教程中, 我们将开发一个能够处理HTTP流量的简单多线程代理服务器。它主要基于基本的套接字编程思想。如果你不确定基础知识, 那么我建议你在阅读本教程之前先将它们刷一下。
这是代理服务器的幼稚实现。在接下来的教程中, 我们将逐步将其开发为非常有用的服务器。
首先, 我们将通过3个简单的步骤来完成该过程
1.创建一个传入套接字
【用Python创建代理Web服务器S1】我们在服务器类的__init__方法中创建一个套接字serverSocket。这将为传入的连接创建一个套接字。然后, 我们绑定套接字, 然后等待客户端连接。

def __init__(self, config): # Shutdown on Ctrl+C signal.signal(signal.SIGINT, self.shutdown) # Create a TCP socket self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# Re-use the socket self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# bind the socket to a public host, and a port self.serverSocket.bind((config['HOST_NAME'], config['BIND_PORT']))self.serverSocket.listen(10) # become a server socket self.__clients = {}

2.接受客户和流程
这是所有步骤中最简单但最重要的步骤。我们等待客户的连接请求, 一旦建立成功连接, 我们就将请求分派到一个单独的线程中, 使我们可用于下一个请求。这使我们可以同时处理多个请求, 从而将服务器的性能提高了数倍。
while True:# Establish the connection (clientSocket, client_address) = self.serverSocket.accept() d = threading.Thread(name=self._getClientName(client_address), target = self.proxy_thread, args=(clientSocket, client_address)) d.setDaemon(True) d.start()

3.重定向流量
代理服务器的主要功能是充当源和目标之间的中介。在这里, 我们将从源中获取数据, 然后将其传递给客户端。
  • 首先, 我们从接收到的请求数据中提取URL。
# get the request from browser request = conn.recv(config['MAX_REQUEST_LEN']) # parse the first line first_line = request.split('\n')[0]# get url url = first_line.split(' ')[1]

  • 然后, 我们找到请求的目标地址。地址是一个元组(destination_ip_address, destination_port_no)。我们将从该地址接收数据。
http_pos = url.find("://") # find pos of :// if (http_pos==-1): temp = url else: temp = url[(http_pos+3):] # get the rest of urlport_pos = temp.find(":") # find the port pos (if any)# find end of web server webserver_pos = temp.find("/") if webserver_pos == -1: webserver_pos = len(temp)webserver = "" port = -1 if (port_pos==-1 or webserver_pos < port_pos): # default port port = 80 webserver = temp[:webserver_pos] else: # specific port port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1]) webserver = temp[:port_pos]

  • 现在, 我们建立了到目标服务器(或远程服务器)的新连接, 然后将原始请求的副本发送到服务器。然后, 服务器将以响应进行响应。所有响应消息均使用以下通用消息格式:RFC 822.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(config['CONNECTION_TIMEOUT']) s.connect((webserver, port)) s.sendall(request)

  • 然后, 我们将服务器的响应重定向到客户端。 conn是与客户端的原始连接。该响应可能大于我们在一个调用中收到的MAX_REQUEST_LEN, 因此, 空响应表示响应结束。
while 1: # receive data from web server data = https://www.lsbin.com/s.recv(config['MAX_REQUEST_LEN'])if (len(data)> 0): conn.send(data) # send to browser/client else: break

然后, 我们适当地关闭服务器连接并进行错误处理, 以确保服务器按预期工作。
如何测试服务器?
1.在终端上运行服务器。保持运行并切换到你喜欢的浏览器。
2.转到浏览器的代理设置, 然后将代理服务器更改为" localhost", 并将端口更改为" 12345"。
3.现在打开任何HTTP网站(非HTTPS), 例如。 lsbin.org和volla!你应该能够在浏览器上访问内容。
服务器运行后, 我们可以监视到客户端的请求。我们可以使用这些数据来监视正在运行的内容, 也可以基于内容开发统计信息。
我们甚至可以限制对网站的访问或将IP地址列入黑名单。在即将到来的教程中, 我们将处理更多此类功能。
接下来是什么?
在接下来的教程中, 我们将在代理服务器中添加以下功能。
–将域名列入黑名单
–内容监控
–记录
– HTTP WebServer + ProxyServer
本教程的整个工作源代码都可用这里
用Python创建代理Web服务器套装2
如果你有任何问题/意见, 请随时在评论部分中发布。
关于作者:
Pinkesh Badjatiya来自海得拉巴(IIIT)海德拉巴。可见他的项目工作这里。
如果你还希望在此处展示你的博客, 请参阅日志用于在lsbin上撰写访客博客。
首先, 你的面试准备可通过以下方式增强你的数据结构概念:Python DS课程。

    推荐阅读