Файлы, обслуживаемые Aqueduct, не имеют заголовка Content-Length - PullRequest
0 голосов
/ 20 апреля 2020

Я пишу бэкэнд для своего приложения Flutter, используя Aqueduct. У меня Aqueduct настроен так, что Nginx прокси-запросы к нему, как это:

server {

    root /home/web/my_server/web;
    index index.html index.htm;

    server_name example.com www.example.com;

    location / {
        try_files $uri $uri/ =404;
    }

    location /api {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://127.0.0.1:8888;
        proxy_http_version 1.1;
    }

    ...
}

В Aqueduct я обслуживаю файлы, используя FileController:

router.route("/api/v1/app/*")
    .link(() => LogController(context))
    .link(() => FileController("public/app/")
  ..setContentTypeForExtension('apk', ContentType('application', 'vnd.android.package-archive')));

Однако, любой возвращаемые файлы не содержат заголовок Content-Length. Это означает, что я не могу показать прогресс загрузки.

Я попытался создать пользовательский FileController, в который я добавил заголовки вручную:

final contentLengthValue = file.lengthSync();

return Response.ok(byteStream,
    headers: {HttpHeaders.lastModifiedHeader: lastModifiedDateStringValue,
      HttpHeaders.contentLengthHeader: contentLengthValue,
      'x-decompressed-content-length': contentLengthValue,
      HttpHeaders.cacheControlHeader: 'no-transform',
      HttpHeaders.acceptRangesHeader: 'bytes'})
  ..cachePolicy = _policyForFile(file)
  ..encodeBody = false
  ..contentType = contentType;

Заголовок Content-Length все еще был удален, но заголовок x-decompressed-content-length остался, так что это возможно обходной путь. Он просто не очень хорошо работает с некоторыми плагинами Flutter, которые ищут заголовок Content-Length и не имеют удобного способа проверки других заголовков.

Это проблема Акведука или Nginx? Как мне это решить?

1 Ответ

1 голос
/ 20 апреля 2020

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

Вместо того, чтобы файлы подачи в Акведук, просто Nginx обслуживают их напрямую.

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

location /api/v1/app/ {
    alias /home/web/my_server/public/app/;
}

Теперь файлы в папке app/ будут обслуживаться Nginx, а не акведуком. Nginx включает заголовок Content-Length в возвращаемых файлах.

...