[forms] 업로드 된 파일의 MIME 유형은 브라우저에서 어떻게 결정됩니까?

사용자가 .zip 파일을 업로드해야하는 웹 앱이 있습니다. 서버 측에서 업로드 된 파일의 MIME 유형을 확인하여 application/x-zip-compressed또는 application/zip.

이것은 Firefox와 IE에서 잘 작동했습니다. 그러나 동료가 테스트했을 때 Firefox에서는 실패했지만 (보낸 MIME 유형은 ” application/octet-stream” 와 같음 ) Internet Explorer에서 작업했습니다. 모든 추가 기능이 비활성화 된 IE8, FF 3.5.1, Win XP SP3, WinRAR이 기본 .zip 파일 처리기로 설치되어 있습니다 (관련성이 있는지 확실하지 않음).

그래서 내 질문은 브라우저가 보낼 MIME 유형을 어떻게 결정합니까?

참고 : MIME 유형이 브라우저에서 전송되어 신뢰할 수 없다는 것을 알고 있습니다. 나는 단지 편의상 확인하고 있습니다. 주로 zip 파일이 아닌 파일을 zip 파일로 열려고 시도하여 얻는 것보다 더 친숙한 오류 메시지를 제공하고 (아마도 무거운) zip 파일 라이브러리를로드하지 않도록합니다.



답변

크롬

Chrome (작성 당시 버전 38) 에는 MIME 유형을 결정하는 세 가지 방법이 있으며 특정 순서로 수행합니다. 아래 스 니펫은 file src/net/base/mime_util.cc, method 에서 가져온 것 MimeUtil::GetMimeTypeFromExtensionHelper입니다.

// We implement the same algorithm as Mozilla for mapping a file extension to
// a mime type.  That is, we first check a hard-coded list (that cannot be
// overridden), and then if not found there, we defer to the system registry.
// Finally, we scan a secondary hard-coded list to catch types that we can
// deduce but that we also want to allow the OS to override.

하드 코딩 된 목록은 https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 ( kPrimaryMappingskSecondaryMappings) 파일에서 조금 더 앞서 있습니다.

예 : Microsoft Excel이 설치된 Windows 시스템에서 CSV 파일을 업로드 할 때 Chrome은이를 application/vnd.ms-excel. 이는 .csv첫 번째 하드 코딩 된 목록에 지정되지 않았기 때문에 브라우저가 시스템 레지스트리로 돌아갑니다. 로 설정된 HKEY_CLASSES_ROOT\.csvContent Typeapplication/vnd.ms-excel있습니다.

인터넷 익스플로러

다시 동일한 예제를 사용하면 브라우저가 application/vnd.ms-excel. Internet Explorer (작성 당시 버전 11) 가 레지스트리를 사용 한다고 가정하는 것이 합리적이라고 생각합니다 . 아마도 Chrome 및 Firefox와 같은 하드 코딩 된 목록을 사용하지만, 폐쇄 된 소스 특성으로 인해 확인하기가 어렵습니다.

Firefox

Chrome 코드에서 알 수 있듯이 Firefox (작성 당시 버전 32) 는 비슷한 방식으로 작동합니다. 파일의 스 니펫 uriloader\exthandler\nsExternalHelperAppService.cpp, 메소드nsExternalHelperAppService::GetTypeFromExtension

// OK. We want to try the following sources of mimetype information, in this order:
// 1. defaultMimeEntries array
// 2. User-set preferences (managed by the handler service)
// 3. OS-provided information
// 4. our "extras" array
// 5. Information from plugins
// 6. The "ext-to-type-mapping" category

하드 코딩 된 목록은 파일의 앞부분 인 441 줄 근처에 있습니다. defaultMimeEntriesextraMimeEntries.

내 현재 프로필을 사용하면 (위 목록의 항목 2)에 항목 text/csv이 있으므로 브라우저 가보고합니다 mimeTypes.rdf. 이 항목이없는 새 프로필을 사용하면 브라우저가보고합니다 application/vnd.ms-excel(목록의 항목 3).

요약

브라우저의 하드 코딩 된 목록은 매우 제한적입니다. 종종 브라우저에서 보낸 MIME 유형은 OS에서보고하는 유형입니다. 이것이 바로 질문에서 언급했듯이 브라우저에서보고하는 MIME 유형이 신뢰할 수없는 이유입니다.


답변

Kip, RFC, MSDN 및 MDN을 읽는 데 시간을 보냈습니다. 여기 내가 이해할 수있는 것이 있습니다. 브라우저가 업로드 할 파일을 발견하면 수신 한 데이터의 첫 번째 버퍼를 확인한 다음 이에 대한 테스트를 실행합니다. 이러한 테스트는 파일이 알려진 MIME 유형인지 아닌지 확인하려고 시도하고 알려진 MIME 유형 인 경우 알려진 MIME 유형에 대해 추가로 테스트하고 그에 따라 조치를 취합니다. IE는 확장에서 파일 유형을 결정하는 것보다 먼저 이것을 시도한다고 생각합니다. 이 페이지에서는 IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx에 대해 설명합니다 . 파이어 폭스의 경우 파일 시스템 또는 디렉토리 항목에서 파일 정보를 읽은 다음 파일 유형을 결정한다는 것을 이해할 수있었습니다. 다음은 FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile에 대한 링크입니다.. 나는 이것에 대해 더 권위있는 정보를 여전히 갖고 싶습니다.


답변

이것은 아마도 OS 및 브라우저에 따라 다를 수 있지만 Windows에서 주어진 파일 확장자에 대한 MIME 유형은 HKCR 아래의 레지스트리에서 찾을 수 있습니다.

예를 들면 :

HKEY_CLASSES_ROOT.zip-ContentType

MIME에서 파일 확장자로 이동하려면 아래의 키를 볼 수 있습니다.

HKEY_CLASSES_ROOT \ Mime \ Database \ Content Type

특정 MIME 유형에 대한 기본 확장자를 가져옵니다.


답변

이것은 귀하의 질문에 대한 답은 아니지만 해결하려는 문제를 해결합니다. YMMV.

당신이 쓴 것처럼, 각 브라우저는 그것을 결정하는 방법이 있기 때문에 MIME 유형은 신뢰할 수 없습니다. 그러나 브라우저는 파일의 원래 이름 (확장자 포함)을 보냅니다. 따라서 문제를 처리하는 가장 좋은 방법은 MIME 유형 대신 파일의 확장자를 검사하는 것입니다.

여전히 mime 유형이 필요한 경우 자체 아파치의 mime.types를 사용하여 서버 측을 결정할 수 있습니다.


답변

저는 johndodo에 동의합니다. 브라우저에서 보낸 MIME 유형을 신뢰할 수 없게 만드는 변수가 너무 많습니다. 받은 하위 유형을 제외하고 ‘응용 프로그램’과 같은 유형에만 집중합니다. 앱이 PHP 기반 인 경우 explode () 함수를 사용하여 쉽게 수행 할 수 있습니다. 또한 파일 확장자를 확인하여 .zip 또는 원하는 다른 압축인지 확인하십시오!


답변

에 따르면 RFC1867 – HTML에서 양식 기반 파일 업로드 :

미디어 유형이 알려진 경우 (예 : 파일 확장자 또는 운영 체제 입력 정보에서 유추) 또는 응용 프로그램 / 옥텟 스트림으로 각 부분에 적절한 콘텐츠 유형으로 레이블을 지정해야합니다.

그래서 내 이해는 유형을 추론 할 수없는 경우 application/octet-stream일종의 blanket catch-all식별자 와 같습니다 .


답변