OP_STATUS ContentDetector::DetectContentType() { m_official_content_type = (URLContentType)m_url->GetAttribute(URL::KContentType, TRUE); UINT32 port = m_url->GetAttribute(URL::KResolvedPort); URLType url_type = static_cast<URLType>(m_url->GetAttribute(URL::KType)); if (((url_type == URL_HTTP && port != 80) || (url_type == URL_HTTPS && port != 443)) && !m_url->GetAttribute(URL::KHTTP_10_or_more)) { // Do not sniff content-type for HTTP 0.9 servers on ports other than 80 for HTTP or 443 for HTTPS (CORE-35973). if (m_official_content_type == URL_UNDETERMINED_CONTENT) RETURN_IF_ERROR(m_url->SetAttribute(URL::KContentType, URL_TEXT_CONTENT)); return OpStatus::OK; } RETURN_IF_ERROR(m_url->GetAttribute(URL::KOriginalMIME_Type, m_official_mime_type)); int mime_length = m_official_mime_type.Length(); URLContentType sniffed_content_type = m_official_content_type; OpStringC8 sniffed_mime_type; OpAutoPtr<URL_DataDescriptor> desc(m_url->GetDescriptor(NULL, URL::KFollowRedirect, TRUE)); if (!desc.get()) { m_octets = NULL; m_length = 0; } else { BOOL more; RETURN_IF_LEAVE(m_length = desc->RetrieveDataL(more)); m_octets = desc->GetBuffer(); } #ifdef NEED_URL_EXTERNAL_GET_MIME_FROM_SAMPLE if (CheckExternally()) return OpStatus::OK; #endif if (m_url->GetAttribute(URL::KMultimedia)) { RETURN_IF_ERROR(IsVideo(sniffed_content_type, sniffed_mime_type)); } else if (m_official_mime_type.CompareI("text/plain") == 0) { RETURN_IF_ERROR(IsTextOrBinary(sniffed_content_type, sniffed_mime_type)); } else if (m_official_mime_type.IsEmpty() || m_official_mime_type.CompareI("unknown/unknown") == 0 || m_official_mime_type.CompareI("application/unknown") == 0 || m_official_mime_type.CompareI("*/*") == 0) { RETURN_IF_ERROR(IsUnknownType(sniffed_content_type, sniffed_mime_type)); } else if (m_official_mime_type.FindI("+xml") == mime_length - 4 || m_official_mime_type.CompareI("text/xml") == 0 || m_official_mime_type.CompareI("application/xml") == 0) { return OpStatus::OK; } else if (m_official_mime_type.CompareI("image/", 6) == 0) { RETURN_IF_ERROR(IsImage(sniffed_content_type, sniffed_mime_type)); } if (m_dont_leave_undetermined && sniffed_content_type == URL_UNDETERMINED_CONTENT) { sniffed_content_type = URL_UNKNOWN_CONTENT; m_url->SetAttribute(URL::KUntrustedContent, TRUE); sniffed_mime_type = "application/octet-stream"; } if (sniffed_content_type != m_official_content_type) { /* CORE-39801: If we sniffed a container format (such as ZIP or GZIP), * check if the URL string suggests a file extension of a known format * using that format as its container. If so, allow it through if we * originally did not get a valid Content-Type. */ OpString fileext; TRAPD(err, m_url->GetAttributeL(URL::KUniNameFileExt_L, fileext, URL::KFollowRedirect)); if (OpStatus::IsSuccess(err) && !fileext.IsEmpty()) { Viewer *viewer = NULL; OP_STATUS rc = g_viewers->FindViewerByExtension(fileext, viewer); if (OpStatus::IsSuccess(rc) && viewer && viewer->AllowedContainer() && 0 == op_strcmp(viewer->AllowedContainer(), sniffed_mime_type.CStr())) { sniffed_content_type = viewer->GetContentType(); sniffed_mime_type = viewer->GetContentTypeString8(); } else if (OpStatus::IsMemoryError(rc)) { /* Propagate out-of-memory errors only; any other error just * means we didn't find a Viewer object. */ return rc; } } RETURN_IF_ERROR(m_url->SetAttribute(URL::KContentType, sniffed_content_type)); RETURN_IF_ERROR(m_url->SetAttribute(URL::KUntrustedContent, TRUE)); RETURN_IF_ERROR(m_url->SetAttribute(URL::KMIME_Type, sniffed_mime_type)); } return OpStatus::OK; }