• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2004, 2006, 2007, 2008 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "ResourceHandle.h"
28 #include "ResourceHandleInternal.h"
29 
30 #include "Logging.h"
31 #include "ResourceHandleClient.h"
32 #include "Timer.h"
33 #include <algorithm>
34 
35 namespace WebCore {
36 
37 static bool shouldForceContentSniffing;
38 
39 static bool portAllowed(const ResourceRequest&);
40 
ResourceHandle(const ResourceRequest & request,ResourceHandleClient * client,bool defersLoading,bool shouldContentSniff,bool mightDownloadFromHandle)41 ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading,
42          bool shouldContentSniff, bool mightDownloadFromHandle)
43     : d(new ResourceHandleInternal(this, request, client, defersLoading, shouldContentSniff, mightDownloadFromHandle))
44 {
45 }
46 
create(const ResourceRequest & request,ResourceHandleClient * client,Frame * frame,bool defersLoading,bool shouldContentSniff,bool mightDownloadFromHandle)47 PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request, ResourceHandleClient* client,
48     Frame* frame, bool defersLoading, bool shouldContentSniff, bool mightDownloadFromHandle)
49 {
50     if (shouldContentSniff)
51         shouldContentSniff = shouldContentSniffURL(request.url());
52 
53     RefPtr<ResourceHandle> newHandle(adoptRef(new ResourceHandle(request, client, defersLoading, shouldContentSniff, mightDownloadFromHandle)));
54 
55     if (!request.url().isValid()) {
56         newHandle->scheduleFailure(InvalidURLFailure);
57         return newHandle.release();
58     }
59 
60     if (!portAllowed(request)) {
61         newHandle->scheduleFailure(BlockedFailure);
62         return newHandle.release();
63     }
64 
65     if (newHandle->start(frame))
66         return newHandle.release();
67 
68     return 0;
69 }
70 
scheduleFailure(FailureType type)71 void ResourceHandle::scheduleFailure(FailureType type)
72 {
73     d->m_failureType = type;
74     d->m_failureTimer.startOneShot(0);
75 }
76 
fireFailure(Timer<ResourceHandle> *)77 void ResourceHandle::fireFailure(Timer<ResourceHandle>*)
78 {
79     if (!client())
80         return;
81 
82     switch (d->m_failureType) {
83         case BlockedFailure:
84             client()->wasBlocked(this);
85             return;
86         case InvalidURLFailure:
87             client()->cannotShowURL(this);
88             return;
89     }
90 
91     ASSERT_NOT_REACHED();
92 }
93 
client() const94 ResourceHandleClient* ResourceHandle::client() const
95 {
96     return d->m_client;
97 }
98 
setClient(ResourceHandleClient * client)99 void ResourceHandle::setClient(ResourceHandleClient* client)
100 {
101     d->m_client = client;
102 }
103 
request() const104 const ResourceRequest& ResourceHandle::request() const
105 {
106     return d->m_request;
107 }
108 
clearAuthentication()109 void ResourceHandle::clearAuthentication()
110 {
111 #if PLATFORM(MAC)
112     d->m_currentMacChallenge = nil;
113 #elif USE(CFNETWORK)
114     d->m_currentCFChallenge = 0;
115 #endif
116     d->m_currentWebChallenge.nullify();
117 }
118 
portAllowed(const ResourceRequest & request)119 static bool portAllowed(const ResourceRequest& request)
120 {
121     unsigned short port = request.url().port();
122 
123     // Since most URLs don't have a port, return early for the "no port" case.
124     if (!port)
125         return true;
126 
127     // This blocked port list matches the port blocking that Mozilla implements.
128     // See http://www.mozilla.org/projects/netlib/PortBanning.html for more information.
129     static const unsigned short blockedPortList[] = {
130         1,    // tcpmux
131         7,    // echo
132         9,    // discard
133         11,   // systat
134         13,   // daytime
135         15,   // netstat
136         17,   // qotd
137         19,   // chargen
138         20,   // FTP-data
139         21,   // FTP-control
140         22,   // SSH
141         23,   // telnet
142         25,   // SMTP
143         37,   // time
144         42,   // name
145         43,   // nicname
146         53,   // domain
147         77,   // priv-rjs
148         79,   // finger
149         87,   // ttylink
150         95,   // supdup
151         101,  // hostriame
152         102,  // iso-tsap
153         103,  // gppitnp
154         104,  // acr-nema
155         109,  // POP2
156         110,  // POP3
157         111,  // sunrpc
158         113,  // auth
159         115,  // SFTP
160         117,  // uucp-path
161         119,  // nntp
162         123,  // NTP
163         135,  // loc-srv / epmap
164         139,  // netbios
165         143,  // IMAP2
166         179,  // BGP
167         389,  // LDAP
168         465,  // SMTP+SSL
169         512,  // print / exec
170         513,  // login
171         514,  // shell
172         515,  // printer
173         526,  // tempo
174         530,  // courier
175         531,  // Chat
176         532,  // netnews
177         540,  // UUCP
178         556,  // remotefs
179         563,  // NNTP+SSL
180         587,  // ESMTP
181         601,  // syslog-conn
182         636,  // LDAP+SSL
183         993,  // IMAP+SSL
184         995,  // POP3+SSL
185         2049, // NFS
186         3659, // apple-sasl / PasswordServer [Apple addition]
187         4045, // lockd
188         6000, // X11
189     };
190     const unsigned short* const blockedPortListEnd = blockedPortList
191         + sizeof(blockedPortList) / sizeof(blockedPortList[0]);
192 
193     // If the port is not in the blocked port list, allow it.
194     if (!std::binary_search(blockedPortList, blockedPortListEnd, port))
195         return true;
196 
197     // Allow ports 21 and 22 for FTP URLs, as Mozilla does.
198     if ((port == 21 || port == 22) && request.url().protocolIs("ftp"))
199         return true;
200 
201     // Allow any port number in a file URL, since the port number is ignored.
202     if (request.url().protocolIs("file"))
203         return true;
204 
205     return false;
206 }
207 
shouldContentSniff() const208 bool ResourceHandle::shouldContentSniff() const
209 {
210     return d->m_shouldContentSniff;
211 }
212 
shouldContentSniffURL(const KURL & url)213 bool ResourceHandle::shouldContentSniffURL(const KURL& url)
214 {
215 #if PLATFORM(MAC)
216     if (shouldForceContentSniffing)
217         return true;
218 #endif
219     // We shouldn't content sniff file URLs as their MIME type should be established via their extension.
220     return !url.protocolIs("file");
221 }
222 
forceContentSniffing()223 void ResourceHandle::forceContentSniffing()
224 {
225     shouldForceContentSniffing = true;
226 }
227 
228 } // namespace WebCore
229