This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
software:nginx:webdav [2015/05/13 00:00] – [Проблема 4 - удаление папок] root | software:nginx:webdav [2022/02/05 04:30] (current) – root | ||
---|---|---|---|
Line 5: | Line 5: | ||
SAMB-у в принципе тоже без VPN можно пробросить, | SAMB-у в принципе тоже без VPN можно пробросить, | ||
- | Nginx в базовом функционале имеет не полную поддержку | + | Nginx в базовом функционале имеет не полную поддержку |
- | Расширить его ещё двумя: PROPFIND и OPTIONS можно с помощью | + | Расширить его ещё двумя: PROPFIND и OPTIONS можно с помощью |
- | Для работы потребуется Nginx собранный с поддержкой | + | Для работы потребуется Nginx собранный с поддержкой |
< | < | ||
[x] HTTP_DAV_EXT | [x] HTTP_DAV_EXT | ||
- | [x] HTTP_REWRITE | + | [x] HTTP_REWRITE |
+ | [x] HEADERS_MORE | ||
===== Проблема 1 - Майкрософт нарушает стандарты и свои обещания ===== | ===== Проблема 1 - Майкрософт нарушает стандарты и свои обещания ===== | ||
- | {{:ru: | + | {{: |
Перед тем как создать файл WebDav клиент проверяет наличие файла посылая запрос: | Перед тем как создать файл WebDav клиент проверяет наличие файла посылая запрос: | ||
Line 92: | Line 93: | ||
===== Проблема 2 - PROPPATCH отсутствует в nginx ===== | ===== Проблема 2 - PROPPATCH отсутствует в nginx ===== | ||
- | {{:ru: | + | {{: |
WebDav от мс очень хочет метод PROPPATCH, которого в Nginx и расширениях нет. Совсем нет.\\ | WebDav от мс очень хочет метод PROPPATCH, которого в Nginx и расширениях нет. Совсем нет.\\ | ||
Я рассматривал два варианта решения: | Я рассматривал два варианта решения: | ||
Line 136: | Line 137: | ||
===== Проблема 3 - создание папок ===== | ===== Проблема 3 - создание папок ===== | ||
- | {{:ru: | + | {{: |
См п1 :) | См п1 :) | ||
Line 182: | Line 183: | ||
**Фикс 3**: | **Фикс 3**: | ||
< | < | ||
- | rewrite ^(.*[^/])$ $1/; | + | rewrite ^(.*[^/])$ $1/ break; |
}</ | }</ | ||
Вот для этого пустяка и потребовался REWRITE плагин.\\ | Вот для этого пустяка и потребовался REWRITE плагин.\\ | ||
Line 189: | Line 190: | ||
===== Проблема 4 - удаление папок ===== | ===== Проблема 4 - удаление папок ===== | ||
Ноги тут те же что и в п3: отсутствие слеша на конце урла.\\ | Ноги тут те же что и в п3: отсутствие слеша на конце урла.\\ | ||
- | Однако я столкнулся с тем, что nginx тоже ведёт себя несколько странно.\\ | + | Однако я столкнулся с тем, что nginx тоже ведёт себя несколько странно: если слеш на конце отсутствует, |
- | 1. Если слеш на конце отсутствует, | + | |
- | 2. Если слеш добавить то папку он почему то так и не удаляет. Подозреваю тут где то баг самого nginx.\\ | + | |
**Фикс 4**: | **Фикс 4**: | ||
Line 204: | Line 204: | ||
open_file_cache off; | open_file_cache off; | ||
if (-d $webdav_root/ | if (-d $webdav_root/ | ||
- | rewrite ^(.*[^/])$ $1/; | + | rewrite ^(.*[^/])$ $1/ break; |
} | } | ||
root $webdav_root; | root $webdav_root; | ||
Line 210: | Line 210: | ||
}</ | }</ | ||
Если кратко, | Если кратко, | ||
+ | |||
+ | |||
+ | ===== Проблема 5 - копирование и переименование ===== | ||
+ | Ноги тут те же что и в п4: отсутствие слеша на конце урла и в Destination заголовке.\\ | ||
+ | Для решения проблемы с добавлением "/" | ||
+ | |||
+ | **Фикс 6**: | ||
+ | < | ||
+ | if ($request_method = COPY) { | ||
+ | return 597; | ||
+ | } | ||
+ | if ($request_method = MOVE) { | ||
+ | return 597; | ||
+ | } | ||
+ | |||
+ | location @copy_move_handler { | ||
+ | internal; | ||
+ | |||
+ | open_file_cache off; | ||
+ | if (-d $webdav_root/ | ||
+ | more_set_input_headers ' | ||
+ | rewrite ^(.*[^/])$ $1/ break; | ||
+ | } | ||
+ | root $webdav_root; | ||
+ | dav_methods COPY MOVE; | ||
+ | }</ | ||
+ | |||
+ | |||
+ | |||
+ | ===== Проблема 6 - OPTIONS корня ===== | ||
+ | Клиент запрашивает опции не у той папки которую мы хотим чтобы он подключил а у корня сервера.\\ | ||
+ | |||
+ | **Фикс 6**: | ||
+ | < | ||
+ | if ($request_method = OPTIONS) { | ||
+ | add_header Allow ' | ||
+ | add_header DAV '1, 2'; | ||
+ | return 200; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | Возвращаем ему статический список.\\ | ||
+ | Можно было просто разрешить: | ||
+ | |||
+ | |||
+ | ===== Проблема 7 - виндовый клиент не может подключится ===== | ||
+ | Соединение происходит но в логах nginx ничего нет, а клиент сообщает об ошибке.\\ | ||
+ | В логах с включённым дебагом ssl видно что рукопожатие не проходит.\\ | ||
+ | Проблема у меня проявилась не так давно, после обновления OpenSSL.\\ | ||
+ | При этом IE и другие браузеры могут авторизоваться по этому URL и отобразить листинг директории.\\ | ||
+ | |||
+ | **Фикс 7**: | ||
+ | Заменить OpenSSL на LibreSSL и пересобрать nginx. | ||
+ | Возможно OpenSSL уже исправили. | ||
Line 216: | Line 270: | ||
< | < | ||
и хотя в данном случае это не создаёт проблем, | и хотя в данном случае это не создаёт проблем, | ||
- | |||
- | Это уже третий раз когда гибкость nginx позволила мне получить результат не используя языки программирования, | ||
- | Прошлые разы я сделал кешируюший прокси с фильтрацией по урл и UPnP/DLNA сервер.\\ | ||
- | |||
Line 227: | Line 277: | ||
set $webdav_root "/ | set $webdav_root "/ | ||
location ^~ /Family { | location ^~ /Family { | ||
+ | if ($ssl_protocol = "" | ||
+ | add_header Strict-Transport-Security ' | ||
+ | return 403; | ||
+ | } | ||
+ | auth_basic " | ||
+ | auth_basic_user_file / | ||
- | root $webdav_root; | + | root $webdav_root; |
- | error_page 599 = @propfind_handler; | + | error_page 599 = @propfind_handler; |
- | error_page 598 = @delete_handler; | + | error_page 598 = @delete_handler; |
- | chunked_transfer_encoding on; | + | error_page 597 = @copy_move_handler; |
- | open_file_cache off; | + | open_file_cache off; |
- | client_max_body_size 50m; | + | client_max_body_size 50m; |
- | add_header Allow ' | + | |
if ($request_method = PROPFIND) { | if ($request_method = PROPFIND) { | ||
Line 244: | Line 299: | ||
} | } | ||
if ($request_method = MKCOL) { # Microsoft specific handle: add trailing slash. | if ($request_method = MKCOL) { # Microsoft specific handle: add trailing slash. | ||
- | rewrite ^(.*[^/])$ $1/; | + | rewrite ^(.*[^/])$ $1/ break; |
} | } | ||
if ($request_method = DELETE) { | if ($request_method = DELETE) { | ||
return 598; | return 598; | ||
+ | } | ||
+ | if ($request_method = COPY) { | ||
+ | return 597; | ||
+ | } | ||
+ | if ($request_method = MOVE) { | ||
+ | return 597; | ||
} | } | ||
- | dav_methods PUT MKCOL COPY MOVE; # | + | dav_methods PUT MKCOL; |
- | dav_ext_methods OPTIONS; | + | dav_ext_methods OPTIONS; |
create_full_put_path on; | create_full_put_path on; | ||
min_delete_depth 0; | min_delete_depth 0; | ||
- | dav_access user:rw group:rw all:rw; | + | dav_access user: |
+ | |||
+ | autoindex on; | ||
+ | autoindex_exact_size on; | ||
+ | autoindex_localtime on; | ||
} | } | ||
location @propfind_handler { | location @propfind_handler { | ||
internal; | internal; | ||
+ | |||
+ | auth_basic " | ||
+ | auth_basic_user_file / | ||
open_file_cache off; | open_file_cache off; | ||
Line 263: | Line 331: | ||
return 404; | return 404; | ||
} | } | ||
- | root $webdav_root; | + | root $webdav_root; |
- | dav_ext_methods PROPFIND; | + | dav_ext_methods PROPFIND; |
} | } | ||
location @delete_handler { | location @delete_handler { | ||
internal; | internal; | ||
+ | |||
+ | auth_basic " | ||
+ | auth_basic_user_file / | ||
open_file_cache off; | open_file_cache off; | ||
- | if (-d $webdav_root/ | + | if (-d $webdav_root/ |
- | rewrite ^(.*[^/])$ $1/; | + | rewrite ^(.*[^/])$ $1/ break; |
} | } | ||
- | root $webdav_root; | + | root $webdav_root; |
- | dav_methods DELETE; | + | dav_methods DELETE; |
- | }</ | + | } |
+ | location @copy_move_handler { | ||
+ | internal; | ||
+ | |||
+ | auth_basic " | ||
+ | auth_basic_user_file / | ||
+ | |||
+ | open_file_cache off; | ||
+ | if (-d $webdav_root/ | ||
+ | more_set_input_headers ' | ||
+ | rewrite ^(.*[^/])$ $1/ break; | ||
+ | } | ||
+ | root $webdav_root; | ||
+ | dav_methods COPY MOVE; | ||
+ | } | ||
+ | location / { | ||
+ | if ($request_method = OPTIONS) { | ||
+ | add_header Allow ' | ||
+ | add_header DAV '1, 2'; | ||
+ | return 200; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
open_file_cache off; | open_file_cache off; | ||
+ | Также в самом начале локейшена есть требование использовать SSL и если SSL используется то запрашивается BASIC авторизация. | ||
+ | ==== Важно ==== | ||
+ | - set $webdav_root "/ | ||
+ | - в папке "/ | ||
+ | - location ^~ **/Family** - означает что клиент должен использовать URL: https:// | ||
+ | - директивы **auth_basic** и **auth_basic_user_file** должны быть в каждом **location** который осуществляет обработку запросов, | ||
Line 284: | Line 383: | ||
Увы, но даже после всех проделанных настроек файлы более 4гб передавать не получится. (Скорее всего из за кривой реализации, | Увы, но даже после всех проделанных настроек файлы более 4гб передавать не получится. (Скорее всего из за кривой реализации, | ||
- | Вот здесь собраны все настройки с описанием: | + | Вот здесь собраны все настройки с описанием: |
На данный момент мои настройки WebClient выглядят так:\\ | На данный момент мои настройки WebClient выглядят так:\\ | ||
Line 304: | Line 403: | ||
+ | ===== Полезное ===== | ||
+ | * Дальнейшая разработка решения происходит тут: [[https:// | ||
+ | * Патч [[https:// | ||
+ | |||
+ | |||
+ | |||
+ | {{tag> |