Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(997)

Side by Side Diff: net/quic/bidirectional_stream_quic_impl.cc

Issue 1992953004: [Cronet] Make delaying sending request headers explicit in bidirectional stream (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: correct a typo Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/bidirectional_stream_quic_impl.h" 5 #include "net/quic/bidirectional_stream_quic_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/timer/timer.h" 10 #include "base/timer/timer.h"
(...skipping 14 matching lines...) Expand all
25 delegate_(nullptr), 25 delegate_(nullptr),
26 response_status_(OK), 26 response_status_(OK),
27 negotiated_protocol_(kProtoUnknown), 27 negotiated_protocol_(kProtoUnknown),
28 read_buffer_len_(0), 28 read_buffer_len_(0),
29 headers_bytes_received_(0), 29 headers_bytes_received_(0),
30 headers_bytes_sent_(0), 30 headers_bytes_sent_(0),
31 closed_stream_received_bytes_(0), 31 closed_stream_received_bytes_(0),
32 closed_stream_sent_bytes_(0), 32 closed_stream_sent_bytes_(0),
33 has_sent_headers_(false), 33 has_sent_headers_(false),
34 has_received_headers_(false), 34 has_received_headers_(false),
35 disable_auto_flush_(false), 35 send_request_headers_automatically_(true),
36 weak_factory_(this) { 36 weak_factory_(this) {
37 DCHECK(session_); 37 DCHECK(session_);
38 session_->AddObserver(this); 38 session_->AddObserver(this);
39 } 39 }
40 40
41 BidirectionalStreamQuicImpl::~BidirectionalStreamQuicImpl() { 41 BidirectionalStreamQuicImpl::~BidirectionalStreamQuicImpl() {
42 Cancel(); 42 Cancel();
43 if (session_) 43 if (session_)
44 session_->RemoveObserver(this); 44 session_->RemoveObserver(this);
45 } 45 }
46 46
47 void BidirectionalStreamQuicImpl::Start( 47 void BidirectionalStreamQuicImpl::Start(
48 const BidirectionalStreamRequestInfo* request_info, 48 const BidirectionalStreamRequestInfo* request_info,
49 const BoundNetLog& net_log, 49 const BoundNetLog& net_log,
50 bool disable_auto_flush, 50 bool send_request_headers_automatically,
51 BidirectionalStreamImpl::Delegate* delegate, 51 BidirectionalStreamImpl::Delegate* delegate,
52 std::unique_ptr<base::Timer> /* timer */) { 52 std::unique_ptr<base::Timer> /* timer */) {
53 DCHECK(!stream_); 53 DCHECK(!stream_);
54 54
55 disable_auto_flush_ = disable_auto_flush; 55 send_request_headers_automatically_ = send_request_headers_automatically;
56 if (!session_) { 56 if (!session_) {
57 NotifyError(was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR 57 NotifyError(was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR
58 : ERR_QUIC_HANDSHAKE_FAILED); 58 : ERR_QUIC_HANDSHAKE_FAILED);
59 return; 59 return;
60 } 60 }
61 61
62 delegate_ = delegate; 62 delegate_ = delegate;
63 request_info_ = request_info; 63 request_info_ = request_info;
64 64
65 int rv = stream_request_.StartRequest( 65 int rv = stream_request_.StartRequest(
66 session_, &stream_, 66 session_, &stream_,
67 base::Bind(&BidirectionalStreamQuicImpl::OnStreamReady, 67 base::Bind(&BidirectionalStreamQuicImpl::OnStreamReady,
68 weak_factory_.GetWeakPtr())); 68 weak_factory_.GetWeakPtr()));
69 if (rv == OK) { 69 if (rv == OK) {
70 OnStreamReady(rv); 70 OnStreamReady(rv);
71 } else if (!was_handshake_confirmed_) { 71 } else if (!was_handshake_confirmed_) {
72 NotifyError(ERR_QUIC_HANDSHAKE_FAILED); 72 NotifyError(ERR_QUIC_HANDSHAKE_FAILED);
73 } 73 }
74 } 74 }
75 75
76 void BidirectionalStreamQuicImpl::SendRequestHeaders() {
77 DCHECK(!has_sent_headers_);
78 DCHECK(stream_);
79
80 SpdyHeaderBlock headers;
81 HttpRequestInfo http_request_info;
82 http_request_info.url = request_info_->url;
83 http_request_info.method = request_info_->method;
84 http_request_info.extra_headers = request_info_->extra_headers;
85
86 CreateSpdyHeadersFromHttpRequest(http_request_info,
87 http_request_info.extra_headers, HTTP2, true,
88 &headers);
89 size_t headers_bytes_sent = stream_->WriteHeaders(
90 headers, request_info_->end_stream_on_headers, nullptr);
91 headers_bytes_sent_ += headers_bytes_sent;
92 has_sent_headers_ = true;
93 }
94
76 int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) { 95 int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) {
77 DCHECK(buffer); 96 DCHECK(buffer);
78 DCHECK(buffer_len); 97 DCHECK(buffer_len);
79 98
80 if (!stream_) { 99 if (!stream_) {
81 // If the stream is already closed, there is no body to read. 100 // If the stream is already closed, there is no body to read.
82 return response_status_; 101 return response_status_;
83 } 102 }
84 int rv = stream_->Read(buffer, buffer_len); 103 int rv = stream_->Read(buffer, buffer_len);
85 if (rv != ERR_IO_PENDING) { 104 if (rv != ERR_IO_PENDING) {
(...skipping 10 matching lines...) Expand all
96 read_buffer_len_ = buffer_len; 115 read_buffer_len_ = buffer_len;
97 return ERR_IO_PENDING; 116 return ERR_IO_PENDING;
98 } 117 }
99 118
100 void BidirectionalStreamQuicImpl::SendData(const scoped_refptr<IOBuffer>& data, 119 void BidirectionalStreamQuicImpl::SendData(const scoped_refptr<IOBuffer>& data,
101 int length, 120 int length,
102 bool end_stream) { 121 bool end_stream) {
103 DCHECK(stream_); 122 DCHECK(stream_);
104 DCHECK(length > 0 || (length == 0 && end_stream)); 123 DCHECK(length > 0 || (length == 0 && end_stream));
105 124
125 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler;
126 if (!has_sent_headers_) {
127 DCHECK(!send_request_headers_automatically_);
128 // Creates a bundler only if there are headers to be sent along with the
129 // single data buffer.
130 bundler.reset(new QuicConnection::ScopedPacketBundler(
131 session_->connection(), QuicConnection::SEND_ACK_IF_PENDING));
132 SendRequestHeaders();
133 }
134
106 base::StringPiece string_data(data->data(), length); 135 base::StringPiece string_data(data->data(), length);
107 int rv = stream_->WriteStreamData( 136 int rv = stream_->WriteStreamData(
108 string_data, end_stream, 137 string_data, end_stream,
109 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 138 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
110 weak_factory_.GetWeakPtr())); 139 weak_factory_.GetWeakPtr()));
111 DCHECK(rv == OK || rv == ERR_IO_PENDING); 140 DCHECK(rv == OK || rv == ERR_IO_PENDING);
112 if (rv == OK) { 141 if (rv == OK) {
113 base::ThreadTaskRunnerHandle::Get()->PostTask( 142 base::ThreadTaskRunnerHandle::Get()->PostTask(
114 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 143 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
115 weak_factory_.GetWeakPtr(), OK)); 144 weak_factory_.GetWeakPtr(), OK));
116 } 145 }
117 } 146 }
118 147
119 void BidirectionalStreamQuicImpl::SendvData( 148 void BidirectionalStreamQuicImpl::SendvData(
120 const std::vector<scoped_refptr<IOBuffer>>& buffers, 149 const std::vector<scoped_refptr<IOBuffer>>& buffers,
121 const std::vector<int>& lengths, 150 const std::vector<int>& lengths,
122 bool end_stream) { 151 bool end_stream) {
123 DCHECK(stream_); 152 DCHECK(stream_);
124 DCHECK_EQ(buffers.size(), lengths.size()); 153 DCHECK_EQ(buffers.size(), lengths.size());
125 154
126 QuicConnection::ScopedPacketBundler bundler( 155 QuicConnection::ScopedPacketBundler bundler(
127 session_->connection(), QuicConnection::SEND_ACK_IF_PENDING); 156 session_->connection(), QuicConnection::SEND_ACK_IF_PENDING);
128 if (!has_sent_headers_) { 157 if (!has_sent_headers_) {
158 DCHECK(!send_request_headers_automatically_);
129 SendRequestHeaders(); 159 SendRequestHeaders();
130 } 160 }
131 161
132 int rv = stream_->WritevStreamData( 162 int rv = stream_->WritevStreamData(
133 buffers, lengths, end_stream, 163 buffers, lengths, end_stream,
134 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 164 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
135 weak_factory_.GetWeakPtr())); 165 weak_factory_.GetWeakPtr()));
136 166
137 DCHECK(rv == OK || rv == ERR_IO_PENDING); 167 DCHECK(rv == OK || rv == ERR_IO_PENDING);
138 if (rv == OK) { 168 if (rv == OK) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 DCHECK_NE(OK, error); 261 DCHECK_NE(OK, error);
232 session_.reset(); 262 session_.reset();
233 NotifyError(error); 263 NotifyError(error);
234 } 264 }
235 265
236 void BidirectionalStreamQuicImpl::OnStreamReady(int rv) { 266 void BidirectionalStreamQuicImpl::OnStreamReady(int rv) {
237 DCHECK_NE(ERR_IO_PENDING, rv); 267 DCHECK_NE(ERR_IO_PENDING, rv);
238 DCHECK(rv == OK || !stream_); 268 DCHECK(rv == OK || !stream_);
239 if (rv == OK) { 269 if (rv == OK) {
240 stream_->SetDelegate(this); 270 stream_->SetDelegate(this);
241 if (!disable_auto_flush_) { 271 if (send_request_headers_automatically_) {
242 SendRequestHeaders(); 272 SendRequestHeaders();
243 } 273 }
244 delegate_->OnStreamReady(); 274 delegate_->OnStreamReady(has_sent_headers_);
245 } else { 275 } else {
246 NotifyError(rv); 276 NotifyError(rv);
247 } 277 }
248 } 278 }
249 279
250 void BidirectionalStreamQuicImpl::OnSendDataComplete(int rv) { 280 void BidirectionalStreamQuicImpl::OnSendDataComplete(int rv) {
251 DCHECK(rv == OK || !stream_); 281 DCHECK(rv == OK || !stream_);
252 if (rv == OK) { 282 if (rv == OK) {
253 delegate_->OnDataSent(); 283 delegate_->OnDataSent();
254 } else { 284 } else {
255 NotifyError(rv); 285 NotifyError(rv);
256 } 286 }
257 } 287 }
258 288
259 void BidirectionalStreamQuicImpl::SendRequestHeaders() {
260 DCHECK(!has_sent_headers_);
261 DCHECK(stream_);
262
263 SpdyHeaderBlock headers;
264 HttpRequestInfo http_request_info;
265 http_request_info.url = request_info_->url;
266 http_request_info.method = request_info_->method;
267 http_request_info.extra_headers = request_info_->extra_headers;
268
269 CreateSpdyHeadersFromHttpRequest(http_request_info,
270 http_request_info.extra_headers, HTTP2, true,
271 &headers);
272 size_t frame_len = stream_->WriteHeaders(
273 headers, request_info_->end_stream_on_headers, nullptr);
274 headers_bytes_sent_ += frame_len;
275 has_sent_headers_ = true;
276 }
277
278 void BidirectionalStreamQuicImpl::NotifyError(int error) { 289 void BidirectionalStreamQuicImpl::NotifyError(int error) {
279 DCHECK_NE(OK, error); 290 DCHECK_NE(OK, error);
280 DCHECK_NE(ERR_IO_PENDING, error); 291 DCHECK_NE(ERR_IO_PENDING, error);
281 292
282 response_status_ = error; 293 response_status_ = error;
283 ResetStream(); 294 ResetStream();
284 delegate_->OnFailed(error); 295 delegate_->OnFailed(error);
285 } 296 }
286 297
287 void BidirectionalStreamQuicImpl::ResetStream() { 298 void BidirectionalStreamQuicImpl::ResetStream() {
288 if (!stream_) 299 if (!stream_)
289 return; 300 return;
290 closed_stream_received_bytes_ = stream_->stream_bytes_read(); 301 closed_stream_received_bytes_ = stream_->stream_bytes_read();
291 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); 302 closed_stream_sent_bytes_ = stream_->stream_bytes_written();
292 stream_->SetDelegate(nullptr); 303 stream_->SetDelegate(nullptr);
293 stream_ = nullptr; 304 stream_ = nullptr;
294 } 305 }
295 306
296 } // namespace net 307 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/bidirectional_stream_quic_impl.h ('k') | net/quic/bidirectional_stream_quic_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698