Don't use (Details) when exposing SPI
[WebKit-https.git] / Source / WebCore / platform / network / mac / WebCoreResourceHandleAsDelegate.mm
1 /*
2  * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 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  * 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 INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WebCoreResourceHandleAsDelegate.h"
28
29 #if !USE(CFNETWORK)
30
31 #import "AuthenticationChallenge.h"
32 #import "AuthenticationMac.h"
33 #import "Logging.h"
34 #import "NSURLRequestSPI.h"
35 #import "ResourceHandle.h"
36 #import "ResourceHandleClient.h"
37 #import "ResourceRequest.h"
38 #import "ResourceResponse.h"
39 #import "SharedBuffer.h"
40 #import "WebCoreURLResponse.h"
41
42 using namespace WebCore;
43
44 @implementation WebCoreResourceHandleAsDelegate
45
46 - (id)initWithHandle:(ResourceHandle*)handle
47 {
48     self = [self init];
49     if (!self)
50         return nil;
51     m_handle = handle;
52     return self;
53 }
54
55 - (void)detachHandle
56 {
57     m_handle = 0;
58 }
59
60 - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse
61 {
62     UNUSED_PARAM(connection);
63
64     if (!m_handle)
65         return nil;
66
67     redirectResponse = synthesizeRedirectResponseIfNecessary(connection, newRequest, redirectResponse);
68     
69     // See <rdar://problem/5380697>. This is a workaround for a behavior change in CFNetwork where willSendRequest gets called more often.
70     if (!redirectResponse)
71         return newRequest;
72
73 #if !LOG_DISABLED
74     if ([redirectResponse isKindOfClass:[NSHTTPURLResponse class]])
75         LOG(Network, "Handle %p delegate connection:%p willSendRequest:%@ redirectResponse:%d, Location:<%@>", m_handle, connection, [newRequest description], static_cast<int>([(id)redirectResponse statusCode]), [[(id)redirectResponse allHeaderFields] objectForKey:@"Location"]);
76     else
77         LOG(Network, "Handle %p delegate connection:%p willSendRequest:%@ redirectResponse:non-HTTP", m_handle, connection, [newRequest description]); 
78 #endif
79
80     ResourceRequest request = newRequest;
81
82     m_handle->willSendRequest(request, redirectResponse);
83
84     return request.nsURLRequest(UpdateHTTPBody);
85 }
86
87 - (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
88 {
89     UNUSED_PARAM(connection);
90
91     LOG(Network, "Handle %p delegate connectionShouldUseCredentialStorage:%p", m_handle, connection);
92
93 #if PLATFORM(IOS)
94     return NO;
95 #else
96     if (!m_handle)
97         return NO;
98
99     return m_handle->shouldUseCredentialStorage();
100 #endif
101 }
102
103 - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
104 {
105     UNUSED_PARAM(connection);
106
107     LOG(Network, "Handle %p delegate connection:%p didReceiveAuthenticationChallenge:%p", m_handle, connection, challenge);
108
109     if (!m_handle) {
110         [[challenge sender] cancelAuthenticationChallenge:challenge];
111         return;
112     }
113     m_handle->didReceiveAuthenticationChallenge(core(challenge));
114 }
115
116 - (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
117 {
118     // FIXME: We probably don't need to implement this (see <rdar://problem/8960124>).
119
120     UNUSED_PARAM(connection);
121
122     LOG(Network, "Handle %p delegate connection:%p didCancelAuthenticationChallenge:%p", m_handle, connection, challenge);
123
124     if (!m_handle)
125         return;
126     m_handle->didCancelAuthenticationChallenge(core(challenge));
127 }
128
129 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
130 - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
131 {
132     UNUSED_PARAM(connection);
133
134     LOG(Network, "Handle %p delegate connection:%p canAuthenticateAgainstProtectionSpace:%@://%@:%u realm:%@ method:%@ %@%@", m_handle, connection, [protectionSpace protocol], [protectionSpace host], [protectionSpace port], [protectionSpace realm], [protectionSpace authenticationMethod], [protectionSpace isProxy] ? @"proxy:" : @"", [protectionSpace isProxy] ? [protectionSpace proxyType] : @"");
135
136     if (!m_handle)
137         return NO;
138
139     return m_handle->canAuthenticateAgainstProtectionSpace(ProtectionSpace(protectionSpace));
140 }
141 #endif
142
143 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)r
144 {
145 #if !PLATFORM(IOS)
146     UNUSED_PARAM(connection);
147 #endif
148
149     LOG(Network, "Handle %p delegate connection:%p didReceiveResponse:%p (HTTP status %d, reported MIMEType '%s')", m_handle, connection, r, [r respondsToSelector:@selector(statusCode)] ? [(id)r statusCode] : 0, [[r MIMEType] UTF8String]);
150
151     if (!m_handle || !m_handle->client())
152         return;
153
154     // Avoid MIME type sniffing if the response comes back as 304 Not Modified.
155     int statusCode = [r respondsToSelector:@selector(statusCode)] ? [(id)r statusCode] : 0;
156     if (statusCode != 304)
157         adjustMIMETypeIfNecessary([r _CFURLResponse]);
158
159 #if !PLATFORM(IOS)
160     if ([m_handle->firstRequest().nsURLRequest(DoNotUpdateHTTPBody) _propertyForKey:@"ForceHTMLMIMEType"])
161         [r _setMIMEType:@"text/html"];
162 #endif
163
164 #if USE(QUICK_LOOK)
165     m_handle->setQuickLookHandle(QuickLookHandle::create(m_handle, connection, r, self));
166     if (m_handle->quickLookHandle())
167         r = m_handle->quickLookHandle()->nsResponse();
168 #endif
169     
170     ResourceResponse resourceResponse(r);
171 #if ENABLE(WEB_TIMING)
172     ResourceHandle::getConnectionTimingData(connection, resourceResponse.resourceLoadTiming());
173 #else
174     UNUSED_PARAM(connection);
175 #endif
176     
177     m_handle->client()->didReceiveResponse(m_handle, resourceResponse);
178 }
179
180 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
181 - (void)connection:(NSURLConnection *)connection didReceiveDataArray:(NSArray *)dataArray
182 {
183     UNUSED_PARAM(connection);
184     LOG(Network, "Handle %p delegate connection:%p didReceiveDataArray:%p arraySize:%d", m_handle, connection, dataArray, [dataArray count]);
185
186     if (!dataArray)
187         return;
188
189     if (!m_handle || !m_handle->client())
190         return;
191
192 #if USE(QUICK_LOOK)
193     if (m_handle->quickLookHandle() && m_handle->quickLookHandle()->didReceiveDataArray(reinterpret_cast<CFArrayRef>(dataArray)))
194         return;
195 #endif
196
197     m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapCFDataArray(reinterpret_cast<CFArrayRef>(dataArray)), -1);
198     // The call to didReceiveData above can cancel a load, and if so, the delegate (self) could have been deallocated by this point.
199 }
200 #endif
201
202 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data lengthReceived:(long long)lengthReceived
203 {
204     UNUSED_PARAM(connection);
205     UNUSED_PARAM(lengthReceived);
206
207     LOG(Network, "Handle %p delegate connection:%p didReceiveData:%p lengthReceived:%lld", m_handle, connection, data, lengthReceived);
208
209 #if PLATFORM(IOS)
210     if ([data length] == 0) // <rdar://problem/5532931>
211         return;
212 #endif
213
214     if (!m_handle || !m_handle->client())
215         return;
216     // FIXME: If we get more than 2B bytes in a single chunk, this code won't do the right thing.
217     // However, with today's computers and networking speeds, this won't happen in practice.
218     // Could be an issue with a giant local file.
219
220 #if USE(QUICK_LOOK)
221     if (m_handle->quickLookHandle() && m_handle->quickLookHandle()->didReceiveData(reinterpret_cast<CFDataRef>(data)))
222         return;
223 #endif
224
225     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793
226     // -1 means we do not provide any data about transfer size to inspector so it would use
227     // Content-Length headers or content size to show transfer size.
228     m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapNSData(data), -1);
229 }
230
231 - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
232 {
233     UNUSED_PARAM(connection);
234     UNUSED_PARAM(bytesWritten);
235
236     LOG(Network, "Handle %p delegate connection:%p didSendBodyData:%d totalBytesWritten:%d totalBytesExpectedToWrite:%d", m_handle, connection, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
237
238     if (!m_handle || !m_handle->client())
239         return;
240     m_handle->client()->didSendData(m_handle, totalBytesWritten, totalBytesExpectedToWrite);
241 }
242
243 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
244 {
245     UNUSED_PARAM(connection);
246
247     LOG(Network, "Handle %p delegate connectionDidFinishLoading:%p", m_handle, connection);
248
249     if (!m_handle || !m_handle->client())
250         return;
251
252 #if USE(QUICK_LOOK)
253     if (m_handle->quickLookHandle() && m_handle->quickLookHandle()->didFinishLoading())
254         return;
255 #endif
256
257     m_handle->client()->didFinishLoading(m_handle, 0);
258 }
259
260 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
261 {
262     UNUSED_PARAM(connection);
263
264     LOG(Network, "Handle %p delegate connection:%p didFailWithError:%@", m_handle, connection, error);
265
266     if (!m_handle || !m_handle->client())
267         return;
268
269 #if USE(QUICK_LOOK)
270     if (m_handle->quickLookHandle())
271         m_handle->quickLookHandle()->didFail();
272 #endif
273
274     m_handle->client()->didFail(m_handle, error);
275 }
276
277
278 - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
279 {
280     LOG(Network, "Handle %p delegate connection:%p willCacheResponse:%p", m_handle, connection, cachedResponse);
281
282     UNUSED_PARAM(connection);
283
284     if (!m_handle || !m_handle->client())
285         return nil;
286
287     return m_handle->client()->willCacheResponse(m_handle, cachedResponse);
288 }
289
290 @end
291
292 #endif // !USE(CFNETWORK)
293