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

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

Issue 2915973002: Fix potential crash bug with BidirectionalStreamQuicImpl::SendRequestHeaders (Closed)
Patch Set: Cleanup Created 3 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/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"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 return; 73 return;
74 74
75 if (rv == OK) { 75 if (rv == OK) {
76 OnStreamReady(rv); 76 OnStreamReady(rv);
77 } else if (!session_->IsCryptoHandshakeConfirmed()) { 77 } else if (!session_->IsCryptoHandshakeConfirmed()) {
78 NotifyError(ERR_QUIC_HANDSHAKE_FAILED); 78 NotifyError(ERR_QUIC_HANDSHAKE_FAILED);
79 } 79 }
80 } 80 }
81 81
82 void BidirectionalStreamQuicImpl::SendRequestHeaders() { 82 void BidirectionalStreamQuicImpl::SendRequestHeaders() {
83 WriteHeaders();
84 }
85
86 bool BidirectionalStreamQuicImpl::WriteHeaders() {
83 DCHECK(!has_sent_headers_); 87 DCHECK(!has_sent_headers_);
84 if (!stream_) { 88 if (!stream_) {
85 LOG(ERROR) 89 LOG(ERROR)
86 << "Trying to send request headers after stream has been destroyed."; 90 << "Trying to send request headers after stream has been destroyed.";
87 base::ThreadTaskRunnerHandle::Get()->PostTask( 91 base::ThreadTaskRunnerHandle::Get()->PostTask(
88 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, 92 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
89 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); 93 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
90 return; 94 return false;
91 } 95 }
92 96
93 SpdyHeaderBlock headers; 97 SpdyHeaderBlock headers;
94 HttpRequestInfo http_request_info; 98 HttpRequestInfo http_request_info;
95 http_request_info.url = request_info_->url; 99 http_request_info.url = request_info_->url;
96 http_request_info.method = request_info_->method; 100 http_request_info.method = request_info_->method;
97 http_request_info.extra_headers = request_info_->extra_headers; 101 http_request_info.extra_headers = request_info_->extra_headers;
98 102
99 CreateSpdyHeadersFromHttpRequest( 103 CreateSpdyHeadersFromHttpRequest(
100 http_request_info, http_request_info.extra_headers, true, &headers); 104 http_request_info, http_request_info.extra_headers, true, &headers);
101 // Sending the request might result in |this| being deleted. 105 // Sending the request might result in |this| being deleted.
102 auto guard = weak_factory_.GetWeakPtr(); 106 auto guard = weak_factory_.GetWeakPtr();
103 size_t headers_bytes_sent = stream_->WriteHeaders( 107 size_t headers_bytes_sent = stream_->WriteHeaders(
104 std::move(headers), request_info_->end_stream_on_headers, nullptr); 108 std::move(headers), request_info_->end_stream_on_headers, nullptr);
Ryan Hamilton 2017/06/01 00:45:33 If this fails synchronously, then the stream will
105 if (!guard.get()) 109 if (!guard.get())
106 return; 110 return false;
111
107 headers_bytes_sent_ += headers_bytes_sent; 112 headers_bytes_sent_ += headers_bytes_sent;
108 has_sent_headers_ = true; 113 has_sent_headers_ = true;
114 return true;
109 } 115 }
110 116
111 int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) { 117 int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) {
112 DCHECK(buffer); 118 DCHECK(buffer);
113 DCHECK(buffer_len); 119 DCHECK(buffer_len);
114 120
115 if (!stream_) { 121 if (!stream_) {
116 // If the stream is already closed, there is no body to read. 122 // If the stream is already closed, there is no body to read.
117 return response_status_; 123 return response_status_;
118 } 124 }
(...skipping 30 matching lines...) Expand all
149 return; 155 return;
150 } 156 }
151 157
152 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler; 158 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler;
153 if (!has_sent_headers_) { 159 if (!has_sent_headers_) {
154 DCHECK(!send_request_headers_automatically_); 160 DCHECK(!send_request_headers_automatically_);
155 // Creates a bundler only if there are headers to be sent along with the 161 // Creates a bundler only if there are headers to be sent along with the
156 // single data buffer. 162 // single data buffer.
157 bundler = 163 bundler =
158 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING); 164 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING);
159 SendRequestHeaders(); 165 // Sending the request might result in |this| being deleted.
166 if (!WriteHeaders())
167 return;
160 } 168 }
161 169
162 QuicStringPiece string_data(data->data(), length); 170 QuicStringPiece string_data(data->data(), length);
163 int rv = stream_->WriteStreamData( 171 int rv = stream_->WriteStreamData(
164 string_data, end_stream, 172 string_data, end_stream,
165 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 173 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
166 weak_factory_.GetWeakPtr())); 174 weak_factory_.GetWeakPtr()));
167 DCHECK(rv == OK || rv == ERR_IO_PENDING); 175 DCHECK(rv == OK || rv == ERR_IO_PENDING);
168 if (rv == OK) { 176 if (rv == OK) {
169 base::ThreadTaskRunnerHandle::Get()->PostTask( 177 base::ThreadTaskRunnerHandle::Get()->PostTask(
(...skipping 13 matching lines...) Expand all
183 base::ThreadTaskRunnerHandle::Get()->PostTask( 191 base::ThreadTaskRunnerHandle::Get()->PostTask(
184 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, 192 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
185 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); 193 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
186 return; 194 return;
187 } 195 }
188 196
189 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler( 197 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler(
190 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING)); 198 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING));
191 if (!has_sent_headers_) { 199 if (!has_sent_headers_) {
192 DCHECK(!send_request_headers_automatically_); 200 DCHECK(!send_request_headers_automatically_);
193 SendRequestHeaders(); 201 // Sending the request might result in |this| being deleted.
202 if (!WriteHeaders())
203 return;
194 } 204 }
195 205
196 int rv = stream_->WritevStreamData( 206 int rv = stream_->WritevStreamData(
197 buffers, lengths, end_stream, 207 buffers, lengths, end_stream,
198 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, 208 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
199 weak_factory_.GetWeakPtr())); 209 weak_factory_.GetWeakPtr()));
200 210
201 DCHECK(rv == OK || rv == ERR_IO_PENDING); 211 DCHECK(rv == OK || rv == ERR_IO_PENDING);
202 if (rv == OK) { 212 if (rv == OK) {
203 base::ThreadTaskRunnerHandle::Get()->PostTask( 213 base::ThreadTaskRunnerHandle::Get()->PostTask(
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 BidirectionalStreamImpl::Delegate* delegate = delegate_; 376 BidirectionalStreamImpl::Delegate* delegate = delegate_;
367 delegate_ = nullptr; 377 delegate_ = nullptr;
368 // Cancel any pending callback. 378 // Cancel any pending callback.
369 weak_factory_.InvalidateWeakPtrs(); 379 weak_factory_.InvalidateWeakPtrs();
370 delegate->OnFailed(error); 380 delegate->OnFailed(error);
371 // |this| might be destroyed at this point. 381 // |this| might be destroyed at this point.
372 } 382 }
373 } 383 }
374 384
375 void BidirectionalStreamQuicImpl::NotifyStreamReady() { 385 void BidirectionalStreamQuicImpl::NotifyStreamReady() {
376 if (send_request_headers_automatically_) { 386 // Sending the request might result in |this| being deleted.
377 // Sending the request might result in |this| being deleted. 387 if (send_request_headers_automatically_ && !WriteHeaders())
378 auto guard = weak_factory_.GetWeakPtr(); 388 return;
379 SendRequestHeaders(); 389
380 if (!guard.get())
381 return;
382 }
383 if (delegate_) 390 if (delegate_)
384 delegate_->OnStreamReady(has_sent_headers_); 391 delegate_->OnStreamReady(has_sent_headers_);
385 } 392 }
386 393
387 void BidirectionalStreamQuicImpl::ResetStream() { 394 void BidirectionalStreamQuicImpl::ResetStream() {
388 if (!stream_) 395 if (!stream_)
389 return; 396 return;
390 closed_stream_received_bytes_ = stream_->stream_bytes_read(); 397 closed_stream_received_bytes_ = stream_->stream_bytes_read();
391 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); 398 closed_stream_sent_bytes_ = stream_->stream_bytes_written();
392 closed_is_first_stream_ = stream_->IsFirstStream(); 399 closed_is_first_stream_ = stream_->IsFirstStream();
393 stream_->ClearDelegate(); 400 stream_->ClearDelegate();
394 stream_ = nullptr; 401 stream_ = nullptr;
395 } 402 }
396 403
397 } // namespace net 404 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698