Вот мой вариант использования:
Я работаю с S3-совместимым провайдером хранения, который не предлагает общедоступные объекты, а только ссылки. Я работаю с Dokku
, nginx
и heroku-php-buildpack
, Мое приложение основано на Slim PHP Framework.
Сейчас я пытаюсь реализовать функцию, которая предварительно назначает объект, а затем отправляет предварительно назначенный анализ в браузер через X-Accel-Redirect.
Это означает:
www.example.com/asset/1/1/Sonnenuntergang-im-Meer_1400.jpg
вызывает скрипт, который возвращает следующий заголовок:
X-Accel-Redirect: /internal_redirect/storage.provider.ch/bucket/Sonnenuntergang-im-Meer_1400.jpg?AWSAccessKeyId=xx&Expires=xx&Signature=xx
Расположение / internal_redirect определяется здесь:
location ~ ^/internal_redirect/(.*?)/(.*) {
internal;
set $aws_access_key 'AWSAccessKeyId=$arg_AWSAccessKeyId';
set $url_expires 'Expires=$arg_Expires';
set $url_signature 'Signature=$arg_Signature';
set $args_full 'https://$1/$2?$aws_access_key&$url_expires&$url_signature';
proxy_set_header Host $1;
proxy_http_version 1.1;
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header Set-Cookie;
proxy_ignore_headers "Set-Cookie";
proxy_buffering off;
proxy_intercept_errors off;
resolver 8.8.8.8 valid=300s;
resolver_timeout 10s;
proxy_pass $args_full;
#proxy_ssl_session_reuse off;
}
Если я отключаю internal
и вызов URL прямо из браузера, это работает. Для этого мне нужно добавить конфигурацию nginx, скопированную в подкаталог nginx.conf.d корня приложения.
Если я вызываю скрипт внутри (с заголовком выше), я получаю следующую ошибку в журналах:
2016-09-01T14:30:27.229716973Z app[web.1]: 2016/09/01 14:30:27 [error] 230#0:
*12 rewrite or internal redirection cycle while redirect to named
location "@heroku-fcgi", client: 172.17.0.1, server: localhost,
request: "GET /asset/1/1/Sonnenuntergang-im-Meer_1400.jpg HTTP/1.1",
upstream: "fastcgi://unix:/tmp/heroku.fcgi.5000.sock", host: "xxx.example.com"
Мой PHP-скрипт в основном не более:
header('X-Accel-Redirect: /internal_redirect/'
. str_replace('https://', '', $this->db->presign_file($args['file']))
. ';');
exit(0);
В то время как presign_file
возвращает строку с заданным файлом.
Если я добавляю nginx location
вставьте в специфическую конфигурацию приложения *, поведение одинаково для внутренних и внешних вызовов. Но, похоже, я не могу использовать https для proxy_pass, который необходим моему провайдеру. Также варианты как proxy_ssl_session_reuse off
, которые выглядят многообещающе, не допускаются.
*) Определяется в Procfile с опцией -C
Refs .:
РЕДАКТИРОВАТЬ: Больше информации о конфигурации nginx
Основной файл создается пакетом сборки:
https://github.com/heroku/heroku-buildpack-php/blob/master/conf/nginx/heroku.conf.php
тогда как позиция include "<?=getenv('HEROKU_PHP_NGINX_CONFIG_INCLUDE')?>";
заменяется этим файлом конфигурации:
location ~ ^/internal_redirect/(.*?)/(.*) {
internal;
set $aws_access_key 'AWSAccessKeyId=$arg_AWSAccessKeyId';
set $url_expires 'Expires=$arg_Expires';
set $url_signature 'Signature=$arg_Signature';
set $args_full 'https://$1/$2?$aws_access_key&$url_expires&$url_signature';
proxy_set_header Host $1;
proxy_http_version 1.1;
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header Set-Cookie;
proxy_ignore_headers "Set-Cookie";
proxy_buffering off;
proxy_intercept_errors off;
resolver 8.8.8.8 valid=300s;
resolver_timeout 10s;
proxy_pass $args_full;
#proxy_ssl_session_reuse off;
}location / {
# try to serve file directly, fallback to rewrite
try_files $uri @rewriteapp;
}
location @rewriteapp {
# rewrite all to index.php
rewrite ^(.*)$ /index.php/$1 last;
}
location ~ ^/index\.php(/|$) {
try_files @heroku-fcgi @heroku-fcgi;
internal;
}
Задача ещё не решена.
Других решений пока нет …