initial import
[vuplus_webkit] / Source / WebCore / platform / network / ResourceHandle.cpp
1 /*
2  * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 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 "BlobRegistry.h"
31 #include "DNS.h"
32 #include "Logging.h"
33 #include "ResourceHandleClient.h"
34 #include "Timer.h"
35 #include <algorithm>
36 #include <wtf/text/CString.h>
37
38 namespace WebCore {
39
40 static bool shouldForceContentSniffing;
41
42 ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff)
43     : d(adoptPtr(new ResourceHandleInternal(this, request, client, defersLoading, shouldContentSniff && shouldContentSniffURL(request.url()))))
44 {
45     if (!request.url().isValid()) {
46         scheduleFailure(InvalidURLFailure);
47         return;
48     }
49
50     if (!portAllowed(request.url())) {
51         scheduleFailure(BlockedFailure);
52         return;
53     }
54 }
55
56 PassRefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context, const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff)
57 {
58 #if ENABLE(BLOB)
59     if (request.url().protocolIs("blob")) {
60         PassRefPtr<ResourceHandle> handle = blobRegistry().createResourceHandle(request, client);
61         if (handle)
62             return handle;
63     }
64 #endif
65
66     RefPtr<ResourceHandle> newHandle(adoptRef(new ResourceHandle(request, client, defersLoading, shouldContentSniff)));
67
68     if (newHandle->d->m_scheduledFailureType != NoFailure)
69         return newHandle.release();
70
71     if (newHandle->start(context))
72         return newHandle.release();
73
74     return 0;
75 }
76
77 void ResourceHandle::scheduleFailure(FailureType type)
78 {
79     d->m_scheduledFailureType = type;
80     d->m_failureTimer.startOneShot(0);
81 }
82
83 void ResourceHandle::fireFailure(Timer<ResourceHandle>*)
84 {
85     if (!client())
86         return;
87
88     switch (d->m_scheduledFailureType) {
89         case NoFailure:
90             ASSERT_NOT_REACHED();
91             return;
92         case BlockedFailure:
93             d->m_scheduledFailureType = NoFailure;
94             client()->wasBlocked(this);
95             return;
96         case InvalidURLFailure:
97             d->m_scheduledFailureType = NoFailure;
98             client()->cannotShowURL(this);
99             return;
100     }
101
102     ASSERT_NOT_REACHED();
103 }
104
105 ResourceHandleClient* ResourceHandle::client() const
106 {
107     return d->m_client;
108 }
109
110 void ResourceHandle::setClient(ResourceHandleClient* client)
111 {
112     d->m_client = client;
113 }
114
115 ResourceRequest& ResourceHandle::firstRequest()
116 {
117     return d->m_firstRequest;
118 }
119
120 const String& ResourceHandle::lastHTTPMethod() const
121 {
122     return d->m_lastHTTPMethod;
123 }
124
125 bool ResourceHandle::hasAuthenticationChallenge() const
126 {
127     return !d->m_currentWebChallenge.isNull();
128 }
129
130 void ResourceHandle::clearAuthentication()
131 {
132 #if PLATFORM(MAC)
133     d->m_currentMacChallenge = nil;
134 #endif
135     d->m_currentWebChallenge.nullify();
136 }
137   
138 bool ResourceHandle::shouldContentSniff() const
139 {
140     return d->m_shouldContentSniff;
141 }
142
143 bool ResourceHandle::shouldContentSniffURL(const KURL& url)
144 {
145 #if PLATFORM(MAC)
146     if (shouldForceContentSniffing)
147         return true;
148 #endif
149     // We shouldn't content sniff file URLs as their MIME type should be established via their extension.
150     return !url.protocolIs("file");
151 }
152
153 void ResourceHandle::forceContentSniffing()
154 {
155     shouldForceContentSniffing = true;
156 }
157
158 void ResourceHandle::setDefersLoading(bool defers)
159 {
160     LOG(Network, "Handle %p setDefersLoading(%s)", this, defers ? "true" : "false");
161
162     ASSERT(d->m_defersLoading != defers); // Deferring is not counted, so calling setDefersLoading() repeatedly is likely to be in error.
163     d->m_defersLoading = defers;
164
165     if (defers) {
166         ASSERT(d->m_failureTimer.isActive() == (d->m_scheduledFailureType != NoFailure));
167         if (d->m_failureTimer.isActive())
168             d->m_failureTimer.stop();
169     } else if (d->m_scheduledFailureType != NoFailure) {
170         ASSERT(!d->m_failureTimer.isActive());
171         d->m_failureTimer.startOneShot(0);
172     }
173
174     platformSetDefersLoading(defers);
175 }
176
177 #if !USE(SOUP)
178 void ResourceHandle::prepareForURL(const KURL& url)
179 {
180     return prefetchDNS(url.host());
181 }
182 #endif
183
184 void ResourceHandle::cacheMetadata(const ResourceResponse&, const Vector<char>&)
185 {
186     // Optionally implemented by platform.
187 }
188
189 } // namespace WebCore