Загрузка данных


import socket
import threading

# ❌ Список доменов, которые нужно заблокировать
BLOCKED_DOMAINS = ["vk.com", "facebook.com", "tiktok.com"]

# Настройки сервера
HOST = '127.0.0.1'
PORT = 8080

def handle_client(client_socket):
    try:
        # Получаем первоначальный запрос от браузера
        request = client_socket.recv(4096)
        if not request:
            return

        # Парсим первую строку запроса (например: "GET http://example.com/ HTTP/1.1")
        first_line = request.split(b'\n')[0].decode('utf-8', errors='ignore')
        if not first_line:
            return
            
        method, url, _ = (first_line.split() + ["", "", ""])[:3]

        # Извлекаем хост (домен) и порт
        http_pos = url.find("://")
        temp = url[(http_pos + 3):] if http_pos != -1 else url

        port_pos = temp.find(":")
        webserver_pos = temp.find("/")
        if webserver_pos == -1:
            webserver_pos = len(temp)

        if port_pos == -1 or webserver_pos < port_pos:
            port = 80
            webserver = temp[:webserver_pos]
        else:
            port = int((temp[(port_pos + 1):])[:webserver_pos - port_pos - 1])
            webserver = temp[:port_pos]

        # Проверяем, находится ли домен в черном списке
        if any(blocked in webserver for blocked in BLOCKED_DOMAINS):
            print(f"[ЗАБЛОКИРОВАНО] Попытка доступа к: {webserver}")
            # Отправляем браузеру страницу с ошибкой 403
            error_msg = "HTTP/1.1 403 Forbidden\r\nContent-Type: text/html\r\n\r\n" \
                        "<html><body><h1>403 Forbidden</h1><p>Доступ к этому сайту заблокирован вашим прокси.</p></body></html>"
            client_socket.sendall(error_msg.encode('utf-8'))
            client_socket.close()
            return

        print(f"[РАЗРЕШЕНО] {method} -> {webserver}:{port}")

        # Подключаемся к целевому серверу
        proxy_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        proxy_server.connect((webserver, port))

        if method == "CONNECT":
            # Для HTTPS устанавливаем прозрачный туннель
            client_socket.sendall(b"HTTP/1.1 200 Connection established\r\n\r\n")
            
            # Запускаем потоки для двусторонней передачи данных
            threading.Thread(target=forward_data, args=(client_socket, proxy_server)).start()
            threading.Thread(target=forward_data, args=(proxy_server, client_socket)).start()
        else:
            # Для обычного HTTP отправляем запрос и возвращаем ответ
            proxy_server.sendall(request)
            while True:
                data = proxy_server.recv(4096)
                if len(data) > 0:
                    client_socket.sendall(data)
                else:
                    break
            proxy_server.close()
            client_socket.close()

    except Exception as e:
        client_socket.close()

def forward_data(source, destination):
    """Пересылает данные между браузером и сервером (для HTTPS)."""
    try:
        while True:
            data = source.recv(4096)
            if not data:
                break
            destination.sendall(data)
    except:
        pass
    finally:
        source.close()
        destination.close()

def start_proxy():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # Позволяет быстро перезапускать сервер на том же порту
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind((HOST, PORT))
    server.listen(50)
    print(f"[*] Локальный прокси-сервер запущен на {HOST}:{PORT}")
    print(f"[*] Заблокированные домены: {', '.join(BLOCKED_DOMAINS)}")

    while True:
        try:
            client_socket, addr = server.accept()
            client_thread = threading.Thread(target=handle_client, args=(client_socket,))
            client_thread.daemon = True
            client_thread.start()
        except KeyboardInterrupt:
            print("\n[*] Остановка сервера...")
            server.close()
            break

if __name__ == "__main__":
    start_proxy()