This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
software:nginx:webdav [2015/05/12 17:14] – [Немного о настройке клиента] root | software:nginx:webdav [2022/02/04 18:33] – removed - external edit (Unknown date) 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Nginx and Microsoft Windows WebClient (WebDav) ====== | ||
- | В Microsoft Windows начиная с 2к встроен Веб Клиент, | ||
- | Клиент писался явно под себя (связка с IIS) и от того работает весьма < | ||
- | Это единственный способ " | ||
- | SAMB-у в принципе тоже без VPN можно пробросить, | ||
- | |||
- | Nginx в базовом функционале имеет не полную поддержку WebDav: PUT DELETE MKCOL COPY MOVE.\\ | ||
- | Расширить его ещё двумя: PROPFIND и OPTIONS можно с помощью плагина: | ||
- | |||
- | |||
- | Для работы потребуется Nginx собранный с поддержкой WebDav, dav-ext модулем и rewrite.\\ | ||
- | < | ||
- | [x] HTTP_DAV_EXT | ||
- | [x] HTTP_REWRITE | ||
- | |||
- | |||
- | |||
- | ===== Проблема 1 - Майкрософт нарушает стандарты и свои обещания ===== | ||
- | {{: | ||
- | |||
- | Перед тем как создать файл WebDav клиент проверяет наличие файла посылая запрос: | ||
- | < | ||
- | Connection: Keep-Alive | ||
- | User-Agent: Microsoft-WebDAV-MiniRedir/ | ||
- | Depth: 0 | ||
- | translate: f | ||
- | Content-Length: | ||
- | Host: 172.16.0.254: | ||
- | |||
- | В ответ IIS ему выдаёт: | ||
- | < | ||
- | Content-Length: | ||
- | Content-Type: | ||
- | Server: Microsoft-IIS/ | ||
- | X-Powered-By: | ||
- | Date: Sun, 10 Aug 2014 20:06:08 GMT | ||
- | |||
- | < | ||
- | ...</ | ||
- | |||
- | Только это не правильно, | ||
- | с точки зрения стандартов: | ||
- | с точки зрения доков мс: http:// | ||
- | У яндекса тоже в примерах xml: http:// | ||
- | |||
- | Ответ Nginx:\\ | ||
- | < | ||
- | Server: nginx/1.7.4 | ||
- | Date: Sun, 10 Aug 2014 21:17:34 GMT | ||
- | Transfer-Encoding: | ||
- | Connection: keep-alive | ||
- | Keep-Alive: timeout=60 | ||
- | |||
- | 47 | ||
- | <?xml version=" | ||
- | < | ||
- | |||
- | cc | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | </ | ||
- | < | ||
- | </ | ||
- | </ | ||
- | |||
- | 11 | ||
- | </ | ||
- | |||
- | 0</ | ||
- | Такой " | ||
- | |||
- | Фиксим в конфиге (возможно это сведёт с ума остальные, | ||
- | **Фикс 1**: | ||
- | < | ||
- | if ($request_method = PROPFIND) { | ||
- | return 599; | ||
- | } | ||
- | |||
- | location @propfind_handler { | ||
- | internal; | ||
- | |||
- | open_file_cache off; | ||
- | if (!-e $webdav_root/ | ||
- | return 404; | ||
- | } | ||
- | root $webdav_root; | ||
- | dav_ext_methods PROPFIND; | ||
- | }</ | ||
- | |||
- | |||
- | |||
- | ===== Проблема 2 - PROPPATCH отсутствует в nginx ===== | ||
- | {{: | ||
- | WebDav от мс очень хочет метод PROPPATCH, которого в Nginx и расширениях нет. Совсем нет.\\ | ||
- | Я рассматривал два варианта решения: | ||
- | 1. Написать плагин к Nginx или патч к dav-ext, короче Си код и пересборка Nginx.\\ | ||
- | 2. Положится на кривость виндовой реализации WebDav и скормить статический ответ.\\ | ||
- | |||
- | Запрос: | ||
- | < | ||
- | Cache-Control: | ||
- | Connection: Keep-Alive | ||
- | Pragma: no-cache | ||
- | Content-Type: | ||
- | User-Agent: Microsoft-WebDAV-MiniRedir/ | ||
- | translate: f | ||
- | Content-Length: | ||
- | Host: xxx.xxx.net | ||
- | |||
- | <?xml version=" | ||
- | |||
- | <spoiler title=" | ||
- | Date: Sun, 10 Aug 2014 12:24:47 GMT | ||
- | Server: Microsoft-IIS/ | ||
- | X-Powered-By: | ||
- | Content-Type: | ||
- | Transfer-Encoding: | ||
- | |||
- | <?xml version=" | ||
- | 0</ | ||
- | " | ||
- | И как эти все атрибуты писать в разных ОС и разных ФС?... | ||
- | |||
- | Так появился второй фикс в конфиге: | ||
- | Фикс 2:\\ | ||
- | < | ||
- | add_header Content-Type ' | ||
- | return 207 '<? | ||
- | }</ | ||
- | |||
- | Из ответа IIS я выкинул всё что мне не понравилось и виндовый WebDav это проглотил.\\ | ||
- | Теперь одиночные и группы файлов без проблем можно копировать на сетевой диск примонтированный по WebDav.\\ | ||
- | Минусом - не выставляется оригинальная дата создания, | ||
- | |||
- | |||
- | ===== Проблема 3 - создание папок ===== | ||
- | {{: | ||
- | См п1 :) | ||
- | |||
- | Приходит запрос: | ||
- | < | ||
- | Connection: Keep-Alive | ||
- | User-Agent: Microsoft-WebDAV-MiniRedir/ | ||
- | translate: f | ||
- | Content-Length: | ||
- | Host: xxx.xxx.net</ | ||
- | |||
- | Nginx на него отвечает (немного странно выбирая код, на мой взгляд, | ||
- | Ответ: | ||
- | < | ||
- | Server: nginx/1.7.4 | ||
- | Date: Sun, 10 Aug 2014 21:43:15 GMT | ||
- | Content-Type: | ||
- | Content-Length: | ||
- | Connection: keep-alive | ||
- | Keep-Alive: timeout=60 | ||
- | |||
- | < | ||
- | < | ||
- | <body bgcolor=" | ||
- | < | ||
- | < | ||
- | </ | ||
- | </ | ||
- | |||
- | IIS отвечает: | ||
- | |||
- | Как должно быть описано: | ||
- | У майкрософта: | ||
- | У яндекса: | ||
- | И даже в RFC: http:// | ||
- | |||
- | Во всех примерах URL оканчивается слешем. \\ | ||
- | Но только не в запросе WebDav клиента от мс. \\ | ||
- | |||
- | Вариантов опять было два: \\ | ||
- | 1. Поправить файл: http:// | ||
- | 2. Пофиксить через конфиг.\\ | ||
- | |||
- | Вариант 1 я оставляю на усмотрение програмеров nginx, может по стандарту оно и должно ругаться. Связываться с отсылкой патчей тоже не хотелось.\\ | ||
- | |||
- | **Фикс 3**:\\ | ||
- | < | ||
- | rewrite ^(.*[^/])$ $1/; | ||
- | }</ | ||
- | Вот для этого пустяка и потребовался REWRITE плагин.\\ | ||
- | |||
- | |||
- | ===== Проблема 4 - удаление папок ===== | ||
- | Ноги тут те же что и в п3: отсутствие слеша на конце урла.\\ | ||
- | Однако я столкнулся с тем, что nginx тоже ведёт себя несколько странно.\\ | ||
- | 1. Если слеш на конце отсутствует, | ||
- | 2. Если слеш добавить то папку он почему то так и не удаляет. Подозреваю тут где то баг самого nginx.\\ | ||
- | |||
- | Фикс в конфиге: | ||
- | **Фикс 4**: | ||
- | < | ||
- | if ($request_method = DELETE) { | ||
- | return 598; | ||
- | } | ||
- | |||
- | location @delete_handler { | ||
- | internal; | ||
- | |||
- | open_file_cache off; | ||
- | if (-d $webdav_root/ | ||
- | rewrite ^(.*[^/])$ $1/; | ||
- | } | ||
- | root $webdav_root; | ||
- | dav_methods DELETE; | ||
- | }</ | ||
- | Если кратко, | ||
- | |||
- | |||
- | ===== Ещё немного о Nginx ===== | ||
- | Не трудно заметить, | ||
- | < | ||
- | и хотя в данном случае это не создаёт проблем, | ||
- | |||
- | Это уже третий раз когда гибкость nginx позволила мне получить результат не используя языки программирования, | ||
- | Прошлые разы я сделал кешируюший прокси с фильтрацией по урл и UPnP/DLNA сервер.\\ | ||
- | |||
- | |||
- | |||
- | ===== Конфиг nginx для WebDav ===== | ||
- | WebDav для Nginx:\\ | ||
- | < | ||
- | set $webdav_root "/ | ||
- | location ^~ /Family { | ||
- | |||
- | root $webdav_root; | ||
- | error_page 599 = @propfind_handler; | ||
- | error_page 598 = @delete_handler; | ||
- | chunked_transfer_encoding on; | ||
- | open_file_cache off; | ||
- | client_max_body_size 50m; | ||
- | add_header Allow ' | ||
- | |||
- | if ($request_method = PROPFIND) { | ||
- | return 599; | ||
- | } | ||
- | if ($request_method = PROPPATCH) { # Unsupported, | ||
- | add_header Content-Type ' | ||
- | return 207 '<? | ||
- | } | ||
- | if ($request_method = MKCOL) { # Microsoft specific handle: add trailing slash. | ||
- | rewrite ^(.*[^/])$ $1/; | ||
- | } | ||
- | if ($request_method = DELETE) { | ||
- | return 598; | ||
- | } | ||
- | |||
- | dav_methods PUT MKCOL COPY MOVE; # | ||
- | dav_ext_methods OPTIONS; | ||
- | create_full_put_path on; | ||
- | min_delete_depth 0; | ||
- | dav_access user:rw group:rw all:rw; | ||
- | } | ||
- | location @propfind_handler { | ||
- | internal; | ||
- | |||
- | open_file_cache off; | ||
- | if (!-e $webdav_root/ | ||
- | return 404; | ||
- | } | ||
- | root $webdav_root; | ||
- | dav_ext_methods PROPFIND; | ||
- | } | ||
- | location @delete_handler { | ||
- | internal; | ||
- | |||
- | open_file_cache off; | ||
- | if (-d $webdav_root/ | ||
- | rewrite ^(.*[^/])$ $1/; | ||
- | } | ||
- | root $webdav_root; | ||
- | dav_methods DELETE; | ||
- | }</ | ||
- | |||
- | open_file_cache off; | ||
- | |||
- | |||
- | ===== Немного о настройке клиента ===== | ||
- | Он как капризный ребёнок, | ||
- | Увы, но даже после всех проделанных настроек файлы более 4гб передавать не получится. (Скорее всего из за кривой реализации, | ||
- | |||
- | Вот здесь собраны все настройки с описанием: | ||
- | |||
- | На данный момент мои настройки WebClient выглядят так:\\ | ||
- | < | ||
- | |||
- | [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\WebClient\Parameters] | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | |||