我正在尝试用 Python 制作非常简单的代理服务器,但现在我希望它除了在那里什么都不做。
这是我到目前为止所写的内容,但 HTTP 页面无法完成加载。
import socket
IP = '192.168.1.31'
PORT = 8080
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((IP, PORT))
s.listen(5)
while True:
conn, addr = s.accept()
with conn:
print("="*(len(str(addr))+14))
print('|Connected by', addr)
while True:
user_data = conn.recv(1024)
if not user_data: break
conn.send(user_data)
try:
full_socket = (user_data.decode()).split(' ')[1]
except Exception as e:
print('Exception', e)
pass
if int(full_socket.find(':')) is 4 or 0:
port = 80
url = (full_socket.split('://')[1]).split('/')[0]
else:
port = int(full_socket.split(':')[1])
url = full_socket.split(':')[0]
print("|Connected to", (url, port))
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((url, port))
sock.sendall(user_data)
sock.close()
print("="*(len(url) + len(str(port)) + 20))
print()
我最近在 python 3.8 中实现了一个代理服务器。支持多个后端。我希望它可以帮助你完善这个想法:
#!/usr/bin/python3
import os
import sys
import threading
import socket
import ssl
LISTEN = 200 # max
MAX_DATA_RECV = 999999 # bytes
BLOCKED = []
TIME_OUT = 20 # seconds
ALLOWED = {
'ms-session': ('http', 'localhost', 8989, 'localhost')
}
class ProxyServer:
def __init__(self, host='', port=8080):
"""
inicializa el servidor socket
"""
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((host, port))
self.server.listen(LISTEN)
print("listening [*] on {}:{}".format(host, port))
except socket.error as e:
print(e)
if self.server:
self.server.close()
sys.exit(1)
except Exception as e:
print(e)
if self.server:
self.server.close()
sys.exit(1)
def run(self):
"""
Se reciben y procesan las peticiones entrantes.
"""
try:
print("starting listening")
while True:
conn, client_addr = self.server.accept()
request = conn.recv(MAX_DATA_RECV)
backend_found = self.get_backend(request) # se busca el servidor backend con respecto a la url de entrada
if not backend_found: # En el caso que no exista la url a procesar, se cierra el socket
conn.close()
else:
#Se crea un hilo para procesar la petición y dar respecta al cliente.
threadx = threading.Thread(target=self.proxy_thread, args=(conn, client_addr, request, backend_found),)
threadx.start()
except Exception as e:
print(e)
if self.server:
self.server.close()
sys.exit(1)
def get_backend(self, request):
"""
Busca el servidor back respecto a la url de procesamiento
"""
pass
def proxy_thread(self, conn, client_addr, request, backend_found):
"""
Al iniciar el hilo, se invoca este metodo, valida si el back es http o https y redirecciona.
"""
protocol = backend_found[0]
if protocol == 'http':
self.http(conn, client_addr, request, backend_found)
elif protocol == 'https':
self.https(conn, client_addr, request, backend_found)
else:
conn.close()
def http(self, conn, client_addr, request, backend_found):
"""
Procesa la peticion http y da respuesta al cliente
"""
print("is HTTP")
s = None
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.resolve(s, conn, request, backend_found)
except socket.error as e:
print(e)
if s:
s.close()
if conn:
conn.close()
except Exception as e:
print(e)
if s:
s.close()
if conn:
conn.close()
finally:
return "http"
def https(self, conn, client_addr, request, backend_found):
"""
Procesa la peticion http y da respuesta al cliente
"""
pass
def resolve(self, s, conn, request, backend_found):
"""
Resuelve la petición
"""
try:
webserver = backend_found[1]
port = backend_found[2]
s.settimeout(TIME_OUT)
s.connect((webserver, port))
print("SOCKET established. Peer: {}".format(s.getpeername()))
s.send(request)
while 1:
data = s.recv(MAX_DATA_RECV)
if (len(data) > 0):
conn.send(data)
else:
break
s.shutdown(socket.SHUT_RDWR)
s.close()
conn.close()
except socket.error as e:
print(e)
if s:
s.close()
if conn:
conn.close()
except Exception as e:
print(e)
if s:
s.close()
if conn:
conn.close()
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句