Неверные mime-типы (заголовок content-type) для mp4 и js

Привет!

Я только что заметил, что Discourse отправляет неверные заголовки Content-Type для нескольких типов файлов:
mp4-файлы из /uploads/ передаются с content-type: application/mp4 вместо video/mp4
мои файлы загружались через S3, поэтому это зависит от хостинг-провайдера S3.

Некоторые файлы JavaScript (.js), например из /brotli_asset/, передаются с content-type: application/javascript вместо text/javascript.

Я использую discourse_docker без каких-либо изменений, проверил включённый nginx — в нём содержится правильный файл конфигурации MIME-типов. Похоже, что проблема в бэкенде Discourse, который отправляет эти неверные MIME-типы.

Привет! Насколько я понял, проблема с загрузкой была на моей стороне и вызвана провайдером S3 (я успешно решил её, переопределив настройку в моём nginx). А проблема с JS из /brotli_asset/ находится где-то во «внутреннем» nginx в Discourse, так что, похоже, это баг в discourse_docker.
Мне стыдно, но я не смог найти лучшего места для сообщения об ошибке, чем эта часть форума. Не могли бы вы подсказать, куда обратиться?

Это правильное место, вы его нашли.

Не могли бы вы объяснить, почему это проблема, которая должна нас волновать? Это что-то ломает?

Коротко: Discourse отправляет JavaScript-файлы с разных путей и с разными MIME-типами. Например, /theme-javascripts/ff3c633d0d4192c83a194066eaa9d823b5c2d8f6.js передаётся с типом text/javascript (правильно), а упомянутый ранее /brotli_asset/… — с типом application/javascript. Это может сбить с толку прокси-серверы между Discourse и клиентом, а также аналитические системы, где я и столкнулся с этой проблемой.

Похоже, вам просто нужно правильно настроить внутренний nginx в Docker-образе Discourse для ресурсов с сжатием brotli.

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

В моих отчётах goaccess на панели управления mime-types для Discourse значения для js разделены: одно для text/javascript, другое для application/javascript.

Второй вариант: директивы gzip_types и brotli_types в nginx работают на основе mime-типов. Поэтому пользователям Discourse приходится настраивать как правильный text/javascript, так и некорректный application/javascript.

То же самое относится к любому прокси-серверу, который повторно сжимает контент на основе mime-типа.

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

Открытие видеофайла, размещённого на Discourse, вызывает его загрузку вместо воспроизведения в браузере.

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

Странно то, что на локальной установке для разработки видео корректно воспроизводится в браузере:

При загрузке URL видео заголовки отличаются между обычной установкой и установкой для разработки.

На обычной продакшн-установке тип контента видео установлен как application/mp4, тогда как на установке для разработки — video/mp4.

Дублирую пост: Discourse send PDF inline, так как автор исправил аналогичное нежелательное поведение для PDF-файлов.

Буду благодарен за любые предложения по решению проблемы, чтобы mp4-файлы не принудительно загружались.

4 лайка

Отличное обнаружение — это странно.

Похоже, что MiniMime (библиотека, которую мы используем и поддерживаем) может возвращать эти значения:

pry(main)> MiniMime.lookup_by_filename("a.mp4").content_type
=> "application/mp4"

Я создам PR, и мы обсудим, является ли изменение этих значений проблемой.

5 лайков

Вот небольшая информация —

База ext_mime_db, которую мы используем, следует стандартам IANA Media Types, описанным здесь — https://www.iana.org/assignments/media-types/media-types.xhtml. К сожалению, это означает, что mp4 правильно определяется как application/mp4 :sweat_smile:


Однако, при более детальном рассмотрении нашей реализации загрузчика S3 я заметил, что мы добавляем заголовок Content-Disposition со значением "attachment" практически для всех загружаемых файлов, кроме изображений. Похоже, что это должно было применяться только к SVG-файлам. Использование "attachment" приводит к тому, что контент загружается на устройство вместо открытия в новой вкладке. Для видео проблема возникает из-за комбинации application/video и attachment.

Я думаю, что мы как минимум можем убрать этот заголовок.

3 лайка

Не совсем уверен, что всё понял, поэтому задам короткий вопрос по этому PR :person_raising_hand:

Почему изменения нацелены конкретно на файлы, связанные с S3, если принудительная загрузка происходит даже без использования S3? :thinking:

Исправит ли это проблему в целом?
Исправит ли это также принудительную загрузку для других файлов, которые можно открыть в браузере, например PDF?

При загрузке в S3 необходимо указывать заголовки, такие как Content-Disposition и Content-Type файла. Именно эти значения будут возвращаться при загрузке файла — PutObject - Amazon Simple Storage Service

Не могли бы вы пояснить, в каких случаях это происходит?

В этом PR будет удалён заголовок Content-Disposition: attachment, который принудительно инициирует загрузку независимо от используемого браузера.

После обновления вашего сайта вместо этого будет использоваться заголовок Content-Type, и браузер сам решит, что с ним делать. Стоит отметить, что с Content-Type: application/mp4 проблем нет в Safari и Firefox, но в Chrome всё ещё происходит принудительная загрузка (вероятно, из-за негативной истории Chrome с типом файла mp4).

2 лайка

Закрыто в пользу Mp4 files are downloading instead of displaying inline