Usando o proxy_redirect de nginx quando o domínio do local de resposta varia

4

Estou fazendo um aplicativo da web usando a API do SoundCloud. Solicitar um MP3 para transmitir envolve dois pedidos. Eu vou dar um exemplo. Em primeiro lugar:

http://api.soundcloud.com/tracks/59815100/stream

Isso retorna um 302 com um link temporário para o MP3 real (que varia a cada vez), por exemplo:

http://ec-media.soundcloud.com/xYZk0lr2TeQf.128.mp3?ff61182e3c2ecefa438cd02102d0e385713f0c1faf3b0339595667fd0907ea1074840971e6330e82d1d6e15dd660317b237a59b15dd687c7c4215ca64124f80381e8bb3cb5&AWSAccessKeyId=AKIAJ4IAZE5EOI7PA7VQ&Expires=1347621419&Signature=Usd%2BqsuO9wGyn5%2BrFjIQDSrZVRY%3D

O problema que tive foi que eu estou tentando carregar o MP3 via XMLHTTPRequest do JavaScript, e por razões de segurança o navegador não pode seguir o 302, como ec-media.soundcloud.com não define um cabeçalho dizendo que é seguro para o navegador acessar via XMLHTTPRequest.

Então, em vez de usar o URL do SoundCloud, eu configuro dois locais no nginx, para que o navegador interaja apenas com o servidor no qual meu aplicativo está hospedado e não há erros de segurança:

location /soundcloud/tracks/ {
    # rewrite URL to match api.soundcloud.com's URL structure
    rewrite \/soundcloud\/tracks\/(\d*) /tracks/$1/stream break;
    proxy_set_header Host api.soundcloud.com;
    proxy_pass http://api.soundcloud.com;
    # the 302 will redirect to /soundcloud/media instead of the original domain
    proxy_redirect http://ec-media.soundcloud.com /soundcloud/media;
}

location /soundcloud/media/ {
    rewrite \/soundcloud\/media\/(.*) /$1 break;
    proxy_set_header Host ec-media.soundcloud.com;
    proxy_pass http://ec-media.soundcloud.com;
}

So myserver / soundcloud / tracks / 59815100 retorna um 302 para /myserver/soundcloud/media/xYZk0lr2TeQf.128.mp3...etc, que então encaminha o MP3.

Isso funciona! No entanto, eu acertei um obstáculo. Às vezes, a localização 302 não é ec-media.soundcloud.com, é ak-media.soundcloud.com. Há possivelmente ainda mais servidores por aí e presumivelmente mais poderia aparecer a qualquer momento. Existe alguma maneira de lidar com um local 302 arbitrário sem ter que inserir manualmente cada variação possível?

Ou é possível que o nginx manipule o redirecionamento e retorne a resposta do segundo passo? Então myserver / soundcloud / tracks / 59815100 segue o 302 nos bastidores e retorna o MP3?

O navegador segue automaticamente o redirecionamento, por isso não posso fazer nada com a resposta inicial no lado do cliente.

Eu sou novo no nginx e um pouco acima da minha cabeça, então peço desculpas se eu perdi algo óbvio, ou está além do escopo do nginx. Muito obrigado pela leitura.

    
por Chalky 16.09.2012 / 03:29

1 resposta

5

Você pode usar expressões regulares em proxy_redirect . Consulte os documentos .

Algo como:

proxy_redirect ~^http://[^/]+(/.+)$ /soundcloud/media$1;

deve fazer o truque.

btw, você está fazendo algo estranho aqui:

location /soundcloud/media/ {
    rewrite \/soundcloud\/media\/(.*) /$1 break;
    proxy_set_header Host ec-media.soundcloud.com;
    proxy_pass http://ec-media.soundcloud.com;
}

é igual a isto:

location /soundcloud/media/ {
    proxy_pass http://ec-media.soundcloud.com/;
}

Ler documentação é sempre uma boa ideia.

    
por 17.09.2012 / 04:57

Tags