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") {
34 CronetURLRequestAdapter::~CronetURLRequestAdapter() {
35 DCHECK(IsOnNetworkThread());
38 void CronetURLRequestAdapter::AddRequestHeader(const std::string
& name
,
39 const std::string
& value
) {
40 DCHECK(!IsOnNetworkThread());
41 initial_request_headers_
.SetHeader(name
, value
);
44 bool CronetURLRequestAdapter::PostTaskToNetworkThread(
45 const tracked_objects::Location
& from_here
,
46 const base::Closure
& task
) {
47 DCHECK(!IsOnNetworkThread());
48 return context_
->GetNetworkTaskRunner()->PostTask(from_here
, task
);
51 bool CronetURLRequestAdapter::IsOnNetworkThread() const {
52 return context_
->GetNetworkTaskRunner()->BelongsToCurrentThread();
55 void CronetURLRequestAdapter::Start() {
56 DCHECK(IsOnNetworkThread());
57 VLOG(1) << "Starting chromium request: "
58 << initial_url_
.possibly_invalid_spec().c_str()
59 << " priority: " << RequestPriorityToString(initial_priority_
);
60 url_request_
= context_
->GetURLRequestContext()->CreateRequest(
61 initial_url_
, net::DEFAULT_PRIORITY
, this, NULL
);
62 url_request_
->SetLoadFlags(context_
->default_load_flags());
63 url_request_
->set_method(initial_method_
);
64 url_request_
->SetExtraRequestHeaders(initial_request_headers_
);
65 url_request_
->SetPriority(initial_priority_
);
66 url_request_
->Start();
69 void CronetURLRequestAdapter::FollowDeferredRedirect() {
70 DCHECK(IsOnNetworkThread());
72 url_request_
->FollowDeferredRedirect();
75 void CronetURLRequestAdapter::ReadData() {
76 DCHECK(IsOnNetworkThread());
77 if (!read_buffer_
.get())
78 read_buffer_
= new net::IOBufferWithSize(kReadBufferSize
);
81 url_request_
->Read(read_buffer_
.get(), read_buffer_
->size(), &bytes_read
);
82 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
83 if (url_request_
->status().is_io_pending())
86 OnReadCompleted(url_request_
.get(), bytes_read
);
89 void CronetURLRequestAdapter::Destroy() {
90 DCHECK(IsOnNetworkThread());
94 const net::HttpResponseHeaders
*
95 CronetURLRequestAdapter::GetResponseHeaders() const {
96 DCHECK(IsOnNetworkThread());
97 return url_request_
->response_headers();
100 const std::string
& CronetURLRequestAdapter::GetNegotiatedProtocol() const {
101 DCHECK(IsOnNetworkThread());
102 return url_request_
->response_info().npn_negotiated_protocol
;
105 bool CronetURLRequestAdapter::GetWasCached() const {
106 DCHECK(IsOnNetworkThread());
107 return url_request_
->response_info().was_cached
;
110 int64
CronetURLRequestAdapter::GetTotalReceivedBytes() const {
111 DCHECK(IsOnNetworkThread());
112 return url_request_
->GetTotalReceivedBytes();
115 // net::URLRequest::Delegate overrides (called on network thread).
117 void CronetURLRequestAdapter::OnReceivedRedirect(
118 net::URLRequest
* request
,
119 const net::RedirectInfo
& redirect_info
,
120 bool* defer_redirect
) {
121 DCHECK(IsOnNetworkThread());
122 DCHECK(request
->status().is_success());
123 delegate_
->OnRedirect(redirect_info
.new_url
, redirect_info
.status_code
);
124 *defer_redirect
= true;
127 void CronetURLRequestAdapter::OnResponseStarted(net::URLRequest
* request
) {
128 DCHECK(IsOnNetworkThread());
129 if (MaybeReportError(request
))
131 delegate_
->OnResponseStarted(request
->GetResponseCode());
134 void CronetURLRequestAdapter::OnReadCompleted(net::URLRequest
* request
,
136 DCHECK(IsOnNetworkThread());
137 if (MaybeReportError(request
))
139 if (bytes_read
!= 0) {
140 delegate_
->OnBytesRead(
141 reinterpret_cast<unsigned char*>(read_buffer_
->data()), bytes_read
);
143 delegate_
->OnRequestFinished();
147 bool CronetURLRequestAdapter::MaybeReportError(net::URLRequest
* request
) const {
148 DCHECK_NE(net::URLRequestStatus::IO_PENDING
, url_request_
->status().status());
149 DCHECK_EQ(request
, url_request_
);
150 if (url_request_
->status().is_success())
152 VLOG(1) << "Error " << url_request_
->status().error()
153 << " on chromium request: " << initial_url_
.possibly_invalid_spec();
154 delegate_
->OnError(url_request_
->status().error());
158 } // namespace cronet