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(net::LOAD_DISABLE_CACHE
|
63 net::LOAD_DO_NOT_SAVE_COOKIES
|
64 net::LOAD_DO_NOT_SEND_COOKIES
);
65 url_request_
->set_method(initial_method_
);
66 url_request_
->SetExtraRequestHeaders(initial_request_headers_
);
67 url_request_
->SetPriority(initial_priority_
);
68 url_request_
->Start();
71 void CronetURLRequestAdapter::FollowDeferredRedirect() {
72 DCHECK(IsOnNetworkThread());
74 url_request_
->FollowDeferredRedirect();
77 void CronetURLRequestAdapter::ReadData() {
78 DCHECK(IsOnNetworkThread());
79 if (!read_buffer_
.get())
80 read_buffer_
= new net::IOBufferWithSize(kReadBufferSize
);
83 url_request_
->Read(read_buffer_
.get(), read_buffer_
->size(), &bytes_read
);
84 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
85 if (url_request_
->status().is_io_pending())
88 OnReadCompleted(url_request_
.get(), bytes_read
);
91 void CronetURLRequestAdapter::Destroy() {
92 DCHECK(IsOnNetworkThread());
96 const net::HttpResponseHeaders
*
97 CronetURLRequestAdapter::GetResponseHeaders() const {
98 DCHECK(IsOnNetworkThread());
99 return url_request_
->response_headers();
102 const std::string
& CronetURLRequestAdapter::GetNegotiatedProtocol() const {
103 DCHECK(IsOnNetworkThread());
104 return url_request_
->response_info().npn_negotiated_protocol
;
107 bool CronetURLRequestAdapter::GetWasCached() const {
108 DCHECK(IsOnNetworkThread());
109 return url_request_
->response_info().was_cached
;
112 int64
CronetURLRequestAdapter::GetTotalReceivedBytes() const {
113 DCHECK(IsOnNetworkThread());
114 return url_request_
->GetTotalReceivedBytes();
117 // net::URLRequest::Delegate overrides (called on network thread).
119 void CronetURLRequestAdapter::OnReceivedRedirect(
120 net::URLRequest
* request
,
121 const net::RedirectInfo
& redirect_info
,
122 bool* defer_redirect
) {
123 DCHECK(IsOnNetworkThread());
124 DCHECK(request
->status().is_success());
125 delegate_
->OnRedirect(redirect_info
.new_url
, redirect_info
.status_code
);
126 *defer_redirect
= true;
129 void CronetURLRequestAdapter::OnResponseStarted(net::URLRequest
* request
) {
130 DCHECK(IsOnNetworkThread());
131 if (MaybeReportError(request
))
133 delegate_
->OnResponseStarted(request
->GetResponseCode());
136 void CronetURLRequestAdapter::OnReadCompleted(net::URLRequest
* request
,
138 DCHECK(IsOnNetworkThread());
139 if (MaybeReportError(request
))
141 if (bytes_read
!= 0) {
142 delegate_
->OnBytesRead(
143 reinterpret_cast<unsigned char*>(read_buffer_
->data()), bytes_read
);
145 delegate_
->OnRequestFinished();
149 bool CronetURLRequestAdapter::MaybeReportError(net::URLRequest
* request
) const {
150 DCHECK_NE(net::URLRequestStatus::IO_PENDING
, url_request_
->status().status());
151 DCHECK_EQ(request
, url_request_
);
152 if (url_request_
->status().is_success())
154 VLOG(1) << "Error " << url_request_
->status().error()
155 << " on chromium request: " << initial_url_
.possibly_invalid_spec();
156 delegate_
->OnError(url_request_
->status().error());
160 } // namespace cronet