webdav в rest на nginx: upload, подзапрос, замена параметров запроса и ответа
Vasiliy Fedorov
fyodorovvv на gmail.com
Пн Окт 4 12:44:58 MSD 2010
Привет.
Есть задача по организации upload & download больших файлов (несколько
Гб) авторизованных пользователей.
Внешнее API, допустим, WebDAV. У бэкенда какое-то REST API и находятся
они на разных машинах.
Легкие запросы к WebDAV можно отдавать обрабатывать еще одному бэкенду
(список файлов директории, свойства файлов, удаление файла) -- пусть к
REST ходит сам, но запросы на upload и download файлов гонять через
этот бэкенд не хочется, хочется напрямую отдавать в REST.
Пытаюсь понять подходит ли Nginx для такой задачи, и что хочется чтобы
умел proxy:
1. Прочитать заголовки запроса, не читая контент.
2. Сходить по какому-то URL с теми же заголовками, проверить что
запрос пропустить можно, ответ на этот запрос можно выдать в любом
устраивающем Nginx формате (чем сходить? у Nginx есть только SSI, но
они включаются только в ответе (?))
3. Если нельзя -- ругнуться пользователю, если можно -- поменять
request: method, uri, заголовки* -- и проксировать дальше.
(Проксировать дальше не считывая весь контент запроса, как я понимаю,
нельзя:
"Note that when using the HTTP Proxy Module (or even when using
FastCGI), the entire client request will be buffered in nginx before
being passed on to the backend proxied servers." (
http://wiki.nginx.org/HttpProxyModule#Synopsis )
То есть upload больших файлов работать будет плохо.
*: X-Accel-Redirect тут подходит плохо, хотя и используют для похожих
вещей: http://kovyrin.net/2010/07/24/nginx-fu-x-accel-redirect-remote/
То есть проблемы 3:
1. Upload всего файла.
2. Авторизация через другой сервер.
3. Замена параметров запроса в зависимости от подзапроса на лету.
Идеи:
1. Непонятно почему "я не дожен хотеть" прямого проксирования запросов
на upload, но у Lighttpd поведение такое же. То есть, казалось бы,
логично прочитать заголовки запроса, разобраться с ними, записать в
выходной сокет новые заголовки, вызвать splice (man splice).
2. Авторизация через другой сервер:
-- можно попробовать запрос направить на статический файлик с SSI
инструкциями, первой инструкцией сходить авторизоваться, в зависимости
от значения ответа вызывать разные SSI (не авторизован -- ошибка,
авторизован -- вызвать url)
-- куда при этом денется контент запроса? отправится и в первый
SSI и во второй? Или ни в один из SSI?
-- какими будут заголовки ответа? (Например, Content-Type для
скачивания видео).
-- можно пробовать использовать embedded Perl, но он не умеет
отправлять неблокирующие http-запросы. Embedded Lua, кстати, говорит
что умеет ( http://github.com/chaoslawful/lua-nginx-module ) -- но
модуль слишком новый, непонятно как с ним связываться.
3. Теоретически менять заголовки и метод можно, есть набор директив,
но как соотнести с другими вариантами -- непонятно, разработчик
lua-модуля пишет что изменять параметры запроса lua-модуль еще не
умеет, хотя и хочет.
Возможно ли то что хочется вообще сделать через Nginx? Какие-то еще
есть варианты? Что-то другое, не Nginx, более приспособлено для
решения таких задач?
P.S.: Директива proxy_pass_request_body есть в документации на
английском (http://wiki.nginx.org/HttpProxyModule#proxy_pass_request_body),
нет в документации на русском
(http://sysoev.ru/nginx/docs/http/ngx_http_proxy_module.html) и нет
слов о ее отмене в changes (http://sysoev.ru/nginx/changes.html)
Подробная информация о списке рассылки nginx-ru