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

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

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

Powered by Google App Engine
This is Rietveld 408576698