Make castv2 performance test work.
[chromium-blink-merge.git] / components / cronet / android / cronet_url_request_adapter.cc
blob237179984a92e5915d8c4e6736d261176cc77b03
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 "cronet_url_request_adapter.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "components/cronet/android/cronet_url_request_context_adapter.h"
11 #include "jni/CronetUrlRequest_jni.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/request_priority.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/http/http_status_code.h"
18 #include "net/http/http_util.h"
19 #include "net/url_request/redirect_info.h"
20 #include "net/url_request/url_request_context.h"
22 using base::android::ConvertUTF8ToJavaString;
24 namespace cronet {
26 static const int kReadBufferSize = 32768;
28 // Explicitly register static JNI functions.
29 bool CronetUrlRequestAdapterRegisterJni(JNIEnv* env) {
30 return RegisterNativesImpl(env);
33 static jlong CreateRequestAdapter(JNIEnv* env,
34 jobject jurl_request,
35 jlong jurl_request_context_adapter,
36 jstring jurl_string,
37 jint jpriority) {
38 CronetURLRequestContextAdapter* context_adapter =
39 reinterpret_cast<CronetURLRequestContextAdapter*>(
40 jurl_request_context_adapter);
41 DCHECK(context_adapter);
43 GURL url(base::android::ConvertJavaStringToUTF8(env, jurl_string));
45 VLOG(1) << "New chromium network request_adapter: "
46 << url.possibly_invalid_spec();
48 CronetURLRequestAdapter* adapter =
49 new CronetURLRequestAdapter(context_adapter, env, jurl_request, url,
50 static_cast<net::RequestPriority>(jpriority));
52 return reinterpret_cast<jlong>(adapter);
55 CronetURLRequestAdapter::CronetURLRequestAdapter(
56 CronetURLRequestContextAdapter* context,
57 JNIEnv* env,
58 jobject jurl_request,
59 const GURL& url,
60 net::RequestPriority priority)
61 : context_(context),
62 initial_url_(url),
63 initial_priority_(priority),
64 initial_method_("GET"),
65 load_flags_(context->default_load_flags()) {
66 DCHECK(!context_->IsOnNetworkThread());
67 owner_.Reset(env, jurl_request);
70 CronetURLRequestAdapter::~CronetURLRequestAdapter() {
71 DCHECK(context_->IsOnNetworkThread());
74 jboolean CronetURLRequestAdapter::SetHttpMethod(JNIEnv* env,
75 jobject jcaller,
76 jstring jmethod) {
77 DCHECK(!context_->IsOnNetworkThread());
78 std::string method(base::android::ConvertJavaStringToUTF8(env, jmethod));
79 // Http method is a token, just as header name.
80 if (!net::HttpUtil::IsValidHeaderName(method))
81 return JNI_FALSE;
82 initial_method_ = method;
83 return JNI_TRUE;
86 jboolean CronetURLRequestAdapter::AddRequestHeader(JNIEnv* env,
87 jobject jcaller,
88 jstring jname,
89 jstring jvalue) {
90 DCHECK(!context_->IsOnNetworkThread());
91 std::string name(base::android::ConvertJavaStringToUTF8(env, jname));
92 std::string value(base::android::ConvertJavaStringToUTF8(env, jvalue));
93 if (!net::HttpUtil::IsValidHeaderName(name) ||
94 !net::HttpUtil::IsValidHeaderValue(value)) {
95 return JNI_FALSE;
97 initial_request_headers_.SetHeader(name, value);
98 return JNI_TRUE;
101 void CronetURLRequestAdapter::DisableCache(JNIEnv* env, jobject jcaller) {
102 DCHECK(!context_->IsOnNetworkThread());
103 load_flags_ |= net::LOAD_DISABLE_CACHE;
106 void CronetURLRequestAdapter::SetUpload(
107 scoped_ptr<net::UploadDataStream> upload) {
108 DCHECK(!context_->IsOnNetworkThread());
109 DCHECK(!upload_);
110 upload_ = upload.Pass();
113 void CronetURLRequestAdapter::Start(JNIEnv* env, jobject jcaller) {
114 DCHECK(!context_->IsOnNetworkThread());
115 context_->PostTaskToNetworkThread(
116 FROM_HERE, base::Bind(&CronetURLRequestAdapter::StartOnNetworkThread,
117 base::Unretained(this)));
120 void CronetURLRequestAdapter::FollowDeferredRedirect(JNIEnv* env,
121 jobject jcaller) {
122 DCHECK(!context_->IsOnNetworkThread());
123 context_->PostTaskToNetworkThread(
124 FROM_HERE,
125 base::Bind(
126 &CronetURLRequestAdapter::FollowDeferredRedirectOnNetworkThread,
127 base::Unretained(this)));
130 void CronetURLRequestAdapter::ReadData(JNIEnv* env, jobject jcaller) {
131 DCHECK(!context_->IsOnNetworkThread());
132 context_->PostTaskToNetworkThread(
133 FROM_HERE, base::Bind(&CronetURLRequestAdapter::ReadDataOnNetworkThread,
134 base::Unretained(this)));
137 void CronetURLRequestAdapter::Destroy(JNIEnv* env, jobject jcaller) {
138 DCHECK(!context_->IsOnNetworkThread());
139 context_->PostTaskToNetworkThread(
140 FROM_HERE, base::Bind(&CronetURLRequestAdapter::DestroyOnNetworkThread,
141 base::Unretained(this)));
144 void CronetURLRequestAdapter::PopulateResponseHeaders(JNIEnv* env,
145 jobject jurl_request,
146 jobject jheaders_list) {
147 DCHECK(context_->IsOnNetworkThread());
148 const net::HttpResponseHeaders* headers = url_request_->response_headers();
149 if (headers == nullptr)
150 return;
152 void* iter = nullptr;
153 std::string header_name;
154 std::string header_value;
155 while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
156 base::android::ScopedJavaLocalRef<jstring> name =
157 ConvertUTF8ToJavaString(env, header_name);
158 base::android::ScopedJavaLocalRef<jstring> value =
159 ConvertUTF8ToJavaString(env, header_value);
160 Java_CronetUrlRequest_onAppendResponseHeader(
161 env, jurl_request, jheaders_list, name.obj(), value.obj());
165 base::android::ScopedJavaLocalRef<jstring>
166 CronetURLRequestAdapter::GetHttpStatusText(JNIEnv* env, jobject jcaller) const {
167 DCHECK(context_->IsOnNetworkThread());
168 const net::HttpResponseHeaders* headers = url_request_->response_headers();
169 return ConvertUTF8ToJavaString(env, headers->GetStatusText());
172 base::android::ScopedJavaLocalRef<jstring>
173 CronetURLRequestAdapter::GetNegotiatedProtocol(JNIEnv* env,
174 jobject jcaller) const {
175 DCHECK(context_->IsOnNetworkThread());
176 return ConvertUTF8ToJavaString(
177 env, url_request_->response_info().npn_negotiated_protocol);
180 jboolean CronetURLRequestAdapter::GetWasCached(JNIEnv* env,
181 jobject jcaller) const {
182 DCHECK(context_->IsOnNetworkThread());
183 return url_request_->response_info().was_cached;
186 int64 CronetURLRequestAdapter::GetTotalReceivedBytes(JNIEnv* env,
187 jobject jcaller) const {
188 DCHECK(context_->IsOnNetworkThread());
189 return url_request_->GetTotalReceivedBytes();
192 // net::URLRequest::Delegate overrides (called on network thread).
194 void CronetURLRequestAdapter::OnReceivedRedirect(
195 net::URLRequest* request,
196 const net::RedirectInfo& redirect_info,
197 bool* defer_redirect) {
198 DCHECK(context_->IsOnNetworkThread());
199 DCHECK(request->status().is_success());
200 JNIEnv* env = base::android::AttachCurrentThread();
201 cronet::Java_CronetUrlRequest_onRedirect(
202 env, owner_.obj(),
203 ConvertUTF8ToJavaString(env, redirect_info.new_url.spec()).obj(),
204 redirect_info.status_code);
205 *defer_redirect = true;
208 void CronetURLRequestAdapter::OnResponseStarted(net::URLRequest* request) {
209 DCHECK(context_->IsOnNetworkThread());
210 if (MaybeReportError(request))
211 return;
212 JNIEnv* env = base::android::AttachCurrentThread();
213 cronet::Java_CronetUrlRequest_onResponseStarted(env, owner_.obj(),
214 request->GetResponseCode());
217 void CronetURLRequestAdapter::OnReadCompleted(net::URLRequest* request,
218 int bytes_read) {
219 DCHECK(context_->IsOnNetworkThread());
220 if (MaybeReportError(request))
221 return;
222 if (bytes_read != 0) {
223 JNIEnv* env = base::android::AttachCurrentThread();
224 base::android::ScopedJavaLocalRef<jobject> java_buffer(
225 env, env->NewDirectByteBuffer(read_buffer_->data(), bytes_read));
226 cronet::Java_CronetUrlRequest_onDataReceived(env, owner_.obj(),
227 java_buffer.obj());
228 } else {
229 JNIEnv* env = base::android::AttachCurrentThread();
230 cronet::Java_CronetUrlRequest_onSucceeded(env, owner_.obj());
234 void CronetURLRequestAdapter::StartOnNetworkThread() {
235 DCHECK(context_->IsOnNetworkThread());
236 VLOG(1) << "Starting chromium request: "
237 << initial_url_.possibly_invalid_spec().c_str()
238 << " priority: " << RequestPriorityToString(initial_priority_);
239 url_request_ = context_->GetURLRequestContext()->CreateRequest(
240 initial_url_, net::DEFAULT_PRIORITY, this);
241 url_request_->SetLoadFlags(load_flags_);
242 url_request_->set_method(initial_method_);
243 url_request_->SetExtraRequestHeaders(initial_request_headers_);
244 url_request_->SetPriority(initial_priority_);
245 if (upload_)
246 url_request_->set_upload(upload_.Pass());
247 url_request_->Start();
250 void CronetURLRequestAdapter::FollowDeferredRedirectOnNetworkThread() {
251 DCHECK(context_->IsOnNetworkThread());
252 url_request_->FollowDeferredRedirect();
255 void CronetURLRequestAdapter::ReadDataOnNetworkThread() {
256 DCHECK(context_->IsOnNetworkThread());
257 if (!read_buffer_.get())
258 read_buffer_ = new net::IOBufferWithSize(kReadBufferSize);
260 int bytes_read = 0;
261 url_request_->Read(read_buffer_.get(), read_buffer_->size(), &bytes_read);
262 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
263 if (url_request_->status().is_io_pending())
264 return;
266 OnReadCompleted(url_request_.get(), bytes_read);
269 void CronetURLRequestAdapter::DestroyOnNetworkThread() {
270 DCHECK(context_->IsOnNetworkThread());
271 delete this;
274 bool CronetURLRequestAdapter::MaybeReportError(net::URLRequest* request) const {
275 DCHECK_NE(net::URLRequestStatus::IO_PENDING, url_request_->status().status());
276 DCHECK_EQ(request, url_request_);
277 if (url_request_->status().is_success())
278 return false;
279 int net_error = url_request_->status().error();
280 VLOG(1) << "Error " << net::ErrorToString(net_error)
281 << " on chromium request: " << initial_url_.possibly_invalid_spec();
282 JNIEnv* env = base::android::AttachCurrentThread();
283 cronet::Java_CronetUrlRequest_onError(
284 env, owner_.obj(), net_error,
285 ConvertUTF8ToJavaString(env, net::ErrorToString(net_error)).obj());
286 return true;
289 } // namespace cronet