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"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "components/cronet/android/cronet_url_request_context_adapter.h"
11 #include "components/cronet/android/wrapped_channel_upload_element_reader.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/load_flags.h"
14 #include "net/http/http_status_code.h"
15 #include "net/url_request/redirect_info.h"
16 #include "net/url_request/url_request_context.h"
20 static const int kReadBufferSize
= 32768;
22 CronetURLRequestAdapter::CronetURLRequestAdapter(
23 CronetURLRequestContextAdapter
* context
,
24 scoped_ptr
<CronetURLRequestAdapterDelegate
> delegate
,
26 net::RequestPriority priority
)
28 delegate_(delegate
.Pass()),
30 initial_priority_(priority
),
31 initial_method_("GET"),
32 load_flags_(context
->default_load_flags()) {
35 CronetURLRequestAdapter::~CronetURLRequestAdapter() {
36 DCHECK(IsOnNetworkThread());
39 void CronetURLRequestAdapter::AddRequestHeader(const std::string
& name
,
40 const std::string
& value
) {
41 DCHECK(!IsOnNetworkThread());
42 initial_request_headers_
.SetHeader(name
, value
);
45 void CronetURLRequestAdapter::DisableCache() {
46 DCHECK(!IsOnNetworkThread());
47 load_flags_
|= net::LOAD_DISABLE_CACHE
;
50 void CronetURLRequestAdapter::PostTaskToNetworkThread(
51 const tracked_objects::Location
& from_here
,
52 const base::Closure
& task
) {
53 DCHECK(!IsOnNetworkThread());
54 context_
->PostTaskToNetworkThread(from_here
, task
);
57 bool CronetURLRequestAdapter::IsOnNetworkThread() const {
58 return context_
->IsOnNetworkThread();
61 void CronetURLRequestAdapter::SetUpload(
62 scoped_ptr
<net::UploadDataStream
> upload
) {
63 DCHECK(!IsOnNetworkThread());
65 upload_
= upload
.Pass();
68 void CronetURLRequestAdapter::Start() {
69 DCHECK(IsOnNetworkThread());
70 VLOG(1) << "Starting chromium request: "
71 << initial_url_
.possibly_invalid_spec().c_str()
72 << " priority: " << RequestPriorityToString(initial_priority_
);
73 url_request_
= context_
->GetURLRequestContext()->CreateRequest(
74 initial_url_
, net::DEFAULT_PRIORITY
, this, NULL
);
75 url_request_
->SetLoadFlags(load_flags_
);
76 url_request_
->set_method(initial_method_
);
77 url_request_
->SetExtraRequestHeaders(initial_request_headers_
);
78 url_request_
->SetPriority(initial_priority_
);
80 url_request_
->set_upload(upload_
.Pass());
81 url_request_
->Start();
84 void CronetURLRequestAdapter::FollowDeferredRedirect() {
85 DCHECK(IsOnNetworkThread());
87 url_request_
->FollowDeferredRedirect();
90 void CronetURLRequestAdapter::ReadData() {
91 DCHECK(IsOnNetworkThread());
92 if (!read_buffer_
.get())
93 read_buffer_
= new net::IOBufferWithSize(kReadBufferSize
);
96 url_request_
->Read(read_buffer_
.get(), read_buffer_
->size(), &bytes_read
);
97 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
98 if (url_request_
->status().is_io_pending())
101 OnReadCompleted(url_request_
.get(), bytes_read
);
104 void CronetURLRequestAdapter::Destroy() {
105 DCHECK(IsOnNetworkThread());
109 const net::HttpResponseHeaders
*
110 CronetURLRequestAdapter::GetResponseHeaders() const {
111 DCHECK(IsOnNetworkThread());
112 return url_request_
->response_headers();
115 const std::string
& CronetURLRequestAdapter::GetNegotiatedProtocol() const {
116 DCHECK(IsOnNetworkThread());
117 return url_request_
->response_info().npn_negotiated_protocol
;
120 bool CronetURLRequestAdapter::GetWasCached() const {
121 DCHECK(IsOnNetworkThread());
122 return url_request_
->response_info().was_cached
;
125 int64
CronetURLRequestAdapter::GetTotalReceivedBytes() const {
126 DCHECK(IsOnNetworkThread());
127 return url_request_
->GetTotalReceivedBytes();
130 // net::URLRequest::Delegate overrides (called on network thread).
132 void CronetURLRequestAdapter::OnReceivedRedirect(
133 net::URLRequest
* request
,
134 const net::RedirectInfo
& redirect_info
,
135 bool* defer_redirect
) {
136 DCHECK(IsOnNetworkThread());
137 DCHECK(request
->status().is_success());
138 delegate_
->OnRedirect(redirect_info
.new_url
, redirect_info
.status_code
);
139 *defer_redirect
= true;
142 void CronetURLRequestAdapter::OnResponseStarted(net::URLRequest
* request
) {
143 DCHECK(IsOnNetworkThread());
144 if (MaybeReportError(request
))
146 delegate_
->OnResponseStarted(request
->GetResponseCode());
149 void CronetURLRequestAdapter::OnReadCompleted(net::URLRequest
* request
,
151 DCHECK(IsOnNetworkThread());
152 if (MaybeReportError(request
))
154 if (bytes_read
!= 0) {
155 delegate_
->OnBytesRead(
156 reinterpret_cast<unsigned char*>(read_buffer_
->data()), bytes_read
);
158 delegate_
->OnRequestFinished();
162 bool CronetURLRequestAdapter::MaybeReportError(net::URLRequest
* request
) const {
163 DCHECK_NE(net::URLRequestStatus::IO_PENDING
, url_request_
->status().status());
164 DCHECK_EQ(request
, url_request_
);
165 if (url_request_
->status().is_success())
167 VLOG(1) << "Error " << url_request_
->status().error()
168 << " on chromium request: " << initial_url_
.possibly_invalid_spec();
169 delegate_
->OnError(url_request_
->status().error());
173 } // namespace cronet