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

Side by Side Diff: components/cronet/android/chromium_url_request.cc

Issue 2339223002: Cronet API Refactoring (Closed)
Patch Set: Moved CronetSampleApp to AppCompat Created 4 years, 2 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 2014 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 "components/cronet/android/chromium_url_request.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/macros.h"
10 #include "components/cronet/android/url_request_adapter.h"
11 #include "components/cronet/android/url_request_context_adapter.h"
12 #include "jni/ChromiumUrlRequest_jni.h"
13 #include "net/base/net_errors.h"
14 #include "net/base/request_priority.h"
15 #include "net/http/http_response_headers.h"
16
17 using base::android::ConvertUTF8ToJavaString;
18 using base::android::ConvertJavaStringToUTF8;
19 using base::android::JavaParamRef;
20 using base::android::ScopedJavaLocalRef;
21
22 namespace cronet {
23 namespace {
24
25 net::RequestPriority ConvertRequestPriority(jint request_priority) {
26 switch (request_priority) {
27 case REQUEST_PRIORITY_IDLE:
28 return net::IDLE;
29 case REQUEST_PRIORITY_LOWEST:
30 return net::LOWEST;
31 case REQUEST_PRIORITY_LOW:
32 return net::LOW;
33 case REQUEST_PRIORITY_MEDIUM:
34 return net::MEDIUM;
35 case REQUEST_PRIORITY_HIGHEST:
36 return net::HIGHEST;
37 default:
38 return net::LOWEST;
39 }
40 }
41
42 void SetPostContentType(JNIEnv* env,
43 URLRequestAdapter* request_adapter,
44 jstring content_type) {
45 std::string method_post("POST");
46 request_adapter->SetMethod(method_post);
47
48 std::string content_type_header("Content-Type");
49 std::string content_type_string(ConvertJavaStringToUTF8(env, content_type));
50
51 request_adapter->AddHeader(content_type_header, content_type_string);
52 }
53
54 // A delegate of URLRequestAdapter that delivers callbacks to the Java layer.
55 class JniURLRequestAdapterDelegate
56 : public URLRequestAdapter::URLRequestAdapterDelegate {
57 public:
58 JniURLRequestAdapterDelegate(JNIEnv* env, jobject owner) {
59 owner_ = env->NewGlobalRef(owner);
60 }
61
62 void OnResponseStarted(URLRequestAdapter* request_adapter) override {
63 JNIEnv* env = base::android::AttachCurrentThread();
64 cronet::Java_ChromiumUrlRequest_onResponseStarted(env, owner_);
65 }
66
67 void OnBytesRead(URLRequestAdapter* request_adapter,
68 int bytes_read) override {
69 if (bytes_read != 0) {
70 JNIEnv* env = base::android::AttachCurrentThread();
71 base::android::ScopedJavaLocalRef<jobject> java_buffer(
72 env, env->NewDirectByteBuffer(request_adapter->Data(), bytes_read));
73 cronet::Java_ChromiumUrlRequest_onBytesRead(env, owner_, java_buffer);
74 }
75 }
76
77 void OnRequestFinished(URLRequestAdapter* request_adapter) override {
78 JNIEnv* env = base::android::AttachCurrentThread();
79 cronet::Java_ChromiumUrlRequest_finish(env, owner_);
80 }
81
82 int ReadFromUploadChannel(net::IOBuffer* buf, int buf_length) override {
83 JNIEnv* env = base::android::AttachCurrentThread();
84 base::android::ScopedJavaLocalRef<jobject> java_buffer(
85 env, env->NewDirectByteBuffer(buf->data(), buf_length));
86 jint bytes_read = cronet::Java_ChromiumUrlRequest_readFromUploadChannel(
87 env, owner_, java_buffer);
88 return bytes_read;
89 }
90
91 protected:
92 ~JniURLRequestAdapterDelegate() override {
93 JNIEnv* env = base::android::AttachCurrentThread();
94 env->DeleteGlobalRef(owner_);
95 }
96
97 private:
98 jobject owner_;
99
100 DISALLOW_COPY_AND_ASSIGN(JniURLRequestAdapterDelegate);
101 };
102
103 } // namespace
104
105 // Explicitly register static JNI functions.
106 bool ChromiumUrlRequestRegisterJni(JNIEnv* env) {
107 return RegisterNativesImpl(env);
108 }
109
110 static jlong CreateRequestAdapter(JNIEnv* env,
111 const JavaParamRef<jobject>& jcaller,
112 jlong jurl_request_context_adapter,
113 const JavaParamRef<jstring>& jurl,
114 jint jrequest_priority) {
115 URLRequestContextAdapter* context_adapter =
116 reinterpret_cast<URLRequestContextAdapter*>(jurl_request_context_adapter);
117 DCHECK(context_adapter);
118
119 GURL url(ConvertJavaStringToUTF8(env, jurl));
120
121 VLOG(1) << "New chromium network request: " << url.possibly_invalid_spec();
122
123 URLRequestAdapter* adapter = new URLRequestAdapter(
124 context_adapter, new JniURLRequestAdapterDelegate(env, jcaller), url,
125 ConvertRequestPriority(jrequest_priority));
126
127 return reinterpret_cast<jlong>(adapter);
128 }
129
130 // synchronized
131 static void AddHeader(JNIEnv* env,
132 const JavaParamRef<jobject>& jcaller,
133 jlong jurl_request_adapter,
134 const JavaParamRef<jstring>& jheader_name,
135 const JavaParamRef<jstring>& jheader_value) {
136 URLRequestAdapter* request_adapter =
137 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
138 DCHECK(request_adapter);
139
140 std::string header_name(ConvertJavaStringToUTF8(env, jheader_name));
141 std::string header_value(ConvertJavaStringToUTF8(env, jheader_value));
142
143 request_adapter->AddHeader(header_name, header_value);
144 }
145
146 static void SetMethod(JNIEnv* env,
147 const JavaParamRef<jobject>& jcaller,
148 jlong jurl_request_adapter,
149 const JavaParamRef<jstring>& jmethod) {
150 URLRequestAdapter* request_adapter =
151 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
152 DCHECK(request_adapter);
153
154 std::string method(ConvertJavaStringToUTF8(env, jmethod));
155
156 request_adapter->SetMethod(method);
157 }
158
159 static void SetUploadData(JNIEnv* env,
160 const JavaParamRef<jobject>& jcaller,
161 jlong jurl_request_adapter,
162 const JavaParamRef<jstring>& jcontent_type,
163 const JavaParamRef<jbyteArray>& jcontent) {
164 URLRequestAdapter* request_adapter =
165 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
166 DCHECK(request_adapter);
167 SetPostContentType(env, request_adapter, jcontent_type);
168
169 if (jcontent != nullptr) {
170 jsize size = env->GetArrayLength(jcontent);
171 if (size > 0) {
172 jbyte* content_bytes = env->GetByteArrayElements(jcontent, nullptr);
173 request_adapter->SetUploadContent(
174 reinterpret_cast<const char*>(content_bytes), size);
175 env->ReleaseByteArrayElements(jcontent, content_bytes, 0);
176 }
177 }
178 }
179
180 static void SetUploadChannel(JNIEnv* env,
181 const JavaParamRef<jobject>& jcaller,
182 jlong jurl_request_adapter,
183 const JavaParamRef<jstring>& jcontent_type,
184 jlong jcontent_length) {
185 URLRequestAdapter* request_adapter =
186 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
187 DCHECK(request_adapter);
188 SetPostContentType(env, request_adapter, jcontent_type);
189
190 request_adapter->SetUploadChannel(env, jcontent_length);
191 }
192
193 static void EnableChunkedUpload(JNIEnv* env,
194 const JavaParamRef<jobject>& jcaller,
195 jlong jurl_request_adapter,
196 const JavaParamRef<jstring>& jcontent_type) {
197 URLRequestAdapter* request_adapter =
198 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
199 DCHECK(request_adapter);
200 SetPostContentType(env, request_adapter, jcontent_type);
201
202 request_adapter->EnableChunkedUpload();
203 }
204
205 static void AppendChunk(JNIEnv* env,
206 const JavaParamRef<jobject>& jcaller,
207 jlong jurl_request_adapter,
208 const JavaParamRef<jobject>& jchunk_byte_buffer,
209 jint jchunk_size,
210 jboolean jis_last_chunk) {
211 URLRequestAdapter* request_adapter =
212 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
213 DCHECK(request_adapter);
214 DCHECK(jchunk_byte_buffer);
215
216 void* chunk = env->GetDirectBufferAddress(jchunk_byte_buffer);
217 request_adapter->AppendChunk(reinterpret_cast<const char*>(chunk),
218 jchunk_size, jis_last_chunk);
219 }
220
221 /* synchronized */
222 static void Start(JNIEnv* env,
223 const JavaParamRef<jobject>& jcaller,
224 jlong jurl_request_adapter) {
225 URLRequestAdapter* request_adapter =
226 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
227 if (request_adapter != nullptr)
228 request_adapter->Start();
229 }
230
231 /* synchronized */
232 static void DestroyRequestAdapter(JNIEnv* env,
233 const JavaParamRef<jobject>& jcaller,
234 jlong jurl_request_adapter) {
235 URLRequestAdapter* request_adapter =
236 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
237 if (request_adapter != nullptr)
238 request_adapter->Destroy();
239 }
240
241 /* synchronized */
242 static void Cancel(JNIEnv* env,
243 const JavaParamRef<jobject>& jcaller,
244 jlong jurl_request_adapter) {
245 URLRequestAdapter* request_adapter =
246 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
247 if (request_adapter != nullptr)
248 request_adapter->Cancel();
249 }
250
251 static jint GetErrorCode(JNIEnv* env,
252 const JavaParamRef<jobject>& jcaller,
253 jlong jurl_request_adapter) {
254 URLRequestAdapter* request_adapter =
255 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
256 DCHECK(request_adapter);
257 int error_code = request_adapter->error_code();
258 switch (error_code) {
259 // TODO(mef): Investigate returning success on positive values, too, as
260 // they technically indicate success.
261 case net::OK:
262 return REQUEST_ERROR_SUCCESS;
263
264 // TODO(mef): Investigate this. The fact is that Chrome does not do this,
265 // and this library is not just being used for downloads.
266
267 // Comment from src/content/browser/download/download_resource_handler.cc:
268 // ERR_CONTENT_LENGTH_MISMATCH and ERR_INCOMPLETE_CHUNKED_ENCODING are
269 // allowed since a number of servers in the wild close the connection too
270 // early by mistake. Other browsers - IE9, Firefox 11.0, and Safari 5.1.4 -
271 // treat downloads as complete in both cases, so we follow their lead.
272 case net::ERR_CONTENT_LENGTH_MISMATCH:
273 case net::ERR_INCOMPLETE_CHUNKED_ENCODING:
274 return REQUEST_ERROR_SUCCESS;
275
276 case net::ERR_INVALID_URL:
277 case net::ERR_DISALLOWED_URL_SCHEME:
278 case net::ERR_UNKNOWN_URL_SCHEME:
279 return REQUEST_ERROR_MALFORMED_URL;
280
281 case net::ERR_CONNECTION_TIMED_OUT:
282 return REQUEST_ERROR_CONNECTION_TIMED_OUT;
283
284 case net::ERR_NAME_NOT_RESOLVED:
285 return REQUEST_ERROR_UNKNOWN_HOST;
286 case net::ERR_TOO_MANY_REDIRECTS:
287 return REQUEST_ERROR_TOO_MANY_REDIRECTS;
288 }
289 return REQUEST_ERROR_UNKNOWN;
290 }
291
292 static ScopedJavaLocalRef<jstring> GetErrorString(
293 JNIEnv* env,
294 const JavaParamRef<jobject>& jcaller,
295 jlong jurl_request_adapter) {
296 URLRequestAdapter* request_adapter =
297 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
298 DCHECK(request_adapter);
299 int error_code = request_adapter->error_code();
300 char buffer[200];
301 std::string error_string = net::ErrorToString(error_code);
302 snprintf(buffer,
303 sizeof(buffer),
304 "System error: %s(%d)",
305 error_string.c_str(),
306 error_code);
307 return ConvertUTF8ToJavaString(env, buffer);
308 }
309
310 static jint GetHttpStatusCode(JNIEnv* env,
311 const JavaParamRef<jobject>& jcaller,
312 jlong jurl_request_adapter) {
313 URLRequestAdapter* request_adapter =
314 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
315 DCHECK(request_adapter);
316 return request_adapter->http_status_code();
317 }
318
319 static ScopedJavaLocalRef<jstring> GetHttpStatusText(
320 JNIEnv* env,
321 const JavaParamRef<jobject>& jcaller,
322 jlong jurl_request_adapter) {
323 URLRequestAdapter* request_adapter =
324 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
325 DCHECK(request_adapter);
326 return ConvertUTF8ToJavaString(env, request_adapter->http_status_text());
327 }
328
329 static ScopedJavaLocalRef<jstring> GetContentType(
330 JNIEnv* env,
331 const JavaParamRef<jobject>& jcaller,
332 jlong jurl_request_adapter) {
333 URLRequestAdapter* request_adapter =
334 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
335 DCHECK(request_adapter);
336 std::string type = request_adapter->content_type();
337 if (!type.empty()) {
338 return ConvertUTF8ToJavaString(env, type.c_str());
339 } else {
340 return ScopedJavaLocalRef<jstring>();
341 }
342 }
343
344 static jlong GetContentLength(JNIEnv* env,
345 const JavaParamRef<jobject>& jcaller,
346 jlong jurl_request_adapter) {
347 URLRequestAdapter* request_adapter =
348 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
349 DCHECK(request_adapter);
350 return request_adapter->content_length();
351 }
352
353 static ScopedJavaLocalRef<jstring> GetHeader(
354 JNIEnv* env,
355 const JavaParamRef<jobject>& jcaller,
356 jlong jurl_request_adapter,
357 const JavaParamRef<jstring>& jheader_name) {
358 URLRequestAdapter* request_adapter =
359 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
360 DCHECK(request_adapter);
361 std::string header_name = ConvertJavaStringToUTF8(env, jheader_name);
362 std::string header_value = request_adapter->GetHeader(header_name);
363 if (!header_value.empty())
364 return ConvertUTF8ToJavaString(env, header_value.c_str());
365 return ScopedJavaLocalRef<jstring>();
366 }
367
368 static void GetAllHeaders(JNIEnv* env,
369 const JavaParamRef<jobject>& jcaller,
370 jlong jurl_request_adapter,
371 const JavaParamRef<jobject>& jheaders_map) {
372 URLRequestAdapter* request_adapter =
373 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
374 DCHECK(request_adapter);
375
376 net::HttpResponseHeaders* headers = request_adapter->GetResponseHeaders();
377 if (headers == nullptr)
378 return;
379
380 size_t iter = 0;
381 std::string header_name;
382 std::string header_value;
383 while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
384 ScopedJavaLocalRef<jstring> name =
385 ConvertUTF8ToJavaString(env, header_name);
386 ScopedJavaLocalRef<jstring> value =
387 ConvertUTF8ToJavaString(env, header_value);
388 Java_ChromiumUrlRequest_onAppendResponseHeader(env, jcaller, jheaders_map,
389 name, value);
390 }
391
392 // Some implementations (notably HttpURLConnection) include a mapping for the
393 // null key; in HTTP's case, this maps to the HTTP status line.
394 ScopedJavaLocalRef<jstring> status_line =
395 ConvertUTF8ToJavaString(env, headers->GetStatusLine());
396 Java_ChromiumUrlRequest_onAppendResponseHeader(env, jcaller, jheaders_map,
397 nullptr, status_line);
398 }
399
400 static ScopedJavaLocalRef<jstring> GetNegotiatedProtocol(
401 JNIEnv* env,
402 const JavaParamRef<jobject>& jcaller,
403 jlong jurl_request_adapter) {
404 URLRequestAdapter* request_adapter =
405 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
406 DCHECK(request_adapter);
407
408 std::string negotiated_protocol = request_adapter->GetNegotiatedProtocol();
409 return ConvertUTF8ToJavaString(env, negotiated_protocol.c_str());
410 }
411
412 static jboolean GetWasCached(JNIEnv* env,
413 const JavaParamRef<jobject>& jcaller,
414 jlong jurl_request_adapter) {
415 URLRequestAdapter* request_adapter =
416 reinterpret_cast<URLRequestAdapter*>(jurl_request_adapter);
417 DCHECK(request_adapter);
418
419 bool was_cached = request_adapter->GetWasCached();
420 return was_cached ? JNI_TRUE : JNI_FALSE;
421 }
422
423 static void DisableRedirects(JNIEnv* env,
424 const JavaParamRef<jobject>& jcaller,
425 jlong jrequest_adapter) {
426 URLRequestAdapter* request_adapter =
427 reinterpret_cast<URLRequestAdapter*>(jrequest_adapter);
428 DCHECK(request_adapter);
429 request_adapter->DisableRedirects();
430 }
431
432 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698