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

Side by Side Diff: sky/services/ns_net/url_loader_impl.mm

Issue 1165283002: Basic network service implementation for iOS (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 6 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 2015 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 #include "url_loader_impl.h"
6 #include "base/logging.h"
7 #include "base/mac/scoped_nsautorelease_pool.h"
8
9 #import <Foundation/Foundation.h>
10
11 @interface URLLoaderConnectionDelegate : NSObject<NSURLConnectionDataDelegate>
12
13 @property(nonatomic) mojo::URLLoaderImpl::StartCallback startCallback;
14
15 @end
16
17 @implementation URLLoaderConnectionDelegate {
18 mojo::URLResponsePtr _response;
eseidel 2015/06/08 20:53:53 Is objc++ smart enough to run destructors on these
Chinmay 2015/06/08 22:03:42 Yeah, unless `-fno-objc-call-cxx-cdtors` is specif
19 mojo::ScopedDataPipeProducerHandle _producer;
20 }
21
22 @synthesize startCallback = _startCallback;
23
24 - (void)connection:(NSURLConnection*)connection
25 didReceiveResponse:(NSHTTPURLResponse*)response {
26 _response = mojo::URLResponse::New();
27 _response->status_code = response.statusCode;
28 _response->url =
29 mojo::String(connection.originalRequest.URL.absoluteString.UTF8String);
30 mojo::DataPipe pipe;
31 _response->body = pipe.consumer_handle.Pass();
32 _producer = pipe.producer_handle.Pass();
33 [self.class updateDelegate:self asPending:YES];
34 }
35
36 - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
37 if (!_startCallback.is_null()) {
38 DCHECK(_response);
39 _startCallback.Run(_response.Pass());
40 _startCallback.reset();
41 _response.reset();
42 }
43 uint32_t length = data.length;
44 MojoResult result = WriteDataRaw(_producer.get(), data.bytes, &length,
45 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
46 // FIXME(csg): Handle buffers in case of failures
47 DCHECK(result == MOJO_RESULT_OK);
48 DCHECK(length == data.length);
49 }
50
51 - (void)connectionDidFinishLoading:(NSURLConnection*)connection {
52 DCHECK(_response.is_null());
53 DCHECK(_startCallback.is_null());
54 _producer.reset();
55 [self.class updateDelegate:self asPending:NO];
56 }
57
58 - (void)connection:(NSURLConnection*)connection
59 didFailWithError:(NSError*)error {
60 if (!_startCallback.is_null()) {
61 if (_response.is_null()) {
62 _response = mojo::URLResponse::New();
63 _response->url = mojo::String(
64 connection.originalRequest.URL.absoluteString.UTF8String);
65 }
66
67 _response->error = mojo::NetworkError::New();
68 _response->error->description =
69 mojo::String(error.localizedDescription.UTF8String);
70
71 _startCallback.Run(_response.Pass());
72 _startCallback.reset();
73 }
74
75 _response.reset();
76 _producer.reset();
77 [self.class updateDelegate:self asPending:NO];
78 }
79
80 // Since the only reference to the producer end of a data pipe is held by the
81 // delegate, which itself has no strong reference, we put the in-flight requests
82 // in a collection that references these delegates while they are active.
83 + (void)updateDelegate:(URLLoaderConnectionDelegate*)delegate
84 asPending:(BOOL)pending {
85 static NSMutableSet* pendingConnections = nil;
86 static dispatch_once_t onceToken;
87 dispatch_once(&onceToken, ^{
88 pendingConnections = [[NSMutableSet alloc] init];
89 });
90 if (pending) {
91 [pendingConnections addObject:delegate];
92 } else {
93 [pendingConnections removeObject:delegate];
94 }
95 }
96
97 - (void)dealloc {
98 DCHECK(_response.is_null());
99 DCHECK(_startCallback.is_null());
100 _producer.reset();
101 [super dealloc];
102 }
103
104 @end
105
106 namespace mojo {
107
108 URLLoaderImpl::URLLoaderImpl(InterfaceRequest<URLLoader> request)
109 : binding_(this, request.Pass()),
110 connection_delegate_(nullptr),
111 pending_connection_(nullptr) {
112 connection_delegate_ = [[URLLoaderConnectionDelegate alloc] init];
113 }
114
115 URLLoaderImpl::~URLLoaderImpl() {
116 [(id)connection_delegate_ release];
117
118 [(id)pending_connection_ cancel];
119 [(id)pending_connection_ release];
120 }
121
122 void URLLoaderImpl::Start(URLRequestPtr request,
123 const StartCallback& callback) {
124 base::mac::ScopedNSAutoreleasePool pool;
125
126 NSURL* url = [NSURL URLWithString:@(request->url.data())];
127 NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
128
129 req.HTTPMethod = @(request->method.data());
130
131 if (request->bypass_cache) {
132 req.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
133 }
134
135 URLLoaderConnectionDelegate* delegate =
136 (URLLoaderConnectionDelegate*)connection_delegate_;
eseidel 2015/06/08 20:53:53 Are you sure you want to c-style cast here?
137
138 NSURLConnection* connection =
139 [NSURLConnection connectionWithRequest:req delegate:delegate];
140
141 delegate.startCallback = callback;
142
143 [connection start];
144
145 pending_connection_ = [connection retain];
146 }
147
148 void URLLoaderImpl::FollowRedirect(const FollowRedirectCallback& callback) {
149 base::mac::ScopedNSAutoreleasePool pool;
150 DCHECK(false);
151 }
152
153 void URLLoaderImpl::QueryStatus(const QueryStatusCallback& callback) {
154 base::mac::ScopedNSAutoreleasePool pool;
155 DCHECK(false);
156 }
157
158 } // namespace mojo
OLDNEW
« sky/services/ns_net/network_service_impl.mm ('K') | « sky/services/ns_net/url_loader_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698