Bundle unified sources more tightly in projects with deep directory structures
[WebKit-https.git] / Source / WebKit / UIProcess / Cocoa / LegacyCustomProtocolManagerClient.mm
1 /*
2  * Copyright (C) 2012-2017 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 "LegacyCustomProtocolManagerClient.h"
28
29 #import "DataReference.h"
30 #import "LegacyCustomProtocolManagerProxy.h"
31 #import <WebCore/ResourceError.h>
32 #import <WebCore/ResourceRequest.h>
33 #import <WebCore/ResourceResponse.h>
34
35 @interface WKCustomProtocolLoader : NSObject <NSURLConnectionDelegate> {
36 @private
37     WebKit::LegacyCustomProtocolManagerProxy* _customProtocolManagerProxy;
38     uint64_t _customProtocolID;
39     NSURLCacheStoragePolicy _storagePolicy;
40     NSURLConnection *_urlConnection;
41 }
42 - (id)initWithLegacyCustomProtocolManagerProxy:(WebKit::LegacyCustomProtocolManagerProxy*)customProtocolManagerProxy customProtocolID:(uint64_t)customProtocolID request:(NSURLRequest *)request;
43 - (void)customProtocolManagerProxyDestroyed;
44 @end
45
46 @implementation WKCustomProtocolLoader
47
48 - (id)initWithLegacyCustomProtocolManagerProxy:(WebKit::LegacyCustomProtocolManagerProxy*)customProtocolManagerProxy customProtocolID:(uint64_t)customProtocolID request:(NSURLRequest *)request
49 {
50     self = [super init];
51     if (!self)
52         return nil;
53
54     ASSERT(customProtocolManagerProxy);
55     ASSERT(request);
56     _customProtocolManagerProxy = customProtocolManagerProxy;
57     _customProtocolID = customProtocolID;
58     _storagePolicy = NSURLCacheStorageNotAllowed;
59 #pragma clang diagnostic push
60 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
61     _urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
62     [_urlConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
63     [_urlConnection start];
64 #pragma clang diagnostic pop
65
66     return self;
67 }
68
69 - (void)dealloc
70 {
71     [_urlConnection cancel];
72     [_urlConnection release];
73     [super dealloc];
74 }
75
76 - (void)customProtocolManagerProxyDestroyed
77 {
78     ASSERT(_customProtocolManagerProxy);
79     _customProtocolManagerProxy = nullptr;
80     [_urlConnection cancel];
81 }
82
83 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
84 {
85     WebCore::ResourceError coreError(error);
86     _customProtocolManagerProxy->didFailWithError(_customProtocolID, coreError);
87     _customProtocolManagerProxy->stopLoading(_customProtocolID);
88 }
89
90 - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
91 {
92     ASSERT(_storagePolicy == NSURLCacheStorageNotAllowed);
93     _storagePolicy = [cachedResponse storagePolicy];
94     return cachedResponse;
95 }
96
97 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
98 {
99     WebCore::ResourceResponse coreResponse(response);
100     _customProtocolManagerProxy->didReceiveResponse(_customProtocolID, coreResponse, _storagePolicy);
101 }
102
103 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
104 {
105     IPC::DataReference coreData(static_cast<const uint8_t*>([data bytes]), [data length]);
106     _customProtocolManagerProxy->didLoadData(_customProtocolID, coreData);
107 }
108
109 - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
110 {
111     if (redirectResponse) {
112         _customProtocolManagerProxy->wasRedirectedToRequest(_customProtocolID, request, redirectResponse);
113         return nil;
114     }
115     return request;
116 }
117
118 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
119 {
120     _customProtocolManagerProxy->didFinishLoading(_customProtocolID);
121     _customProtocolManagerProxy->stopLoading(_customProtocolID);
122 }
123
124 @end
125
126 namespace WebKit {
127 using namespace WebCore;
128
129 void LegacyCustomProtocolManagerClient::startLoading(LegacyCustomProtocolManagerProxy& manager, uint64_t customProtocolID, const ResourceRequest& coreRequest)
130 {
131     NSURLRequest *request = coreRequest.nsURLRequest(HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody);
132     if (!request)
133         return;
134
135     WKCustomProtocolLoader *loader = [[WKCustomProtocolLoader alloc] initWithLegacyCustomProtocolManagerProxy:&manager customProtocolID:customProtocolID request:request];
136     ASSERT(loader);
137     ASSERT(!m_loaderMap.contains(customProtocolID));
138     m_loaderMap.add(customProtocolID, loader);
139     [loader release];
140 }
141
142 void LegacyCustomProtocolManagerClient::stopLoading(LegacyCustomProtocolManagerProxy&, uint64_t customProtocolID)
143 {
144     m_loaderMap.remove(customProtocolID);
145 }
146
147 void LegacyCustomProtocolManagerClient::invalidate(LegacyCustomProtocolManagerProxy&)
148 {
149     while (!m_loaderMap.isEmpty()) {
150         auto loader = m_loaderMap.take(m_loaderMap.begin()->key);
151         ASSERT(loader);
152         [loader customProtocolManagerProxyDestroyed];
153     }
154 }
155
156 } // namespace WebKit