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