File size: 3,282 Bytes
84121fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from fastapi import APIRouter, HTTPException, Query, Request
from fastapi.responses import StreamingResponse
import requests
import os
from typing import Optional

router = APIRouter()

# Headers para bypass de restricciones
DEFAULT_HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
    'Accept': '*/*',
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept-Encoding': 'gzip, deflate',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1'
}

def stream_content(url: str, headers: dict):
    """Genera el contenido del stream"""
    try:
        with requests.get(url, headers=headers, stream=True, timeout=30) as response:
            response.raise_for_status()
            
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:
                    yield chunk
    except requests.RequestException as e:
        print(f"Error streaming content: {e}")
        raise HTTPException(status_code=502, detail="Error al obtener el contenido")

@router.get("/proxy")
async def proxy_stream(
    request: Request,
    url: str = Query(..., description="URL del stream a proxificar")
):
    """Proxy para streams bloqueados por CORS o geolocalización"""
    
    if not url:
        raise HTTPException(status_code=400, detail="URL requerida")
    
    try:
        # Preparar headers
        proxy_headers = DEFAULT_HEADERS.copy()
        
        # Agregar headers del cliente si son relevantes
        client_headers = dict(request.headers)
        if 'referer' in client_headers:
            proxy_headers['Referer'] = client_headers['referer']
        
        # Hacer petición inicial para obtener headers de respuesta
        head_response = requests.head(url, headers=proxy_headers, timeout=10)
        
        # Preparar headers de respuesta
        response_headers = {}
        
        # Copiar headers importantes
        important_headers = [
            'content-type', 'content-length', 'accept-ranges',
            'cache-control', 'expires', 'last-modified'
        ]
        
        for header in important_headers:
            if header in head_response.headers:
                response_headers[header] = head_response.headers[header]
        
        # Headers CORS
        response_headers.update({
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS',
            'Access-Control-Allow-Headers': '*'
        })
        
        # Retornar stream
        return StreamingResponse(
            stream_content(url, proxy_headers),
            headers=response_headers,
            media_type=head_response.headers.get('content-type', 'application/octet-stream')
        )
        
    except requests.RequestException as e:
        print(f"Proxy error for URL {url}: {e}")
        raise HTTPException(status_code=502, detail="Error al acceder al contenido")
    except Exception as e:
        print(f"Unexpected proxy error: {e}")
        raise HTTPException(status_code=500, detail="Error interno del servidor")

@router.options("/proxy")
async def proxy_options():
    """Maneja peticiones OPTIONS para CORS"""
    return {
        "message": "OK"
    }