Roll src/third_party/WebKit a1ed6cd:9e03af6 (svn 190836:190842)
[chromium-blink-merge.git] / components / cronet / android / cronet_url_request.cc
blobbc7b29fea313a72e6d5a580c8669b23e6f1647d0
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/cronet_url_request.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/scoped_java_ref.h"
10 #include "base/logging.h"
11 #include "base/macros.h"
12 #include "components/cronet/android/cronet_url_request_adapter.h"
13 #include "components/cronet/android/cronet_url_request_context_adapter.h"
14 #include "jni/CronetUrlRequest_jni.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/request_priority.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/http/http_util.h"
20 using base::android::ConvertUTF8ToJavaString;
22 // This file contains all the plumbing to handle the bidirectional communication
23 // between the Java CronetURLRequest and C++ CronetURLRequestAdapter.
25 namespace cronet {
26 namespace {
28 // A delegate of CronetURLRequestAdapter that delivers callbacks to the Java
29 // layer. Created on a Java thread, but always called and destroyed on the
30 // Network thread.
31 class JniCronetURLRequestAdapterDelegate
32 : public CronetURLRequestAdapter::CronetURLRequestAdapterDelegate {
33 public:
34 JniCronetURLRequestAdapterDelegate(JNIEnv* env, jobject owner) {
35 owner_.Reset(env, owner);
38 // CronetURLRequestAdapter::CronetURLRequestAdapterDelegate implementation.
40 void OnRedirect(const GURL& new_location, int http_status_code) override {
41 JNIEnv* env = base::android::AttachCurrentThread();
42 cronet::Java_CronetUrlRequest_onRedirect(
43 env,
44 owner_.obj(),
45 ConvertUTF8ToJavaString(env, new_location.spec()).obj(),
46 http_status_code);
49 void OnResponseStarted(int http_status_code) override {
50 JNIEnv* env = base::android::AttachCurrentThread();
51 cronet::Java_CronetUrlRequest_onResponseStarted(env,
52 owner_.obj(),
53 http_status_code);
56 void OnBytesRead(unsigned char* bytes,
57 int bytes_read) override {
58 JNIEnv* env = base::android::AttachCurrentThread();
59 base::android::ScopedJavaLocalRef<jobject> java_buffer(
60 env, env->NewDirectByteBuffer(bytes, bytes_read));
61 cronet::Java_CronetUrlRequest_onDataReceived(
62 env, owner_.obj(), java_buffer.obj());
65 void OnRequestFinished() override {
66 JNIEnv* env = base::android::AttachCurrentThread();
67 cronet::Java_CronetUrlRequest_onSucceeded(env, owner_.obj());
70 void OnError(int net_error) override {
71 JNIEnv* env = base::android::AttachCurrentThread();
72 cronet::Java_CronetUrlRequest_onError(
73 env,
74 owner_.obj(),
75 net_error,
76 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj());
79 private:
80 ~JniCronetURLRequestAdapterDelegate() override {
83 // Java object that owns the CronetURLRequestContextAdapter, which owns this
84 // delegate.
85 base::android::ScopedJavaGlobalRef<jobject> owner_;
87 DISALLOW_COPY_AND_ASSIGN(JniCronetURLRequestAdapterDelegate);
90 } // namespace
92 // Explicitly register static JNI functions.
93 bool CronetUrlRequestRegisterJni(JNIEnv* env) {
94 return RegisterNativesImpl(env);
97 static jlong CreateRequestAdapter(JNIEnv* env,
98 jobject jurl_request,
99 jlong jurl_request_context_adapter,
100 jstring jurl_string,
101 jint jpriority) {
102 CronetURLRequestContextAdapter* context_adapter =
103 reinterpret_cast<CronetURLRequestContextAdapter*>(
104 jurl_request_context_adapter);
105 DCHECK(context_adapter);
107 GURL url(base::android::ConvertJavaStringToUTF8(env, jurl_string));
109 VLOG(1) << "New chromium network request_adapter: "
110 << url.possibly_invalid_spec();
112 scoped_ptr<CronetURLRequestAdapter::CronetURLRequestAdapterDelegate> delegate(
113 new JniCronetURLRequestAdapterDelegate(env, jurl_request));
115 CronetURLRequestAdapter* adapter = new CronetURLRequestAdapter(
116 context_adapter,
117 delegate.Pass(),
118 url,
119 static_cast<net::RequestPriority>(jpriority));
121 return reinterpret_cast<jlong>(adapter);
124 static jboolean SetHttpMethod(JNIEnv* env,
125 jobject jurl_request,
126 jlong jurl_request_adapter,
127 jstring jmethod) {
128 DCHECK(jurl_request_adapter);
129 CronetURLRequestAdapter* request_adapter =
130 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
131 DCHECK(!request_adapter->IsOnNetworkThread());
132 std::string method(base::android::ConvertJavaStringToUTF8(env, jmethod));
133 // Http method is a token, just as header name.
134 if (!net::HttpUtil::IsValidHeaderName(method))
135 return JNI_FALSE;
136 request_adapter->set_method(method);
137 return JNI_TRUE;
140 static jboolean AddHeader(JNIEnv* env,
141 jobject jurl_request,
142 jlong jurl_request_adapter,
143 jstring jname,
144 jstring jvalue) {
145 DCHECK(jurl_request_adapter);
146 CronetURLRequestAdapter* request_adapter =
147 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
148 DCHECK(!request_adapter->IsOnNetworkThread());
149 std::string name(base::android::ConvertJavaStringToUTF8(env, jname));
150 std::string value(base::android::ConvertJavaStringToUTF8(env, jvalue));
151 if (!net::HttpUtil::IsValidHeaderName(name) ||
152 !net::HttpUtil::IsValidHeaderValue(value)) {
153 return JNI_FALSE;
155 request_adapter->AddRequestHeader(name, value);
156 return JNI_TRUE;
159 static void Start(JNIEnv* env,
160 jobject jurl_request,
161 jlong jurl_request_adapter) {
162 DCHECK(jurl_request_adapter);
163 CronetURLRequestAdapter* request_adapter =
164 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
165 DCHECK(!request_adapter->IsOnNetworkThread());
166 request_adapter->PostTaskToNetworkThread(
167 FROM_HERE,
168 base::Bind(&CronetURLRequestAdapter::Start,
169 base::Unretained(request_adapter)));
172 static void DestroyRequestAdapter(JNIEnv* env,
173 jobject jurl_request,
174 jlong jurl_request_adapter) {
175 DCHECK(jurl_request_adapter);
176 CronetURLRequestAdapter* request_adapter =
177 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
178 DCHECK(!request_adapter->IsOnNetworkThread());
179 request_adapter->PostTaskToNetworkThread(
180 FROM_HERE,
181 base::Bind(&CronetURLRequestAdapter::Destroy,
182 base::Unretained(request_adapter)));
185 static void ReceiveData(JNIEnv* env,
186 jobject jcaller,
187 jlong jurl_request_adapter) {
188 DCHECK(jurl_request_adapter);
189 CronetURLRequestAdapter* request_adapter =
190 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
191 DCHECK(!request_adapter->IsOnNetworkThread());
192 request_adapter->PostTaskToNetworkThread(
193 FROM_HERE,
194 base::Bind(&CronetURLRequestAdapter::ReadData,
195 base::Unretained(request_adapter)));
198 static void FollowDeferredRedirect(JNIEnv* env,
199 jobject jcaller,
200 jlong jurl_request_adapter) {
201 DCHECK(jurl_request_adapter);
202 CronetURLRequestAdapter* request_adapter =
203 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
204 DCHECK(!request_adapter->IsOnNetworkThread());
205 request_adapter->PostTaskToNetworkThread(
206 FROM_HERE,
207 base::Bind(&CronetURLRequestAdapter::FollowDeferredRedirect,
208 base::Unretained(request_adapter)));
211 static void DisableCache(JNIEnv* env,
212 jobject jurl_request,
213 jlong jurl_request_adapter) {
214 DCHECK(jurl_request_adapter);
215 CronetURLRequestAdapter* request_adapter =
216 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
217 DCHECK(!request_adapter->IsOnNetworkThread());
218 request_adapter->DisableCache();
221 static void PopulateResponseHeaders(JNIEnv* env,
222 jobject jurl_request,
223 jlong jurl_request_adapter,
224 jobject jheaders_list) {
225 DCHECK(jurl_request_adapter);
226 CronetURLRequestAdapter* request_adapter =
227 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
228 DCHECK(request_adapter->IsOnNetworkThread());
230 const net::HttpResponseHeaders* headers =
231 request_adapter->GetResponseHeaders();
232 if (headers == nullptr)
233 return;
235 void* iter = nullptr;
236 std::string header_name;
237 std::string header_value;
238 while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
239 ScopedJavaLocalRef<jstring> name =
240 ConvertUTF8ToJavaString(env, header_name);
241 ScopedJavaLocalRef<jstring> value =
242 ConvertUTF8ToJavaString(env, header_value);
243 Java_CronetUrlRequest_onAppendResponseHeader(
244 env, jurl_request, jheaders_list, name.obj(), value.obj());
248 static jstring GetNegotiatedProtocol(JNIEnv* env,
249 jobject jurl_request,
250 jlong jurl_request_adapter) {
251 DCHECK(jurl_request_adapter);
252 CronetURLRequestAdapter* request_adapter =
253 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
254 DCHECK(request_adapter->IsOnNetworkThread());
255 return ConvertUTF8ToJavaString(
256 env, request_adapter->GetNegotiatedProtocol()).Release();
259 static jboolean GetWasCached(JNIEnv* env,
260 jobject jurl_request,
261 jlong jurl_request_adapter) {
262 DCHECK(jurl_request_adapter);
263 CronetURLRequestAdapter* request_adapter =
264 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
265 DCHECK(request_adapter->IsOnNetworkThread());
266 return request_adapter->GetWasCached() ? JNI_TRUE : JNI_FALSE;
269 static jlong GetTotalReceivedBytes(JNIEnv* env,
270 jobject jurl_request,
271 jlong jurl_request_adapter) {
272 DCHECK(jurl_request_adapter);
273 CronetURLRequestAdapter* request_adapter =
274 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
275 DCHECK(request_adapter->IsOnNetworkThread());
276 return request_adapter->GetTotalReceivedBytes();
279 static jstring GetHttpStatusText(JNIEnv* env,
280 jobject jurl_request,
281 jlong jurl_request_adapter) {
282 DCHECK(jurl_request_adapter);
283 CronetURLRequestAdapter* request_adapter =
284 reinterpret_cast<CronetURLRequestAdapter*>(jurl_request_adapter);
285 DCHECK(request_adapter->IsOnNetworkThread());
286 const net::HttpResponseHeaders* headers =
287 request_adapter->GetResponseHeaders();
288 return ConvertUTF8ToJavaString(env, headers->GetStatusText()).Release();
291 } // namespace cronet