Мне это кажется простым сценарием:
X
(http://proxy.example.com
)X
пересылает запрос на внутренний сервер Y
(http://internal1.example.com:8000
)Y
отвечает 3xx
перенаправить на другой внутренний сервер Z
(http://internal2.example.com:8000
)X
перехватывает перенаправление 3xx и снова отправляет запрос на бэкэнд-сервер Z
. Он не возвращает клиенту перенаправление 3xx.X
отвечает клиенту результатом перенаправленного запроса с внутреннего сервера Z
.Мне это нужно, потому что некоторые клиенты, похоже, не обрабатывают перенаправление (особенно при выполнении PUT), поэтому я хотел бы, чтобы перенаправление происходило незаметно и внутри прокси-сервера. (На самом деле я использую сервер WebDAV на бэкэнде, поэтому мои клиенты - Cyberduck, Nautilus, OSX Finder и т. Д.).
Я искал огромное количество существующего ответа на этот вопрос, но мне не повезло (этот вопрос это в основном то, что я хочу, но удовлетворительных ответов нет, и он не работал в течение года. Надеюсь, с тех пор все изменилось).
Я хотел бы использовать для этого существующее решение, если это возможно. Возможно ли это с Apache / Nginx?
Итак, после долгих поисков в Google и чата с ребятами из apache в IRC, это кажется невозможным с apache. Итак, я взглянул на nginx и смог найти решение, используя X-Accel-Redirect
с конфигурацией, подобной той, что в конце этого ответа.
См. Соответствующие сообщения в блоге:
http://kovyrin.net/2006/11/01/nginx-x-accel-redirect-php-rails/
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:8000/;
proxy_redirect http://localhost:8001 http://$host:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Proxy download
location ~* ^/internal_redirect/(.*?)/(.*) {
# Do not allow people to mess with this location directly
# Only internal redirects are allowed
internal;
# Location-specific logging
access_log internal_redirect.access.log main;
error_log internal_redirect.error.log debug;
# Extract download url from the request
set $download_uri $2;
set $download_host $1;
# Compose download url
set $download_url http://$download_host/$download_uri?$args;
# Set download request headers
proxy_set_header Host $download_host;
proxy_set_header Authorization '';
# The next two lines could be used if your storage
# backend does not support Content-Disposition
# headers used to specify file name browsers use
# when save content to the disk
# proxy_hide_header Content-Disposition;
# add_header Content-Disposition 'attachment; filename="$args"';
# Do not touch local disks when proxying
# content to clients
proxy_max_temp_file_size 0;
# Download the file and send it to client
# This is where the magic happens
proxy_pass $download_url;
}
}