1/*
2 * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
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 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#import "config.h"
30#import "WebCoreURLResponse.h"
31
32#import "MIMETypeRegistry.h"
33#import "UTIUtilities.h"
34#import "WebCoreSystemInterface.h"
35#import <wtf/Assertions.h>
36#import <wtf/RetainPtr.h>
37
38namespace WebCore {
39
40// <rdar://problem/7007389> CoreTypes UTI map is missing 100+ file extensions that GateKeeper knew about
41// When we disabled content sniffing for file URLs we caused problems with these 100+ extensions that CoreTypes
42// doesn't know about.
43// If CoreTypes is ever brought up to speed we can remove this table and associated code.
44static CFDictionaryRef createExtensionToMIMETypeMap()
45{
46    CFStringRef keys[] = {
47        CFSTR("ai"),
48        CFSTR("asc"),
49        CFSTR("bcpio"),
50        CFSTR("bmp"),
51        CFSTR("cdf"),
52        CFSTR("class"),
53        CFSTR("cpgz"),
54        CFSTR("cpio"),
55        CFSTR("cpt"),
56        CFSTR("csh"),
57        CFSTR("css"),
58        CFSTR("dcr"),
59        CFSTR("dir"),
60        CFSTR("dmg"),
61        CFSTR("dms"),
62        CFSTR("dvi"),
63        CFSTR("dxr"),
64        CFSTR("eps"),
65        CFSTR("etx"),
66        CFSTR("ez"),
67        CFSTR("fdf"),
68        CFSTR("fla"),
69        CFSTR("fp"),
70        CFSTR("fp2"),
71        CFSTR("fp3"),
72        CFSTR("fp4"),
73        CFSTR("fp5"),
74        CFSTR("fp6"),
75        CFSTR("hdf"),
76        CFSTR("ice"),
77        CFSTR("ico"),
78        CFSTR("ics"),
79        CFSTR("ief"),
80        CFSTR("iges"),
81        CFSTR("igs"),
82        CFSTR("iso"),
83        CFSTR("jhtml"),
84        CFSTR("latex"),
85        CFSTR("lha"),
86        CFSTR("lzh"),
87        CFSTR("m3u"),
88        CFSTR("m4p"),
89        CFSTR("mac"),
90        CFSTR("man"),
91        CFSTR("me"),
92        CFSTR("mesh"),
93        CFSTR("mif"),
94        CFSTR("movie"),
95        CFSTR("mp2"),
96        CFSTR("mpga"),
97        CFSTR("ms"),
98        CFSTR("msh"),
99        CFSTR("mxu"),
100        CFSTR("nc"),
101        CFSTR("oda"),
102        CFSTR("pbm"),
103        CFSTR("pcx"),
104        CFSTR("pdb"),
105        CFSTR("pgm"),
106        CFSTR("pgn"),
107        CFSTR("pls"),
108        CFSTR("pnm"),
109        CFSTR("pnt"),
110        CFSTR("pntg"),
111        CFSTR("ppm"),
112        CFSTR("ras"),
113        CFSTR("rgb"),
114        CFSTR("roff"),
115        CFSTR("rpm"),
116        CFSTR("rtx"),
117        CFSTR("sgm"),
118        CFSTR("sgml"),
119        CFSTR("sh"),
120        CFSTR("shar"),
121        CFSTR("silo"),
122        CFSTR("skd"),
123        CFSTR("skm"),
124        CFSTR("skp"),
125        CFSTR("skt"),
126        CFSTR("smi"),
127        CFSTR("so"),
128        CFSTR("spl"),
129        CFSTR("src"),
130        CFSTR("sv4cpio"),
131        CFSTR("sv4crc"),
132        CFSTR("swf"),
133        CFSTR("t"),
134        CFSTR("targa"),
135        CFSTR("tcl"),
136        CFSTR("tex"),
137        CFSTR("texi"),
138        CFSTR("texinfo"),
139        CFSTR("tgz"),
140        CFSTR("torrent"),
141        CFSTR("tr"),
142        CFSTR("tsv"),
143        CFSTR("ustar"),
144        CFSTR("vcd"),
145        CFSTR("vrml"),
146        CFSTR("wbmp"),
147        CFSTR("wbxml"),
148        CFSTR("webarchive"),
149        CFSTR("wmd"),
150        CFSTR("wml"),
151        CFSTR("wmlc"),
152        CFSTR("wmls"),
153        CFSTR("wmlsc"),
154        CFSTR("wrl"),
155        CFSTR("xdp"),
156        CFSTR("xfd"),
157        CFSTR("xfdf"),
158        CFSTR("xpm"),
159        CFSTR("xsl"),
160        CFSTR("xwd"),
161        CFSTR("xyz"),
162        CFSTR("z")
163    };
164
165    CFStringRef values[] = {
166        CFSTR("application/postscript"),
167        CFSTR("text/plain"),
168        CFSTR("application/x-bcpio"),
169        CFSTR("image/bmp"),
170        CFSTR("application/x-netcdf"),
171        CFSTR("application/octet-stream"),
172        CFSTR("application/x-gzip"),
173        CFSTR("application/x-cpio"),
174        CFSTR("application/mac-compactpro"),
175        CFSTR("application/x-csh"),
176        CFSTR("text/css"),
177        CFSTR("application/x-director"),
178        CFSTR("application/x-director"),
179        CFSTR("application/x-diskcopy"),
180        CFSTR("application/octet-stream"),
181        CFSTR("application/x-dvi"),
182        CFSTR("application/x-director"),
183        CFSTR("application/postscript"),
184        CFSTR("text/x-setext"),
185        CFSTR("application/andrew-inset"),
186        CFSTR("application/vnd.fdf"),
187        CFSTR("application/octet-stream"),
188        CFSTR("application/x-filemaker"),
189        CFSTR("application/x-filemaker"),
190        CFSTR("application/x-filemaker"),
191        CFSTR("application/x-filemaker"),
192        CFSTR("application/x-filemaker"),
193        CFSTR("application/x-filemaker"),
194        CFSTR("application/x-hdf"),
195        CFSTR("x-conference/x-cooltalk"),
196        CFSTR("image/x-icon"),
197        CFSTR("text/calendar"),
198        CFSTR("image/ief"),
199        CFSTR("model/iges"),
200        CFSTR("model/iges"),
201        CFSTR("application/octet-stream"),
202        CFSTR("text/html"),
203        CFSTR("application/x-latex"),
204        CFSTR("application/octet-stream"),
205        CFSTR("application/octet-stream"),
206        CFSTR("audio/x-mpegurl"),
207        CFSTR("audio/x-m4p"),
208        CFSTR("image/x-macpaint"),
209        CFSTR("application/x-troff-man"),
210        CFSTR("application/x-troff-me"),
211        CFSTR("model/mesh"),
212        CFSTR("application/vnd.mif"),
213        CFSTR("video/x-sgi-movie"),
214        CFSTR("audio/mpeg"),
215        CFSTR("audio/mpeg"),
216        CFSTR("application/x-troff-ms"),
217        CFSTR("model/mesh"),
218        CFSTR("video/vnd.mpegurl"),
219        CFSTR("application/x-netcdf"),
220        CFSTR("application/oda"),
221        CFSTR("image/x-portable-bitmap"),
222        CFSTR("image/x-pcx"),
223        CFSTR("chemical/x-pdb"),
224        CFSTR("image/x-portable-graymap"),
225        CFSTR("application/x-chess-pgn"),
226        CFSTR("audio/scpls"),
227        CFSTR("image/x-portable-anymap"),
228        CFSTR("image/x-macpaint"),
229        CFSTR("image/x-macpaint"),
230        CFSTR("image/x-portable-pixmap"),
231        CFSTR("image/x-cmu-raster"),
232        CFSTR("image/x-rgb"),
233        CFSTR("application/x-troff"),
234        CFSTR("audio/x-pn-realaudio-plugin"),
235        CFSTR("text/richtext"),
236        CFSTR("text/sgml"),
237        CFSTR("text/sgml"),
238        CFSTR("application/x-sh"),
239        CFSTR("application/x-shar"),
240        CFSTR("model/mesh"),
241        CFSTR("application/x-koan"),
242        CFSTR("application/x-koan"),
243        CFSTR("application/x-koan"),
244        CFSTR("application/x-koan"),
245        CFSTR("application/x-diskcopy"),
246        CFSTR("application/octet-stream"),
247        CFSTR("application/x-futuresplash"),
248        CFSTR("application/x-wais-source"),
249        CFSTR("application/x-sv4cpio"),
250        CFSTR("application/x-sv4crc"),
251        CFSTR("application/x-shockwave-flash"),
252        CFSTR("application/x-troff"),
253        CFSTR("image/x-targa"),
254        CFSTR("application/x-tcl"),
255        CFSTR("application/x-tex"),
256        CFSTR("application/x-texinfo"),
257        CFSTR("application/x-texinfo"),
258        CFSTR("application/x-gzip"),
259        CFSTR("application/x-bittorrent"),
260        CFSTR("application/x-troff"),
261        CFSTR("text/tab-separated-values"),
262        CFSTR("application/x-ustar"),
263        CFSTR("application/x-cdlink"),
264        CFSTR("model/vrml"),
265        CFSTR("image/vnd.wap.wbmp"),
266        CFSTR("application/vnd.wap.wbxml"),
267        CFSTR("application/x-webarchive"),
268        CFSTR("application/x-ms-wmd"),
269        CFSTR("text/vnd.wap.wml"),
270        CFSTR("application/vnd.wap.wmlc"),
271        CFSTR("text/vnd.wap.wmlscript"),
272        CFSTR("application/vnd.wap.wmlscriptc"),
273        CFSTR("model/vrml"),
274        CFSTR("application/vnd.adobe.xdp+xml"),
275        CFSTR("application/vnd.adobe.xfd+xml"),
276        CFSTR("application/vnd.adobe.xfdf"),
277        CFSTR("image/x-xpixmap"),
278        CFSTR("text/xml"),
279        CFSTR("image/x-xwindowdump"),
280        CFSTR("chemical/x-xyz"),
281        CFSTR("application/x-compress")
282    };
283
284    ASSERT(sizeof(keys) == sizeof(values));
285    return CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, sizeof(keys)/sizeof(CFStringRef), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
286}
287
288void adjustMIMETypeIfNecessary(CFURLResponseRef cfResponse)
289{
290    RetainPtr<CFStringRef> result = wkGetCFURLResponseMIMEType(cfResponse);
291    RetainPtr<CFStringRef> originalResult = result;
292
293    if (!result) {
294        CFURLRef url = wkGetCFURLResponseURL(cfResponse);
295        NSURL *nsURL = (NSURL *)url;
296        if ([nsURL isFileURL]) {
297            RetainPtr<CFStringRef> extension = adoptCF(CFURLCopyPathExtension(url));
298            if (extension) {
299                // <rdar://problem/7007389> CoreTypes UTI map is missing 100+ file extensions that GateKeeper knew about
300                // When this radar is resolved, we can remove this file:// url specific code.
301                static CFDictionaryRef extensionMap = createExtensionToMIMETypeMap();
302                CFMutableStringRef mutableExtension = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, extension.get());
303                CFStringLowercase(mutableExtension, NULL);
304                extension = adoptCF(mutableExtension);
305                result = (CFStringRef) CFDictionaryGetValue(extensionMap, extension.get());
306
307                if (!result) {
308                    // If the Gatekeeper-based map doesn't have a MIME type, we'll try to figure out what it should be by
309                    // looking up the file extension in the UTI maps.
310                    RetainPtr<CFStringRef> uti = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension.get(), 0));
311                    result = mimeTypeFromUTITree(uti.get());
312                }
313            }
314        }
315    }
316
317    if (!result) {
318        static CFStringRef defaultMIMETypeString = WebCore::defaultMIMEType().createCFString().leakRef();
319        result = defaultMIMETypeString;
320    }
321
322    if (result != originalResult)
323        wkSetCFURLResponseMIMEType(cfResponse, result.get());
324}
325
326NSURLResponse *synthesizeRedirectResponseIfNecessary(NSURLConnection *connection, NSURLRequest *newRequest, NSURLResponse *redirectResponse)
327{
328#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
329    if (redirectResponse)
330        return redirectResponse;
331
332    if ([[[newRequest URL] scheme] isEqualToString:[[[connection currentRequest] URL] scheme]])
333        return nil;
334
335    // If the new request is a different protocol than the current request, synthesize a redirect response.
336    // This is critical for HSTS (<rdar://problem/14241270>).
337    NSDictionary *synthesizedResponseHeaderFields = @{ @"Location": [[newRequest URL] absoluteString], @"Cache-Control": @"no-store" };
338    return [[[NSHTTPURLResponse alloc] initWithURL:[[connection currentRequest] URL] statusCode:302 HTTPVersion:(NSString *)kCFHTTPVersion1_1 headerFields:synthesizedResponseHeaderFields] autorelease];
339#else
340    UNUSED_PARAM(connection);
341    UNUSED_PARAM(newRequest);
342    return redirectResponse;
343#endif
344}
345
346}
347