Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1167)

Side by Side Diff: ios/net/crn_http_protocol_handler_proxy_with_client_thread.mm

Issue 994823004: [iOS] Upstream //ios/net (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "ios/net/crn_http_protocol_handler_proxy_with_client_thread.h"
6
7 #include "base/logging.h"
8 #import "base/mac/scoped_nsobject.h"
9 #include "base/time/time.h"
10 #import "ios/net/protocol_handler_util.h"
11 #include "net/base/auth.h"
12 #include "net/url_request/url_request.h"
13
14 // When the protocol is invalidated, no synchronization (lock) is needed:
15 // - The actual calls to the protocol and its invalidation are all done on
16 // clientThread_ and thus are serialized.
17 // - When a proxy method is called, the protocol is compared to nil. There may
18 // be a conflict at this point, in the case the protocol is being invalidated
19 // during this comparison. However, in such a case, the actual value of the
20 // pointer does not matter: an invalid pointer will behave as a valid one and
21 // post a task on the clientThread_, and that task will be handled correctly,
22 // as described by the item above.
23
24 @interface CRNHTTPProtocolHandlerProxyWithClientThread () {
25 __weak NSURLProtocol* _protocol;
26 // Thread used to call the client back.
27 // This thread does not have a base::MessageLoop, and thus does not work with
28 // the usual task posting functions.
29 __weak NSThread* _clientThread;
30 // The run loop modes to use when posting tasks to |clientThread_|.
31 base::scoped_nsobject<NSArray> _runLoopModes;
32 // The request URL.
33 base::scoped_nsobject<NSString> _url;
34 // The creation time of the request.
35 base::Time _creationTime;
36 // |requestComplete_| is used in debug to check that the client is not called
37 // after completion.
38 BOOL _requestComplete;
39 }
40
41 // Performs the selector on |clientThread_| using |runLoopModes_|.
42 - (void)performSelectorOnClientThread:(SEL)aSelector withObject:(id)arg;
43 // These functions are just wrappers around the corresponding
44 // NSURLProtocolClient methods, used for task posting.
45 - (void)didFailWithErrorOnClientThread:(NSError*)error;
46 - (void)didLoadDataOnClientThread:(NSData*)data;
47 - (void)didReceiveResponseOnClientThread:(NSURLResponse*)response;
48 - (void)wasRedirectedToRequestOnClientThread:(NSArray*)params;
49 - (void)didFinishLoadingOnClientThread;
50 @end
51
52 @implementation CRNHTTPProtocolHandlerProxyWithClientThread
53
54 - (instancetype)initWithProtocol:(NSURLProtocol*)protocol
55 clientThread:(NSThread*)clientThread
56 runLoopMode:(NSString*)mode {
57 DCHECK(protocol);
58 DCHECK(clientThread);
59 if ((self = [super init])) {
60 _protocol = protocol;
61 _url.reset([[[[protocol request] URL] absoluteString] copy]);
62 _creationTime = base::Time::Now();
63 _clientThread = clientThread;
64 // Use the common run loop mode in addition to the client thread mode, in
65 // hope that our tasks are executed even if the client thread changes mode
66 // later on.
67 if ([mode isEqualToString:NSRunLoopCommonModes])
68 _runLoopModes.reset([@[ NSRunLoopCommonModes ] retain]);
69 else
70 _runLoopModes.reset([@[ mode, NSRunLoopCommonModes ] retain]);
71 }
72 return self;
73 }
74
75 - (void)invalidate {
76 DCHECK([NSThread currentThread] == _clientThread);
77 _protocol = nil;
78 _requestComplete = YES;
79 }
80
81 - (void)performSelectorOnClientThread:(SEL)aSelector withObject:(id)arg {
82 [self performSelector:aSelector
83 onThread:_clientThread
84 withObject:arg
85 waitUntilDone:NO
86 modes:_runLoopModes];
87 }
88
89 #pragma mark Proxy methods called from any thread.
90
91 - (void)didFailWithNSErrorCode:(NSInteger)nsErrorCode
92 netErrorCode:(int)netErrorCode {
93 DCHECK(_clientThread);
94 if (!_protocol)
95 return;
96 NSError* error =
97 net::GetIOSError(nsErrorCode, netErrorCode, _url, _creationTime);
98 [self performSelectorOnClientThread:@selector(didFailWithErrorOnClientThread:)
99 withObject:error];
100 }
101
102 - (void)didLoadData:(NSData*)data {
103 DCHECK(_clientThread);
104 if (!_protocol)
105 return;
106 [self performSelectorOnClientThread:@selector(didLoadDataOnClientThread:)
107 withObject:data];
108 }
109
110 - (void)didReceiveResponse:(NSURLResponse*)response {
111 DCHECK(_clientThread);
112 if (!_protocol)
113 return;
114 [self
115 performSelectorOnClientThread:@selector(didReceiveResponseOnClientThread:)
116 withObject:response];
117 }
118
119 - (void)wasRedirectedToRequest:(NSURLRequest*)request
120 nativeRequest:(net::URLRequest*)nativeRequest
121 redirectResponse:(NSURLResponse*)redirectResponse {
122 DCHECK(_clientThread);
123 if (!_protocol)
124 return;
125 [self performSelectorOnClientThread:@selector(
126 wasRedirectedToRequestOnClientThread:)
127 withObject:@[ request, redirectResponse ]];
128 }
129
130 - (void)didFinishLoading {
131 DCHECK(_clientThread);
132 if (!_protocol)
133 return;
134 [self performSelectorOnClientThread:@selector(didFinishLoadingOnClientThread)
135 withObject:nil];
136 }
137
138 // Feature support methods that don't forward to the NSURLProtocolClient.
139 - (void)didCreateNativeRequest:(net::URLRequest*)nativeRequest {
140 // no-op.
141 }
142
143 - (void)didRecieveAuthChallenge:(net::AuthChallengeInfo*)authInfo
144 nativeRequest:(const net::URLRequest&)nativeRequest
145 callback:(const network_client::AuthCallback&)callback {
146 // If we get this far, authentication has failed.
147 base::string16 empty;
148 callback.Run(false, empty, empty);
149 }
150
151 - (void)cancelAuthRequest {
152 // no-op.
153 }
154
155 - (void)setUnderlyingClient:(id<CRNNetworkClientProtocol>)underlyingClient {
156 // This is the lowest level.
157 DCHECK(!underlyingClient);
158 }
159
160 #pragma mark Proxy methods called from the client thread.
161
162 - (void)didFailWithErrorOnClientThread:(NSError*)error {
163 DCHECK([NSThread currentThread] == _clientThread);
164 DCHECK(!_requestComplete || !_protocol);
165 _requestComplete = YES;
166 [[_protocol client] URLProtocol:_protocol didFailWithError:error];
167 }
168
169 - (void)didLoadDataOnClientThread:(NSData*)data {
170 DCHECK([NSThread currentThread] == _clientThread);
171 DCHECK(!_requestComplete || !_protocol);
172 [[_protocol client] URLProtocol:_protocol didLoadData:data];
173 }
174
175 - (void)didReceiveResponseOnClientThread:(NSURLResponse*)response {
176 DCHECK([NSThread currentThread] == _clientThread);
177 DCHECK(!_requestComplete || !_protocol);
178 [[_protocol client] URLProtocol:_protocol
179 didReceiveResponse:response
180 cacheStoragePolicy:NSURLCacheStorageNotAllowed];
181 }
182
183 - (void)wasRedirectedToRequestOnClientThread:(NSArray*)params {
184 DCHECK([NSThread currentThread] == _clientThread);
185 DCHECK_EQ(2u, [params count]);
186 DCHECK([params[0] isKindOfClass:[NSURLRequest class]]);
187 DCHECK([params[1] isKindOfClass:[NSURLResponse class]]);
188 DCHECK(!_requestComplete || !_protocol);
189 [[_protocol client] URLProtocol:_protocol
190 wasRedirectedToRequest:params[0]
191 redirectResponse:params[1]];
192 }
193
194 - (void)didFinishLoadingOnClientThread {
195 DCHECK([NSThread currentThread] == _clientThread);
196 DCHECK(!_requestComplete || !_protocol);
197 _requestComplete = YES;
198 [[_protocol client] URLProtocolDidFinishLoading:_protocol];
199 }
200
201 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698