Python 中的代理服务器

亚龙

我正在尝试用 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()

HTTP页面执行测试结果

何塞·G·梅加

我最近在 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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章