mp4와 js의 잘못된 MIME 유형 (Content-Type 헤더)

안녕하세요!

최근에 Discourse가 여러 파일 유형에 대해 잘못된 Content-type 헤더를 추가하고 있음을 발견했습니다:
mp4 파일이 /uploads/에서 application/mp4 대신 video/mp4로 전송되어야 하는데 application/mp4로 전송되고 있습니다
제 업로드는 S3를 통해 이루어졌으므로 이는 S3 호스팅 제공업체의 책임입니다.

일부 JavaScript(.js) 파일, 예를 들어 /brotli_asset/에서 오는 경우, text/javascript 대신 application/javascript로 전송됩니다.

저는 수정 사항 없이 discourse_docker를 사용 중이며, 포함된 nginx를 확인해 보니 올바른 mime-types 구성 파일이 포함되어 있습니다. 잘못된 mime-types를 전송하는 것은 Discourse 백엔드의 문제인 것 같습니다.

안녕하세요! 제가 파악한 바로는 업로드 문제는 제 쪽에서 발생한 것이며, S3 제공업체 때문에 생긴 문제였습니다 (nginx 설정을 직접 덮어써서 성공적으로 해결했습니다). 그리고 /brotli_asset/의 JS 관련 문제는 discourse의 내부 nginx 어딘가에 있는 것 같아서, discourse_docker의 버그인 것으로 보입니다.
부끄럽지만 이 포럼의 이 섹션보다 버그를 보고할 더 나은 장소를 찾지 못했습니다. 혹시 어디에 보고하면 좋을지 알려주실 수 있을까요?

이곳이 맞는 곳이니, 잘 찾으신 거예요.

왜 이것이 우리가 신경 써야 할 문제인지 설명해 주시겠어요? 뭔가 깨지는 부분이 있나요?

요약하자면, Discourse는 서로 다른 위치에서 서로 다른 MIME 유형을 사용하여 JavaScript를 전송합니다. 예를 들어 /theme-javascripts/ff3c633d0d4192c83a194066eaa9d823b5c2d8f6.js는 text/javascript(정확함)와 함께 전송되는 반면, 앞서 언급한 /brotli_asset/…는 application/javascript와 함께 전송됩니다. 이로 인해 Discourse와 클라이언트 사이의 프록시 서버나 분석 시스템에서 혼란이 생길 수 있으며, 저 역시 이 문제를 해당 시스템에서 확인했습니다.

Discourse 도커 이미지에서 브로틀리(brotli) 자산에 대해 내부 nginx를 올바르게 설정하기만 하면 될 것 같습니다.

이 문제로 인해 장애가 발생한 프록시/분석 시스템의 이름을 알려 주시겠어요? 실제 환경에서 이 문제가 발생한 사례를 하나 공유해 주시겠어요?

goaccess 리포트의 MIME 유형 대시보드에서 Discourse의 JS 값이 두 개로 나뉘어 있습니다. 하나는 text/javascript이고, 다른 하나는 application/javascript입니다.

두 번째로, nginx의 gzip_types와 brotli_types 지시문은 모두 MIME 유형을 기반으로 작동합니다. 따라서 Discourse 사용자는 올바른 text/javascript와 잘못된 application/javascript를 모두 설정해야 합니다.
MIME 유형을 기반으로 콘텐츠를 다시 압축하는 프록시도 마찬가지입니다.

이 문제가 작은 오류, 또는 원치 않는 동작을 유발한다고 생각하여 이 주제를 다시 올립니다.

Discourse에 호스팅된 비디오 파일을 열면 브라우저에서 재생되는 대신 비디오가 다운로드됩니다.

우클릭하여 비디오 주소를 복사한 후, 브라우저의 주소창에 해당 링크를 붙여넣으세요.

이상한 점은 로컬 개발 환경에서는 비디오가 브라우저에서 정상적으로 재생된다는 것입니다:

비디오 URL을 로드할 때, 일반 설치 환경과 개발 설치 환경 간에 헤더가 다릅니다.

일반 프로덕션 설치 환경에서는 비디오 content-type이 application/mp4로 설정되어 있는 반면, 개발 설치 환경에서는 video/mp4로 설정되어 있습니다.

PDF에서 비슷한 원치 않는 동작을 수정한 사례가 있으므로 Discourse send PDF inline 크로스포스팅합니다.

mp4가 강제로 다운로드되지 않도록 막는 해결책이 있으시다면 조언을 구합니다.

4개의 좋아요

좋은 지적이네요 - 이상하군요.

MiniMime(우리가 사용하고 소유하는 라이브러리)이 이 값들을 반환하고 있는 것 같습니다.

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

PR을 생성하고, 이 값들을 변경하는 것이 문제가 되는지 논의하겠습니다.

5개의 좋아요

간단히 업데이트드립니다 -

위에서 언급한 우리가 사용하는 ext_mime_dbIANA 미디어 유형을 따릅니다. 안타깝게도 이는 mp4application/mp4로 설정되는 것이 올바른 것임을 의미합니다 :sweat_smile:


다만, S3 업로더 구현을 더 자세히 살펴보니 이미지 이외의 거의 모든 업로드에 Content-Disposition 헤더 "attachment"가 추가되고 있음을 확인했습니다. 이는 본래 svg 파일에만 추가될 의도였던 것으로 보입니다. "attachment"를 사용하면 콘텐츠가 새 탭에서 열리는 대신 다운로드됩니다. 영상의 경우 application/videoattachment가 함께 사용되면서 이러한 문제가 발생하고 있습니다.

최소 이 헤더는 제거할 수 있을 것 같습니다.

3개의 좋아요

완전히 이해가 잘 안 되어서 이 PR에 대해 간단한 질문을 드립니다 :person_raising_hand:

s3를 사용하지 않아도 강제 다운로드가 발생하는데, 왜 수정 사항이 구체적으로 s3 관련 파일만 대상으로 하는 건가요? :thinking:

그래도 일반적으로 문제가 해결되나요?
브라우저에서 열 수 있는 PDF 같은 다른 파일의 강제 다운로드 문제도 함께 해결되나요?

S3에 업로드할 때 파일의 Content-DispositionContent-Type과 같은 헤더를 지정해야 합니다. 이러한 값들은 파일을 로드할 때 반환되는 값입니다 - PutObject - Amazon S3

이것이 언제 발생하는지 설명해 주시겠습니까?

해당 PR은 어떤 브라우저를 사용하든 다운로드를 강제하는 Content-Disposition: attachment 헤더를 제거합니다.

사이트를 업그레이드한 후에는 Content-Type이 대신 사용되며, 브라우저가 이를 어떻게 처리할지 결정합니다. 참고할 점으로, Safari와 Firefox에서는 Content-Type: application/mp4에 문제가 없지만, Chrome에서는 여전히 다운로드가 강제됩니다(이는 아마도 Chrome이 mp4 파일 형식과 가진 좋지 않은 역사 때문일 것입니다).

2개의 좋아요

Mp4 files are downloading instead of displaying inline 링크로 병합하여 종료합니다