Компания
362,52
рейтинг
19 марта 2013 в 12:12

Разработка → Как мы выбрали и реализовали WebDAV в Яндекс.Диске

Уже в момент запуска Яндекс.Диск дал многим разработчиками возможность использовать его в своих приложениях и программах. И обеспечивает это то, что протоколом для десктопных клиентов Диска мы выбрали WebDAV.

Так как именно протокол определяет то, как общаются между собой программы и сервер, от его выбора зависит примерно всё. И то, как будут устроены клиенты, и то, какие возможности работы с файлами у них будут.

Красная кнопка — WebDAV

Сегодня мы хотим рассказать о причинах, которые остановили наш выбор именно на WebDAV и сделали его протоколом для клиентов Яндекс.Диска.

Благодаря API, реализованному на его базе, с нашим сервисом уже работают ABBYY FineScanner, Handy Backup 7, ES Проводник и неофициальный клиент Яндекс.Диска для Linux.

Перед тем как выбрать протокол, мы определили для себя важнейшие требования к нему:

  1. Скорость работы;
  2. Открытая лицензия;
  3. Возможность реализации всех необходимых действий: аутентификации, поддержки файловых операций, конкурентного доступа к файлам, докачки с сервера и возобновления закачки на сервер;
  4. Распространённость — он должен работать с целевыми операционными системами (в первую очередь Windows, Mac OS X, Linux) «из коробки» или с минимальными доработками.

Мы даже были готовы разрабатывать свой собственный протокол, если бы существующие нам не подошли. Изменение протокола после запуска потребовало бы много человекочасов работы, поэтому нужно было изучить разные варианты и выбрать лучше всего отвечающий нашим требованиям.

FTP. Этот протокол для удалённой работы с файлами проверен временем. Но создавался он без учёта требований информационной безопасности, что стало для нас его существенным недостатком. Помимо этого, он не поддерживает многие необходимые нам операции, например, передачу метаданных вместе с содержимым файла. И требует для подключения специальные приложения.

BitTorrent. Так как речь сразу шла о синхронизации между девайсами, то использовать соединение между ними без создания нагрузки на серверы было бы очень полезно, но это потребовало бы двойной работы по разработке клиента. Вдобавок возникли бы проблемы при работе через NAT-ы и firewall-ы, что сильно снизило бы пользу от использования этого протокола.

Amazon S3. Это хранилище использует свой собственный протокол, основанный на HTTP. Мы рассматривали возможность использования API S3, однако отказались от этой идеи из-за отсутствия в нём привычной работы с каталогами и из-за необходимости использовать специальные приложения для доступа.

WebDAV. Основанный на HTTP и XML и нетрудно расширяемый, он поддерживает в спецификациях практически все, что нам нужно. C ним достаточно хорошо работают предустановленные пакеты во всех целевых операционных системах. Кроме того отдел разработки десктопных клиентов Яндекс.Диска, занимавшийся XMPP-сервером Яндекса, на тот момент уже имел опыт работы с открытыми протоколами на базе XML.

Главной причиной, по которой нам не хотелось создавать свой собственный протокол, было то, что работать с ним смогут только наши приложения, а мы хотели открытости.

В итоге, из всех обсуждавшихся вариантов мы выбрали WebDAV. Единственное, чего не хватало в протоколе — это информирования клиента об изменениях на сервере, очень важной фичи синхронизации. Но так как протокол расширяем, это не стало проблемой.

После выбора протокола началась работа над прототипом Яндекс.Диска. Наш WebDAV-сервер мы написали на Erlang. В качестве фреймворка для веб-сервера был выбран mochiweb, достаточно легковесная и хорошо знакомая нашим разработчикам библиотека. Она же была использована в известной статье о подключении миллиона пользователей к одному серверу — A million user comet application. Также мы думали и об использовании веб-сервера Yaws, который можно сравнить с Apache. Это полноценный веб-сервер, умеющий отдавать статику, запускать CGI-скрипты, обрабатывать специальные страницы с серверными скриптами. Но это всё было нам не нужно. Если бы мы начинали делать проект сейчас, выбор пал бы на Cowboy, так как он предоставляет больше возможностей по определению проблем с соединением.

После изучения протокола WebDAV началась работа над операциями листинга файлов и каталогов на сервере. В качестве хранилища для прототипа использовались mysql-база данных, в которой хранилась мета-информация и обычная файловая система для хранения содержимого файлов. Масштабирования и высокой надёжности на этом этапе не требовалось.

Схема была довольно простой, так как это был прототип. Как обычно бывает с файловыми системами, встал вопрос ограничений на пути. Так как максимальная длина пути к ресурсу в протоколе не оговаривалась, было решено сделать длину компоненты пути в 255 символов, а количество уровней вложенности неограниченным. Примерно таблица хранилища файлов выглядела так:
id число, автоинкремент, уникальный идентификатор ресурса
uid пользователь, владелец ресурса
path строка длины 255, имя ресурса
type тип ресурса, файл или каталог
parent число, id владельца
depth число, уровень вложенности ресурса
использовалось для оптимизации запросов на выборку

Одной из первых нетривиальных задач стал листинг корня, в котором ничего нет. Сложность в том, что метод PROPFIND, кроме просто листинга, выполняет ещё и задачу чтения свойств ресурса. Необходимо было правильно разбирать запрос, понимать, что мы можем выдать, а что нет; формировать правильный ответ. В качестве первого клиента использовался встроенный в Ubuntu gvfs. Отладив работу с ним, мы решили проверить работу подключения из Windows 7 и обнаружили, что он с нами не работает. Исследование работы с другими серверами показало, что встроенные в Windows клиенты не обрабатывают пространство имён «DAV:», если оно объявлено дефолтным, без префикса. Другие стандартные клиенты оказались более терпимыми и легко переваривали выдачу, сформированную специально для клиентов Windows. К счастью, это была единственная несовместимость, которую нам удалось найти.

Когда работа над листингом была завершена, мы реализовали тривиальные операции создания каталогов и удаления ресусов.

Дальше требовалось научиться заливать файлы, но эта операция была не так проста. А почему — если эта тема будет вам интересна — мы расскажем в следующем посте.
Автор: @bedmitry
Яндекс
рейтинг 362,52

Комментарии (69)

  • +15
    Пишите еще!
  • +3
    «выбор пал бы на Cowboy, так как он предоставляет больше возможностей по определению проблем с соединением» — сколько боли и бессонных ночей я слышу за этой фразой! Интересно было бы почитать, какого рода проблемы возникали и как вы их решали.
    • +3
      Обязательно напишем.
  • +1
    Вопрос не в тему, но мне так и не удалось заставить работать WebDav под XP SP3. Патчи указанные у вас на сайте не помогли. Самое интересное, что после чистой установки обычно один раз подключится удается, а оптом пишет, «Неправильное имя папки. Задайте другое имя.»
    Это будет как то исправляться или для XP уже ждать нечего.
    • +1
      К сожалению, эта какая-то странная ошибка в клиенте, он даже не подключается к нам перед отображением этого сообщения. Так что она не связана с работой сервера и на нашей стороне её решить невозможно.
    • –2
      Вы бы еще NT4 WS поставили…
  • НЛО прилетело и опубликовало эту надпись здесь
    • +4
      Альтернативы, конечно же, есть. Мы же видим, что каждое облачное хранилище создаёт свой собственный неповторимый протокол.
      • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    Erlang был выбран тоже потому что команда была с ним хорошо знакома? (ejabberd)
    • 0
      Именно так.
  • +1
    Охтыжё… Мой диплом, только в промышленном масштабе :)
    • 0
      уровень реализации не выше
      наступают на стандартные грабли, изобретают велосипеды — нет бы поизучать любой из сотни существующих давов, благо многие не скрывают историю доработок
      чего стоит xp sp3, гыгыг
      • 0
        Там всё грустно. Из-за зоопарка, нормальный DAV, обрастает костылями не успев зарелизиться.
  • +9
    Ну как всегда… На самом интересном месте…
  • +1
    Ждем новых откровений!
  • 0
    А расскажите как вы определяете изменение файла? И как следствие необходимость обновления мета-информации о нём в базе и оповещения клиентов о синхронизации.
    • 0
      На сервере? Клиент присылает новое содержимое файла, если его хеши отличаются, значит файл изменился.
      • 0
        А если много и больших файлов «внезапно» изменится? Каждый раз высчитывать хэши для больших файлов довольно накладно как мне кажется.
        • 0
          Я думаю, мы расскажем об этом детально в следующих сериях…
          • 0
            Окей, буду ждать следующей серии.
  • +2
    планируется увеличивать объемы хранилища (за плату разумеется)?
    облако гугла совсем не устраивает, как только объем файлов превышает 100гб клиент начинает отваливаться (windows)
    • 0
      Такая возможность есть планах.
      • 0
        Очень нехватает увеличения, хоть бы и за деньги, как в том же гугле или дропбоксе.
      • 0
        а примерно когда появится, не раскроете?
  • +4
    Вот эта расширяемость вебдава — и есть его беда. Его расширяют как-попало, как клиенты, так и серверы. Майкрософт вон себе кастомную авторизацию туда всобачила — хрен подключишся левым клиентом, информацию о занятом\свободном месте пятью разными способами разные сервера возвращают (а большинство — вообще не возвращает), кто-то аплоадид файлы через PUT, кто-то через POST (причём иногда и тем и тем, а иногда ТОЛЬКО чем-то одним), где-то есть докачка, а где-то нету, кто-то encode\decode именам файлов в полях делает, а кто-то — нет. Яндекс вот себе нотификации об изменениях придумал. Думаете их до этого не придумывали? 150 раз. Думаете, способ Яндекса станет стандартом, войдет во все клиенты? Хрен там.

    Из-за всего этого бардака клиент ВебДава со временем либо превращается в монстра с кучей «если это сервер такой-то — то делаем вот-так», либо перестаёт быть совместимым с рядом серверов.
    Грустно.

    • +5
      Это проблема многих протоколов.
      В XMPP проблему расширяемости решили с помощью XEP — и клиент и сервер при подключении знают, какие расширения поддерживает другая сторона.
  • 0
    До сих пор не удалось подключиться по WebDAV к ЯндексДиску из WinXp sp3. Поправите когда-нибудь или стоит распрощаться с надеждой?
    • 0
      Тут уже выше об этом спрашивали. Обычно эта ошибка возникает при проблемах с подключением к серверу, но бывают случаи, когда например браузером можно нормально подключиться к вебдав-серверу (можно попробовать скачать какой-нибудь файл), а Windows клиент всё-равно выдаёт «Неправильное имя папки». Точную причину этого выяснить не удалось, клиент при этом даже не подключается к серверу и с нашей стороны мы не можем избавить пользователей от этой проблемы.
      • 0
        Увидел пост выше, извините за повтор.
        А свой собственный клиент создать, взамен стандартного, который позволял бы подключать ЯндексДиск как сетевой?
        • 0
          Мы делаем клиенты для синхронизации. Делать приложения для доступа по сети мы не планировали. Для этого есть стандартные клиенты.
          • 0
            Эти клиенты не позволяют подключать диск как сетевой, чтобы данные становились прозрачно доступными для всех.
            • 0
              Если хочется прозрачности для работы приложений, то лучше пользоваться синхронизацией. Обновления файлов по сети могут приводить к ошибкам. У нас были обращения в саппорт по поводу проблем с приложениями, работавшими с содержимым Яндекс.Диска, который был подключён встроенным в MacOSX расширением Finder-а.
    • 0
      Вот сегодня поставил чистую XP SP3 на виртуалку, никаких проблем с подключением. Перезагружался. Несколько подключений делал всё ок. Рядом стоит таже винда но слегка загаженая, там не работает. Видимо кто то из стандартного набора прог обновляет поддержку webdav и ломает её тем самым. Вычислить бы кто это и что меняет.
      • 0
        Да, в виртуалках я не смог воспроизвести эту проблему. Вживую тоже сам не видел. Знаю о ней только через саппорт.
        • 0
          Если нужно могу выложить образ виртуалки, на которой повторяется ошибка.
    • 0
      Попробуйте решение, описаное здесь: chapters.marssociety.org/webdav/
  • +1
    Также стоим перед выбором. WebDAV или GIT?
    У нас одним из камней является важность версионирования.
    Текущая система хранения документов позволяет создавать версии, но не позволяет править файлы прямо на сервере. Приходится скачивать, а потом закачивать обратно. Это проблема.

    Наслышаны о WebDAV и его возможности работать с версиями, но в Яндекс.Диске эта возможность отсутствует. Было бы интересно раскрыть эту часть. Планировали? Решали? Разбирали?
    • 0
      Версионирование — это полезное дополнение к обычному файловому хранилищу. Наличие этой фичи в протоколе — дополнительный плюс. Однако, на текущем этапе мы не считаем её критичной, так как есть более востребованые функции.
      • 0
        Сразу вылезает проблема как хранить версии и быстро получать конкретную версию файла. Я хранил просто копии, но это было ни разу не подходящим решением, а сделать бинарные diff'ы не позволили сроки.
        • 0
          Хранение диффов сильно усложняет работу с файлами. Конечно, всё решается, но чем проще система, тем легче её поддерживать. Поэтому лично я бы воспользовался хранением диффов только в случае жёстких требований по минимизации хранилища.
          • 0
            Насколько я понимаю, у вас будет как раз подобный случай, если надумаете делать версионирование. Я конечно не знаю насколько много файлов хранится на яндекс.диске, но если хотя бы 10% будут иметь больше десятка версий, то их хранение будет накладно.

            Я когда над этим вопросом думал, у меня вырисовывалась гибридная схема, что часть файлов не версионируется вообще, часть файлов версионируется до определённой глубины, оставшаяся часть версионируется от и до.

            При версионировании используются бинарные/текстовые диффы(mimetype, да) и возможно хранятся полные копии, некоторых версий, если к ним надо иметь быстрый доступ — суть кэш.

            Ну и соответственно никаких веток и мержей.

            Но диплом закончился, а внедрение в «боевые условия» не пошло. И к лучшему наверное :)
      • 0
        Для исключения порчи данных была бы полезна хотя бы возможность заливать файл, если текущая версия равна указанной клиентом (последней, про которую знает клиент).
  • 0
    Вопрос не в тему, а почему у подключенного пустого Яндекс.Диска (10 Гб, Win8) в проводнике показывает 55 гб (из которых свободно 7 Гб). Что за баг?
    • 0
      Это особенность Windows-клиентов. Они не запрашивают квоты сервера, а просто выдают данные с какого-то раздела локальной файловой системы.
      • 0
        Спасибо, понял.
  • +1
    Скажите, ждать ли самостоятельный клиент для Убунту, или навечно останется Наутилус?
    • 0
      Мы думаем об этом.
    • 0
      А в чём приемущества native-клиента? Меня вполне устраивает davfs раздел, монтирующийся после входа
      • +1
        Ну например: оповещение об изменениях, сделанных на другой машине, статус полной синхронизации, красивая иконка в трее. :)
  • +1
    Скажите, а файлы одного клиента, я так понимаю, могут лежать на разных стореджах? Как вы решаете эту проблему? Сервер на erlang проксирует отдачу файлов клиенту с разных машин? или используйте 301 редирект в таком случае? вроде как часть клиентов его использует, но к сожалению далеко не все.
    • +1
      Мы обязательно об этом расскажем… в следующих частях истории.
    • 0
      заголовки все в базе данных описаны, а где файлы физически лежат — вообще никакой разницы
  • 0
  • 0
    Когда будет возможно расшаривать папки или по крайней мере файлы мультиселектом?
    • 0
      Мы думаем о такой возможности. Расскажите, такая фича нужна скорее в веб-интерфейсе Диска или в десктопных клиентах?
      • 0
        Везде. Раньше в народе была возможность шарить файлы по галкам. А сейчас нет народа и нет фичи. Сделайте где проще хотябы. Главное чтобы урлы копировались в буфер как в народе.
  • 0
    Странно, что про FTP вы пишете «требует для подключения специальные приложения». В большинстве современных ОС есть встроенная поддержка FTP.
    • 0
      Скачивать все умеют. А вот заливать — не уверен.
      • 0
        В Windows проводник умеет. Во всех Linux, которые я видел, тоже можно заливать.
  • 0
    А rsync вообще не рассматривали, получается? Он ведь, вроде как, именно для ваших целей и разработан — для синхронизации файлов.
    • 0
      Рассматривали, но не как протокол.
      • 0
        А как протокол он чем хуже/лучше?
        • 0
          Как протокол он не подходил по причине необходимости специализированного ПО для работы с хранилищем.
  • 0
    davfs под Линуксом — это настоящая боль.
    0. Вообще нет локальной копии данных.
    1. Через GUI-клиент нельзя работать с данными напрямую и вообще все GUI-клиенты — это кошмарное вышивание бисером. Только консоль и Миднайт, только хардкор!
    2. davfs однопоточен, поэтому пока сбрасываются буфера любая прога, сунувшаяся в каталог на davfs, тупо зависает. Если идёт запись больших файлов то это капут.
    3. Монтирование davfs — не самая удобная операция. Кстати, в вашем мануале не написано, что надо делать /etc/davfs2/davfs2.conf => delay_upload 0, иначе пункт 2 становится фатальным (монтировать просто не следует — при попытке залить в мегабайты данных всё заклинивает без какого-либо фидбэка). Кстати, это всё требует рута на компе, чего в продвинутой организации может быть и не у всех.

    А теперь сравните это с Дропбоксом — я вообще ничего не делаю, кроме разовой установки клиента за пару минут, и дальше всё работает годами без малейшего внимания с моей стороны, не тормозит ни на йоту, прерывается моментально (например, при перезагрузке компа) и копия всего лежит локально — с-но локальная скорость работы с данными, а в случае сбоя сети, например, вообще никаких проблем не возникает. Как поймает сетку, так сам и синхронизирует.
    Моё убеждение: для облачного хранилища рулит только подход Дропбокса, а всё остальное это просто баловство.
    • 0
      Да, синхронизация во многих случаях удобней работы с удалённым хранилищем. Как я уже писал выше, мы думаем над реализацией синхронизирующего клиента под линукс.
  • 0
    Вот бы фотку, где все это храниться…
  • +1
    Хорошо сделано. В OS/2 при помощи NetDrive с NDPDAV плагином работает без проблем(я думаю что и cadaver тоже заработает). Понятное дело что на сервер уходят только файлы, без расширенных атрибутов, но для этого наверное нужно использовать ваше расширение протокола. Как я понимаю можно хранить любую метаинформацию?
    image
  • 0
    При закачке большого файла (2 гига) курлом из под freebsd, под конец закачки (примерно час)
    выдает сообщение:

    SSL read: error:00000000:lib(0):func(0):reason(0), errno 54

    Маленький файл заливается без проблем.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка