LINUX.ORG.RU

Чеклист: загрузка аватаров на сервер, что учесть

 , , , ,


0

1

Итак, что нужно учитывать при организации фичи, позволяющей грузить аватары?

  1. Загруженные файлы не должны исполняться (особенно актуально в случае пыха).
  2. Отвергаем слишком большие запросы?
  3. Валидацию чего-нибудь типа mime-type, extension производим?
  4. Делаем resize, удаляем всю метаинформацию.
  5. Храним в файловой системе?
  6. В качестве имени используем что-нибудь своё. Хеш файла?
  7. В одной корзине все яйца директории все файлы не храним, раскидываем по разным на основе хеша (или чего)? Используем несколько уровней вложенности (filename -> fi/le/na/me.png), сколько?
  8. Как отдаём? Напрямую сервером?
  9. Отдаём статику (в том числе аватары) отдельным cookieless сервером с отдельным доменом.
  10. Превьюшки делаем сразу при загрузке? А если в процессе требование к размеру превьюшки меняется (вчера нужны были 50x50, сегодня 100x100, а с новым дизайном завтра нужно будет 80x80)?


Последнее исправление: nonammy (всего исправлений: 3)

Зачем ты перечислил всё что нужно сделать?

Превьюшки делаем сразу при загрузке? А если в процессе требование к размеру превьюшки меняется

Тогда делай ресайз сразу в несколько размеров. К тому же, вписать картинку побольше в макет можно с помощью css.

ritsufag ★★★★★
()
Ответ на: комментарий от ritsufag

К тому же, вписать картинку побольше в макет можно с помощью css.

Так юзеры же будут страдать, грузить лишнее.

nonammy
() автор топика

А если в процессе требование к размеру превьюшки меняется

Для этого нужен оригинал

goingUp ★★★★★
()

Зачем писать на ЛОР, если и так все правильно расписал? Разве что:

В качестве имени используем что-нибудь своё. Хеш файла?

Или просто id юзера.

Превьюшки делаем сразу при загрузке? А если в процессе требование к размеру превьюшки меняется (вчера нужны были 50x50, сегодня 100x100, а с новым дизайном завтра нужно будет 80x80)?

Храним и оригинал, и превью. При необходимости просто используем оригинал, чтобы сделать превью нужного размера.

ktan ★★★
()
Последнее исправление: ktan (всего исправлений: 1)
Ответ на: комментарий от nonammy

Если ресайзнешь в 100px для 50/80 и 250px для 150/200, то «лишнего» будет совсем немного.
А так если хочешь гибкости, то придётся хранить оригинал и ресайзить все аватарки.

ritsufag ★★★★★
()

Я заметил, многие пыхеры ресайзят динамически (по запросу). Да взять хотя бы Gravatar (хотя они, наверняка, и кешируют ещё). Насколько это плохая идея?

nonammy
() автор топика
Ответ на: комментарий от nonammy

Динамически ли? Не, если у тебя 100500 процессоров и серверов, которым не напряжно картинки поресайзить, то, конечно, можно. А, и по SSD на аватарку ещё :}

Deleted
()
Последнее исправление: Mystra_x64 (всего исправлений: 1)

можно ещё распознавалку изображений прикрутить какую-нибудь, чтоб там матерные слова блокировала, прон, кровь-кишки или ещё что-нить в таком роде

Harald ★★★★★
()

6. В качестве имени используем что-нибудь своё. Хеш файла?

Нахрена файла, достаточно хэш имени. А можно не заморачиваться и просто использовать случайную строку.

7.В одной корзине все яйца директории все файлы не храним

А в чем проблема, у тебя 1000000 пользователей?

Используем несколько уровней вложенности (filename -> fi/le/na/me.png), сколько?

Достаточно по каталогу на первый символ имени. Если будет случайная строка, то файлы распределяться по (26*2+10) каталогам равномерно. Не хватает? Раскидывай по 2 первым символам и т.д.

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

Превьюшки делаем сразу при загрузке?

Да.

А если в процессе требование к размеру превьюшки меняется (вчера нужны были 50x50, сегодня 100x100, а с новым дизайном завтра нужно будет 80x80)?

Делай 2-3 размера в зависимости от логики дизайна. Новые 80x80 не нужно - пусть берут 100x100, масштабирование и кэширование в браузере никто не отменял. Ну а если всё таки нужно, то, опять же, переобуйся на новый размер ресайза, а старые отдавай как есть.

no-such-file ★★★★★
()
Ответ на: комментарий от ktan

Или просто id юзера.

Это плохо совмещается с кэшем браузера и всякими кэширующими прокси. Нужно чтобы uri менялся каждый раз при изменении аватарки.

no-such-file ★★★★★
()

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

Harald ★★★★★
()

Отдаём статику ... отдельным доменом.

Нафига так делать? Вообще запретить подобную ересь, чтоб всякие фейспуки и прочие шпионы обломились.

anonymous
()

Загруженные файлы не должны исполняться (особенно актуально в случае пыха).

Да, поэтому проверяем расширение и не даем его изменить. Разрешаем грузить только определенные расширения

Отвергаем слишком большие запросы?

Дважды. Сначала на уровне веб-сервера, с большим допуском на размер, например 10М. Потом на уровне приложения специально для аватара, допустим 500Кб. Это все на случай, если понадобится загружать что-то еще, например большие pdf.

Валидацию чего-нибудь типа mime-type, extension производим?

extension см. 1, mime-type в принципе не обязательно, можно считать, что грузят с правильным расширением. Можно сделать пареллельно с масштабированием тумб, если тумбы не делаем, то можно и пропустить.

Делаем resize, удаляем всю метаинформацию.

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

Храним в файловой системе?

Да. Если очень много, используем облачные файловые системы. Метаданные, вроде размера, можно закешировать в базе. Еще можно сразу выгрузить на CDN.

В качестве имени используем что-нибудь своё. Хеш файла?

Хеш картинки нельзя, это медленно и люди часто загружают одинаковые картинки аватарами. Если это аватар (один на пользователя) то используем уникальный ID пользователя. Если картинок может быть много, то уникальный ID + текущее время + какой-нибудь рандом. Будет достаточно надежно. Если требования к отсутствию коллизий очень важны - то используем внешний счетчик.

В одной корзине все яйца директории все файлы не храним, раскидываем по разным на основе хеша (или чего)? Используем несколько уровней вложенности (filename -> fi/le/na/me.png), сколько?

Если пользователей до сотни тысяч, можно и в одной директории. Если больше, бьем по датам, уровни вложенности /год/месяц/день/файл. Если совсем много, придется делать горизонтальное масштабирование, использовать CDN ну и вообще это уже другая задача.

Как отдаём? Напрямую сервером?

Если важна скорость и картинок много, можно использовать cdn. А можно и сервером.

Отдаём статику (в том числе аватары) отдельным cookieless сервером с отдельным доменом.

Да в принципе необязательно. Можно просто пути в nginx настроить и отдавать тем же доменом. К этому и предыдущему пункту - если есть требование, что картинки должны быть видны только определенным пользователям (друзьям) а остальным нет, то увы - придется использовать для отображения картинок динамику. При запросе проверять права, потом отдавать картинку чем-то вроде x-sendfile/x-accel-redirect.

Превьюшки делаем сразу при загрузке? А если в процессе требование к размеру превьюшки меняется (вчера нужны были 50x50, сегодня 100x100, а с новым дизайном завтра нужно будет 80x80)?

Тумбы делаем в процессе загрузки сразу для всех необходимых размеров. Если требования меняются, что бывает редко, пишем скрипт и перегенерируем. Или просто делать одну большую тумбу для каждого необходимого сотношения сторон, а в css прописать размеры для масштабирования.

shimshimshim
()
Ответ на: комментарий от shimshimshim

Годный ответ, выбрал как правильный.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.