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

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

Issue 2334943002: Add a new QuicChromiumClientSession::Handle class (Closed)
Patch Set: fixes 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 std::unique_ptr<QuicChromiumClientSession::Handle> session)
25 : session_(session), 25 : session_(std::move(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 int rv = session_->RequestStream(
76 session_->CreateStreamRequest(request_info_->method == "POST"); 70 request_info_->method == "POST",
77 int rv = stream_request_->StartRequest(base::Bind( 71 base::Bind(&BidirectionalStreamQuicImpl::OnStreamReady,
78 &BidirectionalStreamQuicImpl::OnStreamReady, weak_factory_.GetWeakPtr())); 72 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 =
156 session_->connection(), QuicConnection::SEND_ACK_IF_PENDING)); 150 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING);
157 SendRequestHeaders(); 151 SendRequestHeaders();
158 } 152 }
159 153
160 QuicStringPiece string_data(data->data(), length); 154 QuicStringPiece string_data(data->data(), length);
161 int rv = stream_->WriteStreamData( 155 int rv = stream_->WriteStreamData(
162 string_data, end_stream, 156 string_data, end_stream,
163 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 157 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
164 weak_factory_.GetWeakPtr())); 158 weak_factory_.GetWeakPtr()));
165 DCHECK(rv == OK || rv == ERR_IO_PENDING); 159 DCHECK(rv == OK || rv == ERR_IO_PENDING);
166 if (rv == OK) { 160 if (rv == OK) {
(...skipping 10 matching lines...) Expand all
177 DCHECK_EQ(buffers.size(), lengths.size()); 171 DCHECK_EQ(buffers.size(), lengths.size());
178 172
179 if (!stream_) { 173 if (!stream_) {
180 LOG(ERROR) << "Trying to send data after stream has been destroyed."; 174 LOG(ERROR) << "Trying to send data after stream has been destroyed.";
181 base::ThreadTaskRunnerHandle::Get()->PostTask( 175 base::ThreadTaskRunnerHandle::Get()->PostTask(
182 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, 176 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
183 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); 177 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
184 return; 178 return;
185 } 179 }
186 180
187 QuicConnection::ScopedPacketBundler bundler( 181 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler(
188 session_->connection(), QuicConnection::SEND_ACK_IF_PENDING); 182 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING));
189 if (!has_sent_headers_) { 183 if (!has_sent_headers_) {
190 DCHECK(!send_request_headers_automatically_); 184 DCHECK(!send_request_headers_automatically_);
191 SendRequestHeaders(); 185 SendRequestHeaders();
192 } 186 }
193 187
194 int rv = stream_->WritevStreamData( 188 int rv = stream_->WritevStreamData(
195 buffers, lengths, end_stream, 189 buffers, lengths, end_stream,
196 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 190 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
197 weak_factory_.GetWeakPtr())); 191 weak_factory_.GetWeakPtr()));
198 192
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 // Spurrious notification. Wait for the next one. 255 // Spurrious notification. Wait for the next one.
262 return; 256 return;
263 } 257 }
264 read_buffer_ = nullptr; 258 read_buffer_ = nullptr;
265 read_buffer_len_ = 0; 259 read_buffer_len_ = 0;
266 if (delegate_) 260 if (delegate_)
267 delegate_->OnDataRead(rv); 261 delegate_->OnDataRead(rv);
268 } 262 }
269 263
270 void BidirectionalStreamQuicImpl::OnClose() { 264 void BidirectionalStreamQuicImpl::OnClose() {
271 DCHECK(session_);
272 DCHECK(stream_); 265 DCHECK(stream_);
273 266
274 if (stream_->connection_error() != QUIC_NO_ERROR || 267 if (stream_->connection_error() != QUIC_NO_ERROR ||
275 stream_->stream_error() != QUIC_STREAM_NO_ERROR) { 268 stream_->stream_error() != QUIC_STREAM_NO_ERROR) {
276 NotifyError(was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR 269 NotifyError(session_->IsCryptoHandshakeConfirmed()
277 : ERR_QUIC_HANDSHAKE_FAILED); 270 ? ERR_QUIC_PROTOCOL_ERROR
271 : ERR_QUIC_HANDSHAKE_FAILED);
278 return; 272 return;
279 } 273 }
280 274
281 if (!stream_->fin_sent() || !stream_->fin_received()) { 275 if (!stream_->fin_sent() || !stream_->fin_received()) {
282 // The connection must have been closed by the peer with QUIC_NO_ERROR, 276 // The connection must have been closed by the peer with QUIC_NO_ERROR,
283 // which is improper. 277 // which is improper.
284 NotifyError(ERR_UNEXPECTED); 278 NotifyError(ERR_UNEXPECTED);
285 return; 279 return;
286 } 280 }
287 281
288 // The connection was closed normally so there is no need to notify 282 // The connection was closed normally so there is no need to notify
289 // the delegate. 283 // the delegate.
290 ResetStream(); 284 ResetStream();
291 } 285 }
292 286
293 void BidirectionalStreamQuicImpl::OnError(int error) { 287 void BidirectionalStreamQuicImpl::OnError(int error) {
294 NotifyError(error); 288 NotifyError(error);
295 } 289 }
296 290
297 void BidirectionalStreamQuicImpl::OnCryptoHandshakeConfirmed() {
298 was_handshake_confirmed_ = true;
299 }
300
301 void BidirectionalStreamQuicImpl::OnSuccessfulVersionNegotiation(
302 const QuicVersion& version) {}
303
304 void BidirectionalStreamQuicImpl::OnSessionClosed(
305 int error,
306 bool /*port_migration_detected*/) {
307 DCHECK_NE(OK, error);
308 session_.reset();
309 NotifyError(error);
310 }
311
312 void BidirectionalStreamQuicImpl::OnStreamReady(int rv) { 291 void BidirectionalStreamQuicImpl::OnStreamReady(int rv) {
313 DCHECK_NE(ERR_IO_PENDING, rv); 292 DCHECK_NE(ERR_IO_PENDING, rv);
314 DCHECK(rv == OK || !stream_); 293 DCHECK(rv == OK || !stream_);
315 if (rv == OK) { 294 if (rv == OK) {
316 stream_ = stream_request_->ReleaseStream(); 295 stream_ = session_->ReleaseStream();
317 stream_request_.reset();
318 stream_->SetDelegate(this); 296 stream_->SetDelegate(this);
319 NotifyStreamReady(); 297 NotifyStreamReady();
320 } else { 298 } else {
321 NotifyError(rv); 299 NotifyError(rv);
322 } 300 }
323 } 301 }
324 302
325 void BidirectionalStreamQuicImpl::OnSendDataComplete(int rv) { 303 void BidirectionalStreamQuicImpl::OnSendDataComplete(int rv) {
326 DCHECK(rv == OK || !stream_); 304 DCHECK(rv == OK || !stream_);
327 if (rv == OK) { 305 if (rv == OK) {
(...skipping 22 matching lines...) Expand all
350 328
351 void BidirectionalStreamQuicImpl::NotifyStreamReady() { 329 void BidirectionalStreamQuicImpl::NotifyStreamReady() {
352 if (send_request_headers_automatically_) { 330 if (send_request_headers_automatically_) {
353 SendRequestHeaders(); 331 SendRequestHeaders();
354 } 332 }
355 if (delegate_) 333 if (delegate_)
356 delegate_->OnStreamReady(has_sent_headers_); 334 delegate_->OnStreamReady(has_sent_headers_);
357 } 335 }
358 336
359 void BidirectionalStreamQuicImpl::ResetStream() { 337 void BidirectionalStreamQuicImpl::ResetStream() {
360 if (session_) {
361 session_->RemoveObserver(this);
362 session_ = nullptr;
363 }
364
365 if (!stream_) 338 if (!stream_)
366 return; 339 return;
367 closed_stream_received_bytes_ = stream_->stream_bytes_read(); 340 closed_stream_received_bytes_ = stream_->stream_bytes_read();
368 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); 341 closed_stream_sent_bytes_ = stream_->stream_bytes_written();
369 closed_is_first_stream_ = stream_->IsFirstStream(); 342 closed_is_first_stream_ = stream_->IsFirstStream();
370 stream_->SetDelegate(nullptr); 343 stream_->SetDelegate(nullptr);
371 stream_ = nullptr; 344 stream_ = nullptr;
372 } 345 }
373 346
374 } // namespace net 347 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/chromium/bidirectional_stream_quic_impl.h ('k') | net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698