Простая система ведения файлового хранилища.
Клонируем проект
git clone https://github.com/sekerin/xsolla-test.git
Создаем переменные окружения для бэкэнда:
cd backend/
ln -s .env.dist .env
Создаем переменные окружения для docker:
cd ../
ln -s .env.dist .env
Устанавливаем зависимости
composer install
- для бэкэнда
npm i
- для фронтенда
Запускаем с помощью docker-compose
docker-compose up
Система будет доступна по адресу http://sf.local/. Хосты sf.local, sf-assets.local и symfony-stack.local необходимо добавить в файл hosts системы, с IP по которому доступен Docker.
http://sf.local - форнтенд приложения
http://sf-assets.local - Webpack dev server
http://symfony-stack.local - бэкэнд
{
errors: [ string ]
}
GET /files/
Массив метаданных файлов
{
items: [
{
name: string,
path: string,
size: int,
mime: string
},...
]
}
POST /files/
- file - файл, загружаемый пользователем
Метаданные загруженного файла
{
item: {
name: string,
path: string,
size: int,
mime: string
}
}
- 409 - Файл уже существует
POST /files/filename
, где filename - имя файла, который необходимо обновить
- file - файл, загружаемый пользователем
Метаданные обновленного файла
{
item: {
name: string,
path: string,
size: int,
mime: string
}
}
- 404 - файла не существует
DELETE /file/filename
, где filename - имя файла, который необходимо удалить
Имя удаленного файла
{
item: {
name: string
}
}
- 404 - файла не существует
Для сжатия настроен nginx, для всех запросов в заголовке есть Accept-Encoding: gzip
:
gzip on;
gzip_types text/plain application/xml application/json;
gzip_proxied any;
gzip_min_length 1000;
gunzip on;
Для поддержки gzip запросов необходимо установить в nginx модули nginx-extras
lua-zlib
и реализовать декомпрессию на Lua.
Для оптимизации используемой памяти при работе с файлами используются потоки
Система использует стримы, по этому реализация заключается в добавлении к загрузке сжимаюещго потокового фильтра zlib.deflate
stream_filter_append($stream, 'zlib.deflate', STREAM_FILTER_WRITE)
. При отдаче файла необходимо использовать фильтр zlib.inflate
stream_filter_append($file, 'zlib.inflate')
Мржно реализовать через блокировку потоков для перезаписи.
Отдача файлов кусками
function readfile_chunked($filename, $retbytes = true)
{
$buffer = "";
$cnt = 0;
$handle = fopen($filename, "rb");
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, CHUNK_SIZE);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes & $status) {
return $cnt;
}
return $status;
}
Настройка для nginx client_max_body_size max_size;
, где max_size - максималный размер файла.
Настройки для php post_max_size = max_size
и upload_max_filesize = max_size
, где max_size - максималный размер файла.
Лучше всего установить ssl для проксирующего nginx
...
listen 443 ssl;
...
ssl_certificate certificate_bundled.crt;
ssl_certificate_key private.key;
...
Использование CORS протокола. Реализовано через отдельный action, принимающий OPTIONS запросы в контроллере. Разрешенный хост указывается через переменную окружения CORS_ACCEPT.
Можно (будет более правильно) исползовать библиотеку NelmioCorsBundle.
Для аутентификации в апи можно использовать пакет symfony/security-bundle
.
Создать реализауию UserInterface
, определения пользователя.
Созрать реализацю UserProviderInterface
для определения места хранения пользователей.
Созадть реализацию интерфейса AbstractGuardAuthenticator
- непосредственно процесс аутентификации
Настроить security-bundle, добавив реализацию реализацию интерфейса AbstractGuardAuthenticator
в секцию guard/ authenticators
В каждом запросе передавать заголовок X-AUTH-TOKEN, по которому аутентифицировать пользователя, в случае ошибки возвращать:
{
authentificate: false,
errors: []
}
В случае успеха:
{
authentificate: true,
token: string
}
В случае ошибки фронтэнд должен удалить старый токен и показать пользователю форму аутентификации. В случае успеха - записать токен и передавать его во всех запросах.
Настройки пользователя лучше хранить в том же месте, где хранится данныве пользователя. При хранении в базе данных лучше создать view или хранимую процедуру для получения занятого места.
При использовании Unix аутентификации (PAM) можно использовать квоты файловой системы при монтировании файловой системы. Создаем пользователя - создаем ему директорию - монтируем ему ограниченную ФС в эту директоирию. При таком подходе дополнительной обработки файловых квот не требуется.