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

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

Issue 2334943002: Add a new QuicChromiumClientSession::Handle class (Closed)
Patch Set: cleanup Created 3 years, 7 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/chromium/bidirectional_stream_quic_impl.h" 5 #include "net/quic/chromium/bidirectional_stream_quic_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/threading/thread_task_runner_handle.h" 12 #include "base/threading/thread_task_runner_handle.h"
13 #include "base/timer/timer.h" 13 #include "base/timer/timer.h"
14 #include "net/http/bidirectional_stream_request_info.h" 14 #include "net/http/bidirectional_stream_request_info.h"
15 #include "net/quic/core/quic_connection.h" 15 #include "net/quic/core/quic_connection.h"
16 #include "net/quic/platform/api/quic_string_piece.h" 16 #include "net/quic/platform/api/quic_string_piece.h"
17 #include "net/socket/next_proto.h" 17 #include "net/socket/next_proto.h"
18 #include "net/spdy/chromium/spdy_http_utils.h" 18 #include "net/spdy/chromium/spdy_http_utils.h"
19 #include "net/spdy/core/spdy_header_block.h" 19 #include "net/spdy/core/spdy_header_block.h"
20 20
21 namespace net { 21 namespace net {
22 22
23 BidirectionalStreamQuicImpl::BidirectionalStreamQuicImpl( 23 BidirectionalStreamQuicImpl::BidirectionalStreamQuicImpl(
24 const base::WeakPtr<QuicChromiumClientSession>& session) 24 QuicChromiumClientSession::Handle session)
25 : session_(session), 25 : session_(session),
26 was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()),
27 stream_(nullptr), 26 stream_(nullptr),
28 request_info_(nullptr), 27 request_info_(nullptr),
29 delegate_(nullptr), 28 delegate_(nullptr),
30 response_status_(OK), 29 response_status_(OK),
31 negotiated_protocol_(kProtoUnknown), 30 negotiated_protocol_(kProtoUnknown),
32 read_buffer_len_(0), 31 read_buffer_len_(0),
33 headers_bytes_received_(0), 32 headers_bytes_received_(0),
34 headers_bytes_sent_(0), 33 headers_bytes_sent_(0),
35 closed_stream_received_bytes_(0), 34 closed_stream_received_bytes_(0),
36 closed_stream_sent_bytes_(0), 35 closed_stream_sent_bytes_(0),
37 closed_is_first_stream_(false), 36 closed_is_first_stream_(false),
38 has_sent_headers_(false), 37 has_sent_headers_(false),
39 has_received_headers_(false), 38 has_received_headers_(false),
40 send_request_headers_automatically_(true), 39 send_request_headers_automatically_(true),
41 weak_factory_(this) { 40 weak_factory_(this) {}
42 DCHECK(session_);
43 session_->AddObserver(this);
44 }
45 41
46 BidirectionalStreamQuicImpl::~BidirectionalStreamQuicImpl() { 42 BidirectionalStreamQuicImpl::~BidirectionalStreamQuicImpl() {
47 if (stream_) { 43 if (stream_) {
48 delegate_ = nullptr; 44 delegate_ = nullptr;
49 stream_->Reset(QUIC_STREAM_CANCELLED); 45 stream_->Reset(QUIC_STREAM_CANCELLED);
50 } 46 }
51
52 if (session_)
53 session_->RemoveObserver(this);
54 } 47 }
55 48
56 void BidirectionalStreamQuicImpl::Start( 49 void BidirectionalStreamQuicImpl::Start(
57 const BidirectionalStreamRequestInfo* request_info, 50 const BidirectionalStreamRequestInfo* request_info,
58 const NetLogWithSource& net_log, 51 const NetLogWithSource& net_log,
59 bool send_request_headers_automatically, 52 bool send_request_headers_automatically,
60 BidirectionalStreamImpl::Delegate* delegate, 53 BidirectionalStreamImpl::Delegate* delegate,
61 std::unique_ptr<base::Timer> /* timer */) { 54 std::unique_ptr<base::Timer> /* timer */) {
62 DCHECK(!stream_); 55 DCHECK(!stream_);
63 CHECK(delegate); 56 CHECK(delegate);
64 57
65 send_request_headers_automatically_ = send_request_headers_automatically; 58 send_request_headers_automatically_ = send_request_headers_automatically;
66 if (!session_) { 59 if (!session_.IsConnected()) {
67 NotifyError(was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR 60 NotifyError(session_.IsCryptoHandshakeConfirmed()
68 : ERR_QUIC_HANDSHAKE_FAILED); 61 ? ERR_QUIC_PROTOCOL_ERROR
62 : ERR_QUIC_HANDSHAKE_FAILED);
69 return; 63 return;
70 } 64 }
71 65
72 delegate_ = delegate; 66 delegate_ = delegate;
73 request_info_ = request_info; 67 request_info_ = request_info;
74 68
75 stream_request_ = 69 stream_request_ =
76 session_->CreateStreamRequest(request_info_->method == "POST"); 70 session_.CreateStreamRequest(request_info_->method == "POST");
77 int rv = stream_request_->StartRequest(base::Bind( 71 int rv = stream_request_->StartRequest(base::Bind(
xunjieli 2017/05/04 16:54:42 Instead of requiring BidiStream/HttpStream to know
Ryan Hamilton 2017/05/04 18:45:53 I hear ya! I spent a bunch of time thinking about
Ryan Hamilton 2017/05/05 03:50:24 Now that we decided to make the handle non-copyabl
78 &BidirectionalStreamQuicImpl::OnStreamReady, weak_factory_.GetWeakPtr())); 72 &BidirectionalStreamQuicImpl::OnStreamReady, weak_factory_.GetWeakPtr()));
79 if (rv == ERR_IO_PENDING) 73 if (rv == ERR_IO_PENDING)
80 return; 74 return;
81 75
82 if (rv == OK) { 76 if (rv == OK) {
83 OnStreamReady(rv); 77 OnStreamReady(rv);
84 } else if (!was_handshake_confirmed_) { 78 } else if (!session_.IsCryptoHandshakeConfirmed()) {
85 NotifyError(ERR_QUIC_HANDSHAKE_FAILED); 79 NotifyError(ERR_QUIC_HANDSHAKE_FAILED);
86 } 80 }
87 } 81 }
88 82
89 void BidirectionalStreamQuicImpl::SendRequestHeaders() { 83 void BidirectionalStreamQuicImpl::SendRequestHeaders() {
90 DCHECK(!has_sent_headers_); 84 DCHECK(!has_sent_headers_);
91 if (!stream_) { 85 if (!stream_) {
92 LOG(ERROR) 86 LOG(ERROR)
93 << "Trying to send request headers after stream has been destroyed."; 87 << "Trying to send request headers after stream has been destroyed.";
94 base::ThreadTaskRunnerHandle::Get()->PostTask( 88 base::ThreadTaskRunnerHandle::Get()->PostTask(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, 139 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
146 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); 140 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
147 return; 141 return;
148 } 142 }
149 143
150 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler; 144 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler;
151 if (!has_sent_headers_) { 145 if (!has_sent_headers_) {
152 DCHECK(!send_request_headers_automatically_); 146 DCHECK(!send_request_headers_automatically_);
153 // Creates a bundler only if there are headers to be sent along with the 147 // Creates a bundler only if there are headers to be sent along with the
154 // single data buffer. 148 // single data buffer.
155 bundler.reset(new QuicConnection::ScopedPacketBundler( 149 bundler = session_.CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING);
156 session_->connection(), QuicConnection::SEND_ACK_IF_PENDING));
157 SendRequestHeaders(); 150 SendRequestHeaders();
158 } 151 }
159 152
160 QuicStringPiece string_data(data->data(), length); 153 QuicStringPiece string_data(data->data(), length);
161 int rv = stream_->WriteStreamData( 154 int rv = stream_->WriteStreamData(
162 string_data, end_stream, 155 string_data, end_stream,
163 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 156 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
164 weak_factory_.GetWeakPtr())); 157 weak_factory_.GetWeakPtr()));
165 DCHECK(rv == OK || rv == ERR_IO_PENDING); 158 DCHECK(rv == OK || rv == ERR_IO_PENDING);
166 if (rv == OK) { 159 if (rv == OK) {
(...skipping 10 matching lines...) Expand all
177 DCHECK_EQ(buffers.size(), lengths.size()); 170 DCHECK_EQ(buffers.size(), lengths.size());
178 171
179 if (!stream_) { 172 if (!stream_) {
180 LOG(ERROR) << "Trying to send data after stream has been destroyed."; 173 LOG(ERROR) << "Trying to send data after stream has been destroyed.";
181 base::ThreadTaskRunnerHandle::Get()->PostTask( 174 base::ThreadTaskRunnerHandle::Get()->PostTask(
182 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, 175 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
183 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); 176 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
184 return; 177 return;
185 } 178 }
186 179
187 QuicConnection::ScopedPacketBundler bundler( 180 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler(
188 session_->connection(), QuicConnection::SEND_ACK_IF_PENDING); 181 session_.CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING));
189 if (!has_sent_headers_) { 182 if (!has_sent_headers_) {
190 DCHECK(!send_request_headers_automatically_); 183 DCHECK(!send_request_headers_automatically_);
191 SendRequestHeaders(); 184 SendRequestHeaders();
192 } 185 }
193 186
194 int rv = stream_->WritevStreamData( 187 int rv = stream_->WritevStreamData(
xunjieli 2017/05/04 16:54:42 Potential crash? With OnSessionClosed() removed, i
Ryan Hamilton 2017/05/05 03:50:24 Seems like a potential crash, but as discussed, it
195 buffers, lengths, end_stream, 188 buffers, lengths, end_stream,
196 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 189 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
197 weak_factory_.GetWeakPtr())); 190 weak_factory_.GetWeakPtr()));
198 191
199 DCHECK(rv == OK || rv == ERR_IO_PENDING); 192 DCHECK(rv == OK || rv == ERR_IO_PENDING);
200 if (rv == OK) { 193 if (rv == OK) {
201 base::ThreadTaskRunnerHandle::Get()->PostTask( 194 base::ThreadTaskRunnerHandle::Get()->PostTask(
202 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 195 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
203 weak_factory_.GetWeakPtr(), OK)); 196 weak_factory_.GetWeakPtr(), OK));
204 } 197 }
(...skipping 29 matching lines...) Expand all
234 return true; 227 return true;
235 } 228 }
236 229
237 void BidirectionalStreamQuicImpl::OnHeadersAvailable( 230 void BidirectionalStreamQuicImpl::OnHeadersAvailable(
238 const SpdyHeaderBlock& headers, 231 const SpdyHeaderBlock& headers,
239 size_t frame_len) { 232 size_t frame_len) {
240 headers_bytes_received_ += frame_len; 233 headers_bytes_received_ += frame_len;
241 negotiated_protocol_ = kProtoQUIC; 234 negotiated_protocol_ = kProtoQUIC;
242 if (!has_received_headers_) { 235 if (!has_received_headers_) {
243 has_received_headers_ = true; 236 has_received_headers_ = true;
244 connect_timing_ = session_->GetConnectTiming(); 237 connect_timing_ = session_.GetConnectTiming();
245 if (delegate_) 238 if (delegate_)
246 delegate_->OnHeadersReceived(headers); 239 delegate_->OnHeadersReceived(headers);
247 } else { 240 } else {
248 if (delegate_) 241 if (delegate_)
249 delegate_->OnTrailersReceived(headers); 242 delegate_->OnTrailersReceived(headers);
250 // |this| can be destroyed after this point. 243 // |this| can be destroyed after this point.
251 } 244 }
252 } 245 }
253 246
254 void BidirectionalStreamQuicImpl::OnDataAvailable() { 247 void BidirectionalStreamQuicImpl::OnDataAvailable() {
255 // Return early if ReadData has not been called. 248 // Return early if ReadData has not been called.
256 if (!read_buffer_) 249 if (!read_buffer_)
257 return; 250 return;
258 251
259 int rv = ReadData(read_buffer_.get(), read_buffer_len_); 252 int rv = ReadData(read_buffer_.get(), read_buffer_len_);
260 if (rv == ERR_IO_PENDING) { 253 if (rv == ERR_IO_PENDING) {
261 // Spurrious notification. Wait for the next one. 254 // Spurrious notification. Wait for the next one.
262 return; 255 return;
263 } 256 }
264 read_buffer_ = nullptr; 257 read_buffer_ = nullptr;
265 read_buffer_len_ = 0; 258 read_buffer_len_ = 0;
266 if (delegate_) 259 if (delegate_)
267 delegate_->OnDataRead(rv); 260 delegate_->OnDataRead(rv);
268 } 261 }
269 262
270 void BidirectionalStreamQuicImpl::OnClose() { 263 void BidirectionalStreamQuicImpl::OnClose() {
271 DCHECK(session_);
272 DCHECK(stream_); 264 DCHECK(stream_);
273 265
274 if (stream_->connection_error() != QUIC_NO_ERROR || 266 if (stream_->connection_error() != QUIC_NO_ERROR ||
275 stream_->stream_error() != QUIC_STREAM_NO_ERROR) { 267 stream_->stream_error() != QUIC_STREAM_NO_ERROR) {
276 NotifyError(was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR 268 NotifyError(session_.IsCryptoHandshakeConfirmed()
277 : ERR_QUIC_HANDSHAKE_FAILED); 269 ? ERR_QUIC_PROTOCOL_ERROR
270 : ERR_QUIC_HANDSHAKE_FAILED);
278 return; 271 return;
279 } 272 }
280 273
281 if (!stream_->fin_sent() || !stream_->fin_received()) { 274 if (!stream_->fin_sent() || !stream_->fin_received()) {
282 // The connection must have been closed by the peer with QUIC_NO_ERROR, 275 // The connection must have been closed by the peer with QUIC_NO_ERROR,
283 // which is improper. 276 // which is improper.
284 NotifyError(ERR_UNEXPECTED); 277 NotifyError(ERR_UNEXPECTED);
285 return; 278 return;
286 } 279 }
287 280
288 // The connection was closed normally so there is no need to notify 281 // The connection was closed normally so there is no need to notify
289 // the delegate. 282 // the delegate.
290 ResetStream(); 283 ResetStream();
291 } 284 }
292 285
293 void BidirectionalStreamQuicImpl::OnError(int error) { 286 void BidirectionalStreamQuicImpl::OnError(int error) {
294 NotifyError(error); 287 NotifyError(error);
295 } 288 }
296 289
297 bool BidirectionalStreamQuicImpl::HasSendHeadersComplete() { 290 bool BidirectionalStreamQuicImpl::HasSendHeadersComplete() {
298 return has_sent_headers_; 291 return has_sent_headers_;
299 } 292 }
300 293
301 void BidirectionalStreamQuicImpl::OnCryptoHandshakeConfirmed() {
302 was_handshake_confirmed_ = true;
303 }
304
305 void BidirectionalStreamQuicImpl::OnSuccessfulVersionNegotiation(
306 const QuicVersion& version) {}
307
308 void BidirectionalStreamQuicImpl::OnSessionClosed(
309 int error,
310 bool /*port_migration_detected*/) {
311 DCHECK_NE(OK, error);
312 session_.reset();
313 NotifyError(error);
314 }
315
316 void BidirectionalStreamQuicImpl::OnStreamReady(int rv) { 294 void BidirectionalStreamQuicImpl::OnStreamReady(int rv) {
317 DCHECK_NE(ERR_IO_PENDING, rv); 295 DCHECK_NE(ERR_IO_PENDING, rv);
318 DCHECK(rv == OK || !stream_); 296 DCHECK(rv == OK || !stream_);
319 if (rv == OK) { 297 if (rv == OK) {
320 stream_ = stream_request_->ReleaseStream(); 298 stream_ = stream_request_->ReleaseStream();
321 stream_request_.reset(); 299 stream_request_.reset();
322 stream_->SetDelegate(this); 300 stream_->SetDelegate(this);
323 NotifyStreamReady(); 301 NotifyStreamReady();
324 } else { 302 } else {
325 NotifyError(rv); 303 NotifyError(rv);
(...skipping 28 matching lines...) Expand all
354 332
355 void BidirectionalStreamQuicImpl::NotifyStreamReady() { 333 void BidirectionalStreamQuicImpl::NotifyStreamReady() {
356 if (send_request_headers_automatically_) { 334 if (send_request_headers_automatically_) {
357 SendRequestHeaders(); 335 SendRequestHeaders();
358 } 336 }
359 if (delegate_) 337 if (delegate_)
360 delegate_->OnStreamReady(has_sent_headers_); 338 delegate_->OnStreamReady(has_sent_headers_);
361 } 339 }
362 340
363 void BidirectionalStreamQuicImpl::ResetStream() { 341 void BidirectionalStreamQuicImpl::ResetStream() {
364 if (session_) {
365 session_->RemoveObserver(this);
366 session_ = nullptr;
367 }
368
369 if (!stream_) 342 if (!stream_)
370 return; 343 return;
371 closed_stream_received_bytes_ = stream_->stream_bytes_read(); 344 closed_stream_received_bytes_ = stream_->stream_bytes_read();
372 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); 345 closed_stream_sent_bytes_ = stream_->stream_bytes_written();
373 closed_is_first_stream_ = stream_->IsFirstStream(); 346 closed_is_first_stream_ = stream_->IsFirstStream();
374 stream_->SetDelegate(nullptr); 347 stream_->SetDelegate(nullptr);
375 stream_ = nullptr; 348 stream_ = nullptr;
376 } 349 }
377 350
378 } // namespace net 351 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698