1/* 2 * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28#include "MIMETypeRegistry.h" 29 30#include "MediaPlayer.h" 31#include <wtf/HashMap.h> 32#include <wtf/HashSet.h> 33#include <wtf/MainThread.h> 34#include <wtf/StdLibExtras.h> 35#include <wtf/text/StringHash.h> 36 37#if USE(CG) 38#include "ImageSourceCG.h" 39#if !PLATFORM(IOS) 40#include <ApplicationServices/ApplicationServices.h> 41#else 42#include <ImageIO/CGImageDestination.h> 43#endif 44#include <wtf/RetainPtr.h> 45#endif 46 47#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML) 48#include "ArchiveFactory.h" 49#endif 50 51namespace WebCore { 52 53namespace { 54struct TypeExtensionPair { 55 const char* type; 56 const char* extension; 57}; 58} 59 60// A table of common media MIME types and file extenstions used when a platform's 61// specific MIME type lookup doesn't have a match for a media file extension. 62static const TypeExtensionPair commonMediaTypes[] = { 63 64 // Ogg 65 { "application/ogg", "ogx" }, 66 { "audio/ogg", "ogg" }, 67 { "audio/ogg", "oga" }, 68 { "video/ogg", "ogv" }, 69 70 // Annodex 71 { "application/annodex", "anx" }, 72 { "audio/annodex", "axa" }, 73 { "video/annodex", "axv" }, 74 { "audio/speex", "spx" }, 75 76 // WebM 77 { "video/webm", "webm" }, 78 { "audio/webm", "webm" }, 79 80 // MPEG 81 { "audio/mpeg", "m1a" }, 82 { "audio/mpeg", "m2a" }, 83 { "audio/mpeg", "m1s" }, 84 { "audio/mpeg", "mpa" }, 85 { "video/mpeg", "mpg" }, 86 { "video/mpeg", "m15" }, 87 { "video/mpeg", "m1s" }, 88 { "video/mpeg", "m1v" }, 89 { "video/mpeg", "m75" }, 90 { "video/mpeg", "mpa" }, 91 { "video/mpeg", "mpeg" }, 92 { "video/mpeg", "mpm" }, 93 { "video/mpeg", "mpv" }, 94 95 // MPEG playlist 96 { "application/vnd.apple.mpegurl", "m3u8" }, 97 { "application/mpegurl", "m3u8" }, 98 { "application/x-mpegurl", "m3u8" }, 99 { "audio/mpegurl", "m3url" }, 100 { "audio/x-mpegurl", "m3url" }, 101 { "audio/mpegurl", "m3u" }, 102 { "audio/x-mpegurl", "m3u" }, 103 104 // MPEG-4 105 { "video/x-m4v", "m4v" }, 106 { "audio/x-m4a", "m4a" }, 107 { "audio/x-m4b", "m4b" }, 108 { "audio/x-m4p", "m4p" }, 109 { "audio/mp4", "m4a" }, 110 111 // MP3 112 { "audio/mp3", "mp3" }, 113 { "audio/x-mp3", "mp3" }, 114 { "audio/x-mpeg", "mp3" }, 115 116 // MPEG-2 117 { "video/x-mpeg2", "mp2" }, 118 { "video/mpeg2", "vob" }, 119 { "video/mpeg2", "mod" }, 120 { "video/m2ts", "m2ts" }, 121 { "video/x-m2ts", "m2t" }, 122 { "video/x-m2ts", "ts" }, 123 124 // 3GP/3GP2 125 { "audio/3gpp", "3gpp" }, 126 { "audio/3gpp2", "3g2" }, 127 { "application/x-mpeg", "amc" }, 128 129 // AAC 130 { "audio/aac", "aac" }, 131 { "audio/aac", "adts" }, 132 { "audio/x-aac", "m4r" }, 133 134 // CoreAudio File 135 { "audio/x-caf", "caf" }, 136 { "audio/x-gsm", "gsm" }, 137 138 // ADPCM 139 { "audio/x-wav", "wav" } 140}; 141 142static HashSet<String>* supportedImageResourceMIMETypes; 143static HashSet<String>* supportedImageMIMETypes; 144static HashSet<String>* supportedImageMIMETypesForEncoding; 145static HashSet<String>* supportedJavaScriptMIMETypes; 146static HashSet<String>* supportedNonImageMIMETypes; 147static HashSet<String>* supportedMediaMIMETypes; 148static HashSet<String>* pdfMIMETypes; 149static HashSet<String>* pdfAndPostScriptMIMETypes; 150static HashSet<String>* unsupportedTextMIMETypes; 151 152typedef HashMap<String, Vector<String>*, CaseFoldingHash> MediaMIMETypeMap; 153 154static void initializeSupportedImageMIMETypes() 155{ 156#if USE(CG) 157 RetainPtr<CFArrayRef> supportedTypes = adoptCF(CGImageSourceCopyTypeIdentifiers()); 158 CFIndex count = CFArrayGetCount(supportedTypes.get()); 159 for (CFIndex i = 0; i < count; i++) { 160 CFStringRef supportedType = reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(supportedTypes.get(), i)); 161 String mimeType = MIMETypeForImageSourceType(supportedType); 162 if (!mimeType.isEmpty()) { 163 supportedImageMIMETypes->add(mimeType); 164 supportedImageResourceMIMETypes->add(mimeType); 165 } 166 } 167 168 // On Tiger and Leopard, com.microsoft.bmp doesn't have a MIME type in the registry. 169 supportedImageMIMETypes->add("image/bmp"); 170 supportedImageResourceMIMETypes->add("image/bmp"); 171 172 // Favicons don't have a MIME type in the registry either. 173 supportedImageMIMETypes->add("image/vnd.microsoft.icon"); 174 supportedImageMIMETypes->add("image/x-icon"); 175 supportedImageResourceMIMETypes->add("image/vnd.microsoft.icon"); 176 supportedImageResourceMIMETypes->add("image/x-icon"); 177 178 // We only get one MIME type per UTI, hence our need to add these manually 179 supportedImageMIMETypes->add("image/pjpeg"); 180 supportedImageResourceMIMETypes->add("image/pjpeg"); 181 182 // We don't want to try to treat all binary data as an image 183 supportedImageMIMETypes->remove("application/octet-stream"); 184 supportedImageResourceMIMETypes->remove("application/octet-stream"); 185 186 // Don't treat pdf/postscript as images directly 187 supportedImageMIMETypes->remove("application/pdf"); 188 supportedImageMIMETypes->remove("application/postscript"); 189 190#if PLATFORM(IOS) 191 // Add malformed image mimetype for compatibility with Mail and to handle malformed mimetypes from the net 192 // These were removed for <rdar://problem/6564538> Re-enable UTI code in WebCore now that MobileCoreServices exists 193 // But Mail relies on at least image/tif reported as being supported (should be image/tiff). 194 // This can be removed when Mail addresses: 195 // <rdar://problem/7879510> Mail should use standard image mimetypes 196 // and we fix sniffing so that it corrects items such as image/jpg -> image/jpeg. 197 static const char* malformedMIMETypes[] = { 198 // JPEG (image/jpeg) 199 "image/jpg", "image/jp_", "image/jpe_", "application/jpg", "application/x-jpg", "image/pipeg", 200 "image/vnd.switfview-jpeg", "image/x-xbitmap", 201 // GIF (image/gif) 202 "image/gi_", 203 // PNG (image/png) 204 "application/png", "application/x-png", 205 // TIFF (image/tiff) 206 "image/x-tif", "image/tif", "image/x-tiff", "application/tif", "application/x-tif", "application/tiff", 207 "application/x-tiff", 208 // BMP (image/bmp, image/x-bitmap) 209 "image/x-bmp", "image/x-win-bitmap", "image/x-windows-bmp", "image/ms-bmp", "image/x-ms-bmp", 210 "application/bmp", "application/x-bmp", "application/x-win-bitmap", 211 }; 212 for (size_t i = 0; i < WTF_ARRAY_LENGTH(malformedMIMETypes); ++i) { 213 supportedImageMIMETypes->add(malformedMIMETypes[i]); 214 supportedImageResourceMIMETypes->add(malformedMIMETypes[i]); 215 } 216#endif 217 218#else 219 // assume that all implementations at least support the following standard 220 // image types: 221 static const char* types[] = { 222 "image/jpeg", 223 "image/png", 224 "image/gif", 225 "image/bmp", 226 "image/vnd.microsoft.icon", // ico 227 "image/x-icon", // ico 228 "image/x-xbitmap" // xbm 229 }; 230 for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i) { 231 supportedImageMIMETypes->add(types[i]); 232 supportedImageResourceMIMETypes->add(types[i]); 233 } 234 235#if USE(WEBP) 236 supportedImageMIMETypes->add("image/webp"); 237 supportedImageResourceMIMETypes->add("image/webp"); 238#endif 239 240#endif // USE(CG) 241} 242 243static void initializeSupportedImageMIMETypesForEncoding() 244{ 245 supportedImageMIMETypesForEncoding = new HashSet<String>; 246 247#if USE(CG) 248#if PLATFORM(COCOA) 249 RetainPtr<CFArrayRef> supportedTypes = adoptCF(CGImageDestinationCopyTypeIdentifiers()); 250 CFIndex count = CFArrayGetCount(supportedTypes.get()); 251 for (CFIndex i = 0; i < count; i++) { 252 CFStringRef supportedType = reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(supportedTypes.get(), i)); 253 String mimeType = MIMETypeForImageSourceType(supportedType); 254 if (!mimeType.isEmpty()) 255 supportedImageMIMETypesForEncoding->add(mimeType); 256 } 257#else 258 // FIXME: Add Windows support for all the supported UTI's when a way to convert from MIMEType to UTI reliably is found. 259 // For now, only support PNG, JPEG and GIF. See <rdar://problem/6095286>. 260 supportedImageMIMETypesForEncoding->add("image/png"); 261 supportedImageMIMETypesForEncoding->add("image/jpeg"); 262 supportedImageMIMETypesForEncoding->add("image/gif"); 263#endif 264#elif PLATFORM(GTK) 265 supportedImageMIMETypesForEncoding->add("image/png"); 266 supportedImageMIMETypesForEncoding->add("image/jpeg"); 267 supportedImageMIMETypesForEncoding->add("image/tiff"); 268 supportedImageMIMETypesForEncoding->add("image/bmp"); 269 supportedImageMIMETypesForEncoding->add("image/ico"); 270#elif USE(CAIRO) 271 supportedImageMIMETypesForEncoding->add("image/png"); 272#endif 273} 274 275static void initializeSupportedJavaScriptMIMETypes() 276{ 277 /* 278 Mozilla 1.8 and WinIE 7 both accept text/javascript and text/ecmascript. 279 Mozilla 1.8 accepts application/javascript, application/ecmascript, and application/x-javascript, but WinIE 7 doesn't. 280 WinIE 7 accepts text/javascript1.1 - text/javascript1.3, text/jscript, and text/livescript, but Mozilla 1.8 doesn't. 281 Mozilla 1.8 allows leading and trailing whitespace, but WinIE 7 doesn't. 282 Mozilla 1.8 and WinIE 7 both accept the empty string, but neither accept a whitespace-only string. 283 We want to accept all the values that either of these browsers accept, but not other values. 284 */ 285 static const char* types[] = { 286 "text/javascript", 287 "text/ecmascript", 288 "application/javascript", 289 "application/ecmascript", 290 "application/x-javascript", 291 "text/javascript1.1", 292 "text/javascript1.2", 293 "text/javascript1.3", 294 "text/jscript", 295 "text/livescript", 296 }; 297 for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i) 298 supportedJavaScriptMIMETypes->add(types[i]); 299} 300 301static void initializePDFMIMETypes() 302{ 303 const char* const types[] = { 304 "application/pdf", 305 "text/pdf" 306 }; 307 for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i) 308 pdfMIMETypes->add(types[i]); 309} 310 311static void initializePostScriptMIMETypes() 312{ 313 pdfAndPostScriptMIMETypes->add("application/postscript"); 314} 315 316static void initializeSupportedNonImageMimeTypes() 317{ 318 static const char* types[] = { 319 "text/html", 320 "text/xml", 321 "text/xsl", 322 "text/plain", 323 "text/", 324 "application/xml", 325 "application/xhtml+xml", 326#if !PLATFORM(IOS) 327 "application/vnd.wap.xhtml+xml", 328 "application/rss+xml", 329 "application/atom+xml", 330#endif 331 "application/json", 332 "image/svg+xml", 333#if ENABLE(FTPDIR) 334 "application/x-ftp-directory", 335#endif 336 "multipart/x-mixed-replace" 337 // Note: ADDING a new type here will probably render it as HTML. This can 338 // result in cross-site scripting. 339 }; 340 COMPILE_ASSERT(sizeof(types) / sizeof(types[0]) <= 16, 341 nonimage_mime_types_must_be_less_than_or_equal_to_16); 342 343 for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i) 344 supportedNonImageMIMETypes->add(types[i]); 345 346#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML) 347 ArchiveFactory::registerKnownArchiveMIMETypes(); 348#endif 349} 350 351static MediaMIMETypeMap& mediaMIMETypeMap() 352{ 353 DEPRECATED_DEFINE_STATIC_LOCAL(MediaMIMETypeMap, mediaMIMETypeForExtensionMap, ()); 354 355 if (!mediaMIMETypeForExtensionMap.isEmpty()) 356 return mediaMIMETypeForExtensionMap; 357 358 const unsigned numPairs = sizeof(commonMediaTypes) / sizeof(commonMediaTypes[0]); 359 for (unsigned ndx = 0; ndx < numPairs; ++ndx) { 360 361 if (mediaMIMETypeForExtensionMap.contains(commonMediaTypes[ndx].extension)) 362 mediaMIMETypeForExtensionMap.get(commonMediaTypes[ndx].extension)->append(commonMediaTypes[ndx].type); 363 else { 364 Vector<String>* synonyms = new Vector<String>; 365 366 // If there is a system specific type for this extension, add it as the first type so 367 // getMediaMIMETypeForExtension will always return it. 368 String systemType = MIMETypeRegistry::getMIMETypeForExtension(commonMediaTypes[ndx].extension); 369 if (!systemType.isEmpty() && commonMediaTypes[ndx].type != systemType) 370 synonyms->append(systemType); 371 synonyms->append(commonMediaTypes[ndx].type); 372 mediaMIMETypeForExtensionMap.add(commonMediaTypes[ndx].extension, synonyms); 373 } 374 } 375 376 return mediaMIMETypeForExtensionMap; 377} 378 379String MIMETypeRegistry::getMediaMIMETypeForExtension(const String& ext) 380{ 381 // Look in the system-specific registry first. 382 String type = getMIMETypeForExtension(ext); 383 if (!type.isEmpty()) 384 return type; 385 386 Vector<String>* typeList = mediaMIMETypeMap().get(ext); 387 if (typeList) 388 return (*typeList)[0]; 389 390 return String(); 391} 392 393Vector<String> MIMETypeRegistry::getMediaMIMETypesForExtension(const String& ext) 394{ 395 Vector<String>* typeList = mediaMIMETypeMap().get(ext); 396 if (typeList) 397 return *typeList; 398 399 // Only need to look in the system-specific registry if mediaMIMETypeMap() doesn't contain 400 // the extension at all, because it always contains the system-specific type if the 401 // extension is in the static mapping table. 402 String type = getMIMETypeForExtension(ext); 403 if (!type.isEmpty()) { 404 Vector<String> typeList; 405 typeList.append(type); 406 return typeList; 407 } 408 409 return Vector<String>(); 410} 411 412static void initializeSupportedMediaMIMETypes() 413{ 414 supportedMediaMIMETypes = new HashSet<String>; 415#if ENABLE(VIDEO) 416 MediaPlayer::getSupportedTypes(*supportedMediaMIMETypes); 417#endif 418} 419 420static void initializeUnsupportedTextMIMETypes() 421{ 422 static const char* types[] = { 423 "text/calendar", 424 "text/x-calendar", 425 "text/x-vcalendar", 426 "text/vcalendar", 427 "text/vcard", 428 "text/x-vcard", 429 "text/directory", 430 "text/ldif", 431 "text/qif", 432 "text/x-qif", 433 "text/x-csv", 434 "text/x-vcf", 435#if !PLATFORM(IOS) 436 "text/rtf", 437#else 438 "text/vnd.sun.j2me.app-descriptor", 439#endif 440 }; 441 for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i) 442 unsupportedTextMIMETypes->add(types[i]); 443} 444 445static void initializeMIMETypeRegistry() 446{ 447 supportedJavaScriptMIMETypes = new HashSet<String>; 448 initializeSupportedJavaScriptMIMETypes(); 449 450 supportedNonImageMIMETypes = new HashSet<String>(*supportedJavaScriptMIMETypes); 451 initializeSupportedNonImageMimeTypes(); 452 453 supportedImageResourceMIMETypes = new HashSet<String>; 454 supportedImageMIMETypes = new HashSet<String>; 455 initializeSupportedImageMIMETypes(); 456 457 pdfMIMETypes = new HashSet<String>; 458 initializePDFMIMETypes(); 459 460 pdfAndPostScriptMIMETypes = new HashSet<String>(*pdfMIMETypes); 461 initializePostScriptMIMETypes(); 462 463 unsupportedTextMIMETypes = new HashSet<String>; 464 initializeUnsupportedTextMIMETypes(); 465} 466 467String MIMETypeRegistry::getMIMETypeForPath(const String& path) 468{ 469 size_t pos = path.reverseFind('.'); 470 if (pos != notFound) { 471 String extension = path.substring(pos + 1); 472 String result = getMIMETypeForExtension(extension); 473 if (result.length()) 474 return result; 475 } 476 return defaultMIMEType(); 477} 478 479bool MIMETypeRegistry::isSupportedImageMIMEType(const String& mimeType) 480{ 481 if (mimeType.isEmpty()) 482 return false; 483 if (!supportedImageMIMETypes) 484 initializeMIMETypeRegistry(); 485 return supportedImageMIMETypes->contains(getNormalizedMIMEType(mimeType)); 486} 487 488bool MIMETypeRegistry::isSupportedImageResourceMIMEType(const String& mimeType) 489{ 490 if (mimeType.isEmpty()) 491 return false; 492 if (!supportedImageResourceMIMETypes) 493 initializeMIMETypeRegistry(); 494 return supportedImageResourceMIMETypes->contains(getNormalizedMIMEType(mimeType)); 495} 496 497bool MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(const String& mimeType) 498{ 499 ASSERT(isMainThread()); 500 501 if (mimeType.isEmpty()) 502 return false; 503 if (!supportedImageMIMETypesForEncoding) 504 initializeSupportedImageMIMETypesForEncoding(); 505 return supportedImageMIMETypesForEncoding->contains(mimeType); 506} 507 508bool MIMETypeRegistry::isSupportedJavaScriptMIMEType(const String& mimeType) 509{ 510 if (mimeType.isEmpty()) 511 return false; 512 if (!supportedJavaScriptMIMETypes) 513 initializeMIMETypeRegistry(); 514 return supportedJavaScriptMIMETypes->contains(mimeType); 515} 516 517bool MIMETypeRegistry::isSupportedNonImageMIMEType(const String& mimeType) 518{ 519 if (mimeType.isEmpty()) 520 return false; 521 if (!supportedNonImageMIMETypes) 522 initializeMIMETypeRegistry(); 523 return supportedNonImageMIMETypes->contains(mimeType); 524} 525 526bool MIMETypeRegistry::isSupportedMediaMIMEType(const String& mimeType) 527{ 528 if (mimeType.isEmpty()) 529 return false; 530 if (!supportedMediaMIMETypes) 531 initializeSupportedMediaMIMETypes(); 532 return supportedMediaMIMETypes->contains(mimeType); 533} 534 535bool MIMETypeRegistry::isUnsupportedTextMIMEType(const String& mimeType) 536{ 537 if (mimeType.isEmpty()) 538 return false; 539 if (!unsupportedTextMIMETypes) 540 initializeMIMETypeRegistry(); 541 return unsupportedTextMIMETypes->contains(mimeType); 542} 543 544bool MIMETypeRegistry::isJavaAppletMIMEType(const String& mimeType) 545{ 546 // Since this set is very limited and is likely to remain so we won't bother with the overhead 547 // of using a hash set. 548 // Any of the MIME types below may be followed by any number of specific versions of the JVM, 549 // which is why we use startsWith() 550 return mimeType.startsWith("application/x-java-applet", false) 551 || mimeType.startsWith("application/x-java-bean", false) 552 || mimeType.startsWith("application/x-java-vm", false); 553} 554 555bool MIMETypeRegistry::isPDFOrPostScriptMIMEType(const String& mimeType) 556{ 557 if (mimeType.isEmpty()) 558 return false; 559 if (!pdfAndPostScriptMIMETypes) 560 initializeMIMETypeRegistry(); 561 return pdfAndPostScriptMIMETypes->contains(mimeType); 562} 563 564bool MIMETypeRegistry::isPDFMIMEType(const String& mimeType) 565{ 566 if (mimeType.isEmpty()) 567 return false; 568 if (!pdfMIMETypes) 569 initializeMIMETypeRegistry(); 570 return pdfMIMETypes->contains(mimeType); 571} 572 573bool MIMETypeRegistry::canShowMIMEType(const String& mimeType) 574{ 575 if (isSupportedImageMIMEType(mimeType) || isSupportedNonImageMIMEType(mimeType) || isSupportedMediaMIMEType(mimeType)) 576 return true; 577 578 if (mimeType.startsWith("text/", false)) 579 return !MIMETypeRegistry::isUnsupportedTextMIMEType(mimeType); 580 581 return false; 582} 583 584HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypes() 585{ 586 if (!supportedImageMIMETypes) 587 initializeMIMETypeRegistry(); 588 return *supportedImageMIMETypes; 589} 590 591HashSet<String>& MIMETypeRegistry::getSupportedImageResourceMIMETypes() 592{ 593 if (!supportedImageResourceMIMETypes) 594 initializeMIMETypeRegistry(); 595 return *supportedImageResourceMIMETypes; 596} 597 598HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypesForEncoding() 599{ 600 if (!supportedImageMIMETypesForEncoding) 601 initializeSupportedImageMIMETypesForEncoding(); 602 return *supportedImageMIMETypesForEncoding; 603} 604 605HashSet<String>& MIMETypeRegistry::getSupportedNonImageMIMETypes() 606{ 607 if (!supportedNonImageMIMETypes) 608 initializeMIMETypeRegistry(); 609 return *supportedNonImageMIMETypes; 610} 611 612HashSet<String>& MIMETypeRegistry::getSupportedMediaMIMETypes() 613{ 614 if (!supportedMediaMIMETypes) 615 initializeSupportedMediaMIMETypes(); 616 return *supportedMediaMIMETypes; 617} 618 619 620HashSet<String>& MIMETypeRegistry::getPDFMIMETypes() 621{ 622 if (!pdfMIMETypes) 623 initializeMIMETypeRegistry(); 624 return *pdfMIMETypes; 625} 626 627HashSet<String>& MIMETypeRegistry::getPDFAndPostScriptMIMETypes() 628{ 629 if (!pdfAndPostScriptMIMETypes) 630 initializeMIMETypeRegistry(); 631 return *pdfAndPostScriptMIMETypes; 632} 633 634HashSet<String>& MIMETypeRegistry::getUnsupportedTextMIMETypes() 635{ 636 if (!unsupportedTextMIMETypes) 637 initializeMIMETypeRegistry(); 638 return *unsupportedTextMIMETypes; 639} 640 641const String& defaultMIMEType() 642{ 643 DEPRECATED_DEFINE_STATIC_LOCAL(const String, defaultMIMEType, (ASCIILiteral("application/octet-stream"))); 644 return defaultMIMEType; 645} 646 647#if !USE(CURL) 648String MIMETypeRegistry::getNormalizedMIMEType(const String& mimeType) 649{ 650 return mimeType; 651} 652#endif 653 654#if USE(CURL) 655typedef HashMap<String, String> MIMETypeAssociationMap; 656 657static const MIMETypeAssociationMap& mimeTypeAssociationMap() 658{ 659 static MIMETypeAssociationMap* mimeTypeMap = 0; 660 if (mimeTypeMap) 661 return *mimeTypeMap; 662 663 mimeTypeMap = new MIMETypeAssociationMap; 664 665 mimeTypeMap->add(ASCIILiteral("image/x-ms-bmp"), ASCIILiteral("image/bmp")); 666 mimeTypeMap->add(ASCIILiteral("image/x-windows-bmp"), ASCIILiteral("image/bmp")); 667 mimeTypeMap->add(ASCIILiteral("image/x-bmp"), ASCIILiteral("image/bmp")); 668 mimeTypeMap->add(ASCIILiteral("image/x-bitmap"), ASCIILiteral("image/bmp")); 669 mimeTypeMap->add(ASCIILiteral("image/x-ms-bitmap"), ASCIILiteral("image/bmp")); 670 mimeTypeMap->add(ASCIILiteral("image/jpg"), ASCIILiteral("image/jpeg")); 671 mimeTypeMap->add(ASCIILiteral("image/pjpeg"), ASCIILiteral("image/jpeg")); 672 mimeTypeMap->add(ASCIILiteral("image/x-png"), ASCIILiteral("image/png")); 673 mimeTypeMap->add(ASCIILiteral("image/vnd.rim.png"), ASCIILiteral("image/png")); 674 mimeTypeMap->add(ASCIILiteral("image/ico"), ASCIILiteral("image/vnd.microsoft.icon")); 675 mimeTypeMap->add(ASCIILiteral("image/icon"), ASCIILiteral("image/vnd.microsoft.icon")); 676 mimeTypeMap->add(ASCIILiteral("text/ico"), ASCIILiteral("image/vnd.microsoft.icon")); 677 mimeTypeMap->add(ASCIILiteral("application/ico"), ASCIILiteral("image/vnd.microsoft.icon")); 678 mimeTypeMap->add(ASCIILiteral("image/x-icon"), ASCIILiteral("image/vnd.microsoft.icon")); 679 mimeTypeMap->add(ASCIILiteral("audio/vnd.qcelp"), ASCIILiteral("audio/qcelp")); 680 mimeTypeMap->add(ASCIILiteral("audio/qcp"), ASCIILiteral("audio/qcelp")); 681 mimeTypeMap->add(ASCIILiteral("audio/vnd.qcp"), ASCIILiteral("audio/qcelp")); 682 mimeTypeMap->add(ASCIILiteral("audio/wav"), ASCIILiteral("audio/x-wav")); 683 mimeTypeMap->add(ASCIILiteral("audio/mid"), ASCIILiteral("audio/midi")); 684 mimeTypeMap->add(ASCIILiteral("audio/sp-midi"), ASCIILiteral("audio/midi")); 685 mimeTypeMap->add(ASCIILiteral("audio/x-mid"), ASCIILiteral("audio/midi")); 686 mimeTypeMap->add(ASCIILiteral("audio/x-midi"), ASCIILiteral("audio/midi")); 687 mimeTypeMap->add(ASCIILiteral("audio/x-mpeg"), ASCIILiteral("audio/mpeg")); 688 mimeTypeMap->add(ASCIILiteral("audio/mp3"), ASCIILiteral("audio/mpeg")); 689 mimeTypeMap->add(ASCIILiteral("audio/x-mp3"), ASCIILiteral("audio/mpeg")); 690 mimeTypeMap->add(ASCIILiteral("audio/mpeg3"), ASCIILiteral("audio/mpeg")); 691 mimeTypeMap->add(ASCIILiteral("audio/x-mpeg3"), ASCIILiteral("audio/mpeg")); 692 mimeTypeMap->add(ASCIILiteral("audio/mpg3"), ASCIILiteral("audio/mpeg")); 693 mimeTypeMap->add(ASCIILiteral("audio/mpg"), ASCIILiteral("audio/mpeg")); 694 mimeTypeMap->add(ASCIILiteral("audio/x-mpg"), ASCIILiteral("audio/mpeg")); 695 mimeTypeMap->add(ASCIILiteral("audio/m4a"), ASCIILiteral("audio/mp4")); 696 mimeTypeMap->add(ASCIILiteral("audio/x-m4a"), ASCIILiteral("audio/mp4")); 697 mimeTypeMap->add(ASCIILiteral("audio/x-mp4"), ASCIILiteral("audio/mp4")); 698 mimeTypeMap->add(ASCIILiteral("audio/x-aac"), ASCIILiteral("audio/aac")); 699 mimeTypeMap->add(ASCIILiteral("audio/x-amr"), ASCIILiteral("audio/amr")); 700 mimeTypeMap->add(ASCIILiteral("audio/mpegurl"), ASCIILiteral("audio/x-mpegurl")); 701 mimeTypeMap->add(ASCIILiteral("audio/flac"), ASCIILiteral("audio/x-flac")); 702 mimeTypeMap->add(ASCIILiteral("video/3gp"), ASCIILiteral("video/3gpp")); 703 mimeTypeMap->add(ASCIILiteral("video/avi"), ASCIILiteral("video/x-msvideo")); 704 mimeTypeMap->add(ASCIILiteral("video/x-m4v"), ASCIILiteral("video/mp4")); 705 mimeTypeMap->add(ASCIILiteral("video/x-quicktime"), ASCIILiteral("video/quicktime")); 706 mimeTypeMap->add(ASCIILiteral("application/java"), ASCIILiteral("application/java-archive")); 707 mimeTypeMap->add(ASCIILiteral("application/x-java-archive"), ASCIILiteral("application/java-archive")); 708 mimeTypeMap->add(ASCIILiteral("application/x-zip-compressed"), ASCIILiteral("application/zip")); 709 mimeTypeMap->add(ASCIILiteral("text/cache-manifest"), ASCIILiteral("text/plain")); 710 711 return *mimeTypeMap; 712} 713 714String MIMETypeRegistry::getNormalizedMIMEType(const String& mimeType) 715{ 716 MIMETypeAssociationMap::const_iterator it = mimeTypeAssociationMap().find(mimeType); 717 718 if (it != mimeTypeAssociationMap().end()) 719 return it->value; 720 721 return mimeType; 722} 723#endif 724 725} // namespace WebCore 726