Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/quic_chromium_client_stream.h" | 5 #include "net/quic/chromium/quic_chromium_client_stream.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/threading/thread_task_runner_handle.h" | 12 #include "base/threading/thread_task_runner_handle.h" |
| 13 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
| 14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/log/net_log_event_type.h" | 15 #include "net/log/net_log_event_type.h" |
| 16 #include "net/quic/chromium/quic_chromium_client_session.h" | 16 #include "net/quic/chromium/quic_chromium_client_session.h" |
| 17 #include "net/quic/chromium/quic_http_utils.h" | 17 #include "net/quic/chromium/quic_http_utils.h" |
| 18 #include "net/quic/core/quic_spdy_session.h" | 18 #include "net/quic/core/quic_spdy_session.h" |
| 19 #include "net/quic/core/quic_write_blocked_list.h" | 19 #include "net/quic/core/quic_write_blocked_list.h" |
| 20 #include "net/quic/core/spdy_utils.h" | 20 #include "net/quic/core/spdy_utils.h" |
| 21 | 21 |
| 22 namespace net { | 22 namespace net { |
| 23 namespace { | |
| 24 // Sets a boolean to a value, and restores it to the previous value once | |
| 25 // the saver goes out of scope. | |
| 26 class ScopedBoolSaver { | |
| 27 public: | |
| 28 ScopedBoolSaver(bool* var, bool new_val) : var_(var), old_val_(*var) { | |
| 29 *var_ = new_val; | |
| 30 } | |
| 23 | 31 |
| 24 QuicChromiumClientStream::Handle::Handle(QuicChromiumClientStream* stream, | 32 ~ScopedBoolSaver() { *var_ = old_val_; } |
| 25 Delegate* delegate) | 33 |
| 34 private: | |
| 35 bool* var_; | |
| 36 bool old_val_; | |
| 37 }; | |
| 38 } // namespace | |
| 39 | |
| 40 QuicChromiumClientStream::Handle::Handle(QuicChromiumClientStream* stream) | |
| 26 : stream_(stream), | 41 : stream_(stream), |
| 27 delegate_(delegate), | 42 may_invoke_callbacks_(true), |
| 28 read_headers_buffer_(nullptr), | 43 read_headers_buffer_(nullptr), |
| 29 read_body_buffer_len_(0) { | 44 read_body_buffer_len_(0), |
| 45 net_error_(ERR_UNEXPECTED), | |
| 46 weak_factory_(this) { | |
| 30 SaveState(); | 47 SaveState(); |
| 31 } | 48 } |
| 32 | 49 |
| 33 QuicChromiumClientStream::Handle::~Handle() { | 50 QuicChromiumClientStream::Handle::~Handle() { |
| 34 if (stream_) { | 51 if (stream_) { |
| 35 stream_->ClearHandle(); | 52 stream_->ClearHandle(); |
| 36 // TODO(rch): If stream_ is still valid, it should probably be Reset() | 53 // TODO(rch): If stream_ is still valid, it should probably be Reset() |
| 37 // so that it does not leak. | 54 // so that it does not leak. |
| 38 // stream_->Reset(QUIC_STREAM_CANCELLED); | 55 // stream_->Reset(QUIC_STREAM_CANCELLED); |
| 39 } | 56 } |
| 40 } | 57 } |
| 41 | 58 |
| 42 void QuicChromiumClientStream::Handle::ClearDelegate() { | |
| 43 delegate_ = nullptr; | |
| 44 } | |
| 45 | |
| 46 void QuicChromiumClientStream::Handle::OnInitialHeadersAvailable() { | 59 void QuicChromiumClientStream::Handle::OnInitialHeadersAvailable() { |
| 47 if (!read_headers_callback_) | 60 if (!read_headers_callback_) |
| 48 return; // Wait for ReadInitialHeaders to be called. | 61 return; // Wait for ReadInitialHeaders to be called. |
| 49 | 62 |
| 50 int rv = ERR_QUIC_PROTOCOL_ERROR; | 63 int rv = ERR_QUIC_PROTOCOL_ERROR; |
| 51 if (!stream_->DeliverInitialHeaders(read_headers_buffer_, &rv)) | 64 if (!stream_->DeliverInitialHeaders(read_headers_buffer_, &rv)) |
| 52 rv = ERR_QUIC_PROTOCOL_ERROR; | 65 rv = ERR_QUIC_PROTOCOL_ERROR; |
| 53 | 66 |
| 54 ResetAndReturn(&read_headers_callback_).Run(rv); | 67 ResetAndRun(&read_headers_callback_, rv); |
| 55 } | 68 } |
| 56 | 69 |
| 57 void QuicChromiumClientStream::Handle::OnTrailingHeadersAvailable() { | 70 void QuicChromiumClientStream::Handle::OnTrailingHeadersAvailable() { |
| 58 if (!read_headers_callback_) | 71 if (!read_headers_callback_) |
| 59 return; // Wait for ReadInitialHeaders to be called. | 72 return; // Wait for ReadInitialHeaders to be called. |
| 60 | 73 |
| 61 int rv = ERR_QUIC_PROTOCOL_ERROR; | 74 int rv = ERR_QUIC_PROTOCOL_ERROR; |
| 62 if (!stream_->DeliverTrailingHeaders(read_headers_buffer_, &rv)) | 75 if (!stream_->DeliverTrailingHeaders(read_headers_buffer_, &rv)) |
| 63 rv = ERR_QUIC_PROTOCOL_ERROR; | 76 rv = ERR_QUIC_PROTOCOL_ERROR; |
| 64 | 77 |
| 65 ResetAndReturn(&read_headers_callback_).Run(rv); | 78 ResetAndRun(&read_headers_callback_, rv); |
| 66 } | 79 } |
| 67 | 80 |
| 68 void QuicChromiumClientStream::Handle::OnDataAvailable() { | 81 void QuicChromiumClientStream::Handle::OnDataAvailable() { |
| 69 if (!read_body_callback_) | 82 if (!read_body_callback_) |
| 70 return; // Wait for ReadBody to be called. | 83 return; // Wait for ReadBody to be called. |
| 71 | 84 |
| 72 int rv = stream_->Read(read_body_buffer_, read_body_buffer_len_); | 85 int rv = stream_->Read(read_body_buffer_, read_body_buffer_len_); |
| 73 if (rv == ERR_IO_PENDING) | 86 if (rv == ERR_IO_PENDING) |
| 74 return; // Spurrious, likely because of trailers? | 87 return; // Spurrious, likely because of trailers? |
| 75 | 88 |
| 76 read_body_buffer_ = nullptr; | 89 read_body_buffer_ = nullptr; |
| 77 read_body_buffer_len_ = 0; | 90 read_body_buffer_len_ = 0; |
| 78 ResetAndReturn(&read_body_callback_).Run(rv); | 91 ResetAndRun(&read_body_callback_, rv); |
| 79 } | 92 } |
| 80 | 93 |
| 81 void QuicChromiumClientStream::Handle::OnCanWrite() { | 94 void QuicChromiumClientStream::Handle::OnCanWrite() { |
| 82 if (!write_callback_) | 95 if (!write_callback_) |
| 83 return; | 96 return; |
| 84 | 97 |
| 85 base::ResetAndReturn(&write_callback_).Run(OK); | 98 ResetAndRun(&write_callback_, OK); |
| 86 } | 99 } |
| 87 | 100 |
| 88 void QuicChromiumClientStream::Handle::OnClose() { | 101 void QuicChromiumClientStream::Handle::OnClose() { |
| 102 if (net_error_ == ERR_UNEXPECTED) { | |
| 103 if (stream_error() == QUIC_STREAM_NO_ERROR && | |
| 104 connection_error() == QUIC_NO_ERROR && fin_sent() && fin_received()) { | |
| 105 net_error_ = ERR_CONNECTION_CLOSED; | |
| 106 } else { | |
| 107 net_error_ = ERR_QUIC_PROTOCOL_ERROR; | |
| 108 } | |
| 109 } | |
| 110 OnError(net_error_); | |
| 111 } | |
| 112 | |
| 113 void QuicChromiumClientStream::Handle::OnError(int error) { | |
| 114 net_error_ = error; | |
| 89 if (stream_) | 115 if (stream_) |
| 90 SaveState(); | 116 SaveState(); |
| 91 stream_ = nullptr; | 117 stream_ = nullptr; |
| 92 if (delegate_) { | 118 |
| 93 auto* delegate = delegate_; | 119 // Post a task to invoke the callbacks to ensure that there is no reentrancy. |
| 94 delegate_ = nullptr; | 120 // A ScopedPacketBundler might cause an error which closes the stream under |
| 95 delegate->OnClose(); | 121 // the call stack of the owner of the handle. |
| 96 } | 122 base::ThreadTaskRunnerHandle::Get()->PostTask( |
|
xunjieli
2017/05/31 00:25:22
Is this PostTask necessary?
The callback shouldn'
Ryan Hamilton
2017/05/31 02:49:56
The problem is not that the caller might call into
xunjieli
2017/06/01 15:30:32
Acknowledged. You are totally right. I missed the
| |
| 123 FROM_HERE, | |
| 124 base::Bind(&QuicChromiumClientStream::Handle::InvokeCallbacksOnError, | |
| 125 weak_factory_.GetWeakPtr(), error)); | |
| 97 } | 126 } |
| 98 | 127 |
| 99 void QuicChromiumClientStream::Handle::OnError(int error) { | 128 void QuicChromiumClientStream::Handle::InvokeCallbacksOnError(int error) { |
| 100 if (stream_) | 129 // Invoking a callback may cause |this| to be deleted. If this happens, no |
| 101 SaveState(); | 130 // more callbacks should be invoked. Guard against this by holding a WeakPtr |
| 102 stream_ = nullptr; | 131 // to |this| and ensuring it's still valid. |
| 103 if (delegate_) { | 132 auto guard(weak_factory_.GetWeakPtr()); |
| 104 auto* delegate = delegate_; | 133 for (auto* callback : |
| 105 delegate_ = nullptr; | 134 {&read_headers_callback_, &read_body_callback_, &write_callback_}) { |
| 106 delegate->OnError(error); | 135 if (*callback) |
| 136 ResetAndRun(callback, error); | |
| 137 if (!guard.get()) | |
| 138 return; | |
| 107 } | 139 } |
| 108 } | 140 } |
| 109 | 141 |
| 110 int QuicChromiumClientStream::Handle::ReadInitialHeaders( | 142 int QuicChromiumClientStream::Handle::ReadInitialHeaders( |
| 111 SpdyHeaderBlock* header_block, | 143 SpdyHeaderBlock* header_block, |
| 112 const CompletionCallback& callback) { | 144 const CompletionCallback& callback) { |
| 145 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | |
| 113 if (!stream_) | 146 if (!stream_) |
| 114 return ERR_CONNECTION_CLOSED; | 147 return net_error_; |
| 115 | 148 |
| 116 int frame_len = 0; | 149 int frame_len = 0; |
| 117 if (stream_->DeliverInitialHeaders(header_block, &frame_len)) | 150 if (stream_->DeliverInitialHeaders(header_block, &frame_len)) |
| 118 return frame_len; | 151 return frame_len; |
| 119 | 152 |
| 120 read_headers_buffer_ = header_block; | 153 read_headers_buffer_ = header_block; |
| 121 read_headers_callback_ = callback; | 154 SetCallback(callback, &read_headers_callback_); |
| 122 return ERR_IO_PENDING; | 155 return ERR_IO_PENDING; |
| 123 } | 156 } |
| 124 | 157 |
| 125 int QuicChromiumClientStream::Handle::ReadBody( | 158 int QuicChromiumClientStream::Handle::ReadBody( |
| 126 IOBuffer* buffer, | 159 IOBuffer* buffer, |
| 127 int buffer_len, | 160 int buffer_len, |
| 128 const CompletionCallback& callback) { | 161 const CompletionCallback& callback) { |
| 162 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | |
| 163 if (IsDoneReading()) | |
| 164 return OK; | |
| 165 | |
| 129 if (!stream_) | 166 if (!stream_) |
| 130 return ERR_CONNECTION_CLOSED; | 167 return net_error_; |
| 131 | 168 |
| 132 int rv = stream_->Read(buffer, buffer_len); | 169 int rv = stream_->Read(buffer, buffer_len); |
| 133 if (rv != ERR_IO_PENDING) | 170 if (rv != ERR_IO_PENDING) |
| 134 return rv; | 171 return rv; |
| 135 | 172 |
| 136 read_body_callback_ = callback; | 173 SetCallback(callback, &read_body_callback_); |
| 137 read_body_buffer_ = buffer; | 174 read_body_buffer_ = buffer; |
| 138 read_body_buffer_len_ = buffer_len; | 175 read_body_buffer_len_ = buffer_len; |
| 139 return ERR_IO_PENDING; | 176 return ERR_IO_PENDING; |
| 140 } | 177 } |
| 141 | 178 |
| 142 int QuicChromiumClientStream::Handle::ReadTrailingHeaders( | 179 int QuicChromiumClientStream::Handle::ReadTrailingHeaders( |
| 143 SpdyHeaderBlock* header_block, | 180 SpdyHeaderBlock* header_block, |
| 144 const CompletionCallback& callback) { | 181 const CompletionCallback& callback) { |
| 182 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | |
| 145 if (!stream_) | 183 if (!stream_) |
| 146 return ERR_CONNECTION_CLOSED; | 184 return net_error_; |
| 147 | 185 |
| 148 int frame_len = 0; | 186 int frame_len = 0; |
| 149 if (stream_->DeliverTrailingHeaders(header_block, &frame_len)) | 187 if (stream_->DeliverTrailingHeaders(header_block, &frame_len)) |
| 150 return frame_len; | 188 return frame_len; |
| 151 | 189 |
| 152 read_headers_buffer_ = header_block; | 190 read_headers_buffer_ = header_block; |
| 153 read_headers_callback_ = callback; | 191 SetCallback(callback, &read_headers_callback_); |
| 154 return ERR_IO_PENDING; | 192 return ERR_IO_PENDING; |
| 155 } | 193 } |
| 156 | 194 |
| 157 size_t QuicChromiumClientStream::Handle::WriteHeaders( | 195 int QuicChromiumClientStream::Handle::WriteHeaders( |
| 158 SpdyHeaderBlock header_block, | 196 SpdyHeaderBlock header_block, |
| 159 bool fin, | 197 bool fin, |
| 160 QuicReferenceCountedPointer<QuicAckListenerInterface> | 198 QuicReferenceCountedPointer<QuicAckListenerInterface> |
| 161 ack_notifier_delegate) { | 199 ack_notifier_delegate) { |
| 162 if (!stream_) | 200 if (!stream_) |
| 163 return 0; | 201 return 0; |
| 164 return stream_->WriteHeaders(std::move(header_block), fin, | 202 return HandleIOComplete(stream_->WriteHeaders(std::move(header_block), fin, |
|
xunjieli
2017/05/31 00:25:22
Doesn't stream_->WriteHeaders() return a size_t ?
Ryan Hamilton
2017/05/31 02:49:56
What should we check?
| |
| 165 ack_notifier_delegate); | 203 ack_notifier_delegate)); |
| 166 } | 204 } |
| 167 | 205 |
| 168 int QuicChromiumClientStream::Handle::WriteStreamData( | 206 int QuicChromiumClientStream::Handle::WriteStreamData( |
| 169 base::StringPiece data, | 207 base::StringPiece data, |
| 170 bool fin, | 208 bool fin, |
| 171 const CompletionCallback& callback) { | 209 const CompletionCallback& callback) { |
| 210 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | |
| 172 if (!stream_) | 211 if (!stream_) |
| 173 return ERR_CONNECTION_CLOSED; | 212 return net_error_; |
| 174 | 213 |
| 175 if (stream_->WriteStreamData(data, fin)) | 214 if (stream_->WriteStreamData(data, fin)) |
| 176 return OK; | 215 return HandleIOComplete(OK); |
| 177 | 216 |
| 178 write_callback_ = callback; | 217 SetCallback(callback, &write_callback_); |
| 179 return ERR_IO_PENDING; | 218 return ERR_IO_PENDING; |
| 180 } | 219 } |
| 181 | 220 |
| 182 int QuicChromiumClientStream::Handle::WritevStreamData( | 221 int QuicChromiumClientStream::Handle::WritevStreamData( |
| 183 const std::vector<scoped_refptr<IOBuffer>>& buffers, | 222 const std::vector<scoped_refptr<IOBuffer>>& buffers, |
| 184 const std::vector<int>& lengths, | 223 const std::vector<int>& lengths, |
| 185 bool fin, | 224 bool fin, |
| 186 const CompletionCallback& callback) { | 225 const CompletionCallback& callback) { |
| 226 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | |
| 187 if (!stream_) | 227 if (!stream_) |
| 188 return ERR_CONNECTION_CLOSED; | 228 return net_error_; |
| 189 | 229 |
| 190 if (stream_->WritevStreamData(buffers, lengths, fin)) | 230 if (stream_->WritevStreamData(buffers, lengths, fin)) |
| 191 return OK; | 231 return HandleIOComplete(OK); |
| 192 | 232 |
| 193 write_callback_ = callback; | 233 SetCallback(callback, &write_callback_); |
| 194 return ERR_IO_PENDING; | 234 return ERR_IO_PENDING; |
| 195 } | 235 } |
| 196 | 236 |
| 197 int QuicChromiumClientStream::Handle::Read(IOBuffer* buf, int buf_len) { | 237 int QuicChromiumClientStream::Handle::Read(IOBuffer* buf, int buf_len) { |
| 198 if (!stream_) | 238 if (!stream_) |
| 199 return ERR_CONNECTION_CLOSED; | 239 return net_error_; |
| 200 return stream_->Read(buf, buf_len); | 240 return stream_->Read(buf, buf_len); |
| 201 } | 241 } |
| 202 | 242 |
| 203 void QuicChromiumClientStream::Handle::OnFinRead() { | 243 void QuicChromiumClientStream::Handle::OnFinRead() { |
| 244 read_headers_callback_.Reset(); | |
|
xunjieli
2017/05/31 00:25:22
Should we also reset the read trailers callback an
Ryan Hamilton
2017/05/31 02:49:56
There is no read trailers callback, only read_head
xunjieli
2017/06/01 15:30:32
Got it. Thanks for the details!
| |
| 204 if (stream_) | 245 if (stream_) |
| 205 stream_->OnFinRead(); | 246 stream_->OnFinRead(); |
| 206 } | 247 } |
| 207 | 248 |
| 208 void QuicChromiumClientStream::Handle::DisableConnectionMigration() { | 249 void QuicChromiumClientStream::Handle::DisableConnectionMigration() { |
| 209 if (stream_) | 250 if (stream_) |
| 210 stream_->DisableConnectionMigration(); | 251 stream_->DisableConnectionMigration(); |
| 211 } | 252 } |
| 212 | 253 |
| 213 void QuicChromiumClientStream::Handle::SetPriority(SpdyPriority priority) { | 254 void QuicChromiumClientStream::Handle::SetPriority(SpdyPriority priority) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 return priority_; | 334 return priority_; |
| 294 return stream_->priority(); | 335 return stream_->priority(); |
| 295 } | 336 } |
| 296 | 337 |
| 297 bool QuicChromiumClientStream::Handle::can_migrate() { | 338 bool QuicChromiumClientStream::Handle::can_migrate() { |
| 298 if (!stream_) | 339 if (!stream_) |
| 299 return false; | 340 return false; |
| 300 return stream_->can_migrate(); | 341 return stream_->can_migrate(); |
| 301 } | 342 } |
| 302 | 343 |
| 303 QuicChromiumClientStream::Delegate* | |
| 304 QuicChromiumClientStream::Handle::GetDelegate() { | |
| 305 return delegate_; | |
| 306 } | |
| 307 | |
| 308 void QuicChromiumClientStream::Handle::SaveState() { | 344 void QuicChromiumClientStream::Handle::SaveState() { |
| 309 DCHECK(stream_); | 345 DCHECK(stream_); |
| 310 fin_sent_ = stream_->fin_sent(); | 346 fin_sent_ = stream_->fin_sent(); |
| 311 fin_received_ = stream_->fin_received(); | 347 fin_received_ = stream_->fin_received(); |
| 312 num_bytes_consumed_ = stream_->sequencer()->NumBytesConsumed(); | 348 num_bytes_consumed_ = stream_->sequencer()->NumBytesConsumed(); |
| 313 id_ = stream_->id(); | 349 id_ = stream_->id(); |
| 314 connection_error_ = stream_->connection_error(); | 350 connection_error_ = stream_->connection_error(); |
| 315 stream_error_ = stream_->stream_error(); | 351 stream_error_ = stream_->stream_error(); |
| 316 is_done_reading_ = stream_->IsDoneReading(); | 352 is_done_reading_ = stream_->IsDoneReading(); |
| 317 is_first_stream_ = stream_->IsFirstStream(); | 353 is_first_stream_ = stream_->IsFirstStream(); |
| 318 stream_bytes_read_ = stream_->stream_bytes_read(); | 354 stream_bytes_read_ = stream_->stream_bytes_read(); |
| 319 stream_bytes_written_ = stream_->stream_bytes_written(); | 355 stream_bytes_written_ = stream_->stream_bytes_written(); |
| 320 priority_ = stream_->priority(); | 356 priority_ = stream_->priority(); |
| 321 } | 357 } |
| 322 | 358 |
| 359 void QuicChromiumClientStream::Handle::SetCallback( | |
| 360 CompletionCallback new_callback, | |
| 361 CompletionCallback* callback) { | |
| 362 CHECK(!may_invoke_callbacks_); | |
|
xunjieli
2017/05/31 00:25:22
Should we add a TODO to convert this CHECK to DCHE
Ryan Hamilton
2017/05/31 02:49:56
Done.
| |
| 363 *callback = new_callback; | |
| 364 } | |
| 365 | |
| 366 void QuicChromiumClientStream::Handle::ResetAndRun(CompletionCallback* callback, | |
| 367 int rv) { | |
| 368 CHECK(may_invoke_callbacks_); | |
| 369 ResetAndReturn(callback).Run(rv); | |
| 370 } | |
| 371 | |
| 372 int QuicChromiumClientStream::Handle::HandleIOComplete(int rv) { | |
| 373 if (rv < 0 || stream_) | |
|
xunjieli
2017/05/31 00:25:22
Why do we need the |stream_| check? Could you add
Ryan Hamilton
2017/05/31 02:49:56
If |stream_| is still valid the stream has not bee
| |
| 374 return rv; | |
| 375 | |
| 376 if (stream_error_ == QUIC_STREAM_NO_ERROR && | |
| 377 connection_error_ == QUIC_NO_ERROR && fin_sent_ && fin_received_) { | |
| 378 return rv; | |
| 379 } | |
| 380 | |
| 381 return net_error_; | |
| 382 } | |
| 383 | |
| 323 QuicChromiumClientStream::QuicChromiumClientStream( | 384 QuicChromiumClientStream::QuicChromiumClientStream( |
| 324 QuicStreamId id, | 385 QuicStreamId id, |
| 325 QuicClientSessionBase* session, | 386 QuicClientSessionBase* session, |
| 326 const NetLogWithSource& net_log) | 387 const NetLogWithSource& net_log) |
| 327 : QuicSpdyStream(id, session), | 388 : QuicSpdyStream(id, session), |
| 328 net_log_(net_log), | 389 net_log_(net_log), |
| 329 handle_(nullptr), | 390 handle_(nullptr), |
| 330 headers_delivered_(false), | 391 headers_delivered_(false), |
| 331 initial_headers_sent_(false), | 392 initial_headers_sent_(false), |
| 332 session_(session), | 393 session_(session), |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 // Writes the data, or buffers it. | 533 // Writes the data, or buffers it. |
| 473 for (size_t i = 0; i < buffers.size(); ++i) { | 534 for (size_t i = 0; i < buffers.size(); ++i) { |
| 474 bool is_fin = fin && (i == buffers.size() - 1); | 535 bool is_fin = fin && (i == buffers.size() - 1); |
| 475 QuicStringPiece string_data(buffers[i]->data(), lengths[i]); | 536 QuicStringPiece string_data(buffers[i]->data(), lengths[i]); |
| 476 WriteOrBufferData(string_data, is_fin, nullptr); | 537 WriteOrBufferData(string_data, is_fin, nullptr); |
| 477 } | 538 } |
| 478 return !HasBufferedData(); // Was all data written? | 539 return !HasBufferedData(); // Was all data written? |
| 479 } | 540 } |
| 480 | 541 |
| 481 std::unique_ptr<QuicChromiumClientStream::Handle> | 542 std::unique_ptr<QuicChromiumClientStream::Handle> |
| 482 QuicChromiumClientStream::CreateHandle( | 543 QuicChromiumClientStream::CreateHandle() { |
| 483 QuicChromiumClientStream::Delegate* delegate) { | |
| 484 DCHECK(!handle_); | 544 DCHECK(!handle_); |
| 485 auto handle = std::unique_ptr<QuicChromiumClientStream::Handle>( | 545 auto handle = std::unique_ptr<QuicChromiumClientStream::Handle>( |
| 486 new QuicChromiumClientStream::Handle(this, delegate)); | 546 new QuicChromiumClientStream::Handle(this)); |
| 487 handle_ = handle.get(); | 547 handle_ = handle.get(); |
| 488 | 548 |
| 489 // Should this perhaps be via PostTask to make reasoning simpler? | 549 // Should this perhaps be via PostTask to make reasoning simpler? |
| 490 if (!initial_headers_.empty()) | 550 if (!initial_headers_.empty()) |
| 491 handle_->OnInitialHeadersAvailable(); | 551 handle_->OnInitialHeadersAvailable(); |
| 492 | 552 |
| 493 return handle; | 553 return handle; |
| 494 } | 554 } |
| 495 | 555 |
| 496 void QuicChromiumClientStream::ClearHandle() { | 556 void QuicChromiumClientStream::ClearHandle() { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 base::Bind( | 605 base::Bind( |
| 546 &QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable, | 606 &QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable, |
| 547 weak_factory_.GetWeakPtr())); | 607 weak_factory_.GetWeakPtr())); |
| 548 } | 608 } |
| 549 | 609 |
| 550 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable() { | 610 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable() { |
| 551 if (!handle_) | 611 if (!handle_) |
| 552 return; | 612 return; |
| 553 | 613 |
| 554 DCHECK(headers_delivered_); | 614 DCHECK(headers_delivered_); |
| 555 // Post an async task to notify delegate of the FIN flag. | 615 // Post an async task to notify handle of the FIN flag. |
| 556 NotifyHandleOfDataAvailableLater(); | 616 NotifyHandleOfDataAvailableLater(); |
| 557 handle_->OnTrailingHeadersAvailable(); | 617 handle_->OnTrailingHeadersAvailable(); |
| 558 } | 618 } |
| 559 | 619 |
| 560 bool QuicChromiumClientStream::DeliverInitialHeaders(SpdyHeaderBlock* headers, | 620 bool QuicChromiumClientStream::DeliverInitialHeaders(SpdyHeaderBlock* headers, |
| 561 int* frame_len) { | 621 int* frame_len) { |
| 562 if (initial_headers_.empty()) | 622 if (initial_headers_.empty()) |
| 563 return false; | 623 return false; |
| 564 | 624 |
| 565 headers_delivered_ = true; | 625 headers_delivered_ = true; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 | 663 |
| 604 void QuicChromiumClientStream::DisableConnectionMigration() { | 664 void QuicChromiumClientStream::DisableConnectionMigration() { |
| 605 can_migrate_ = false; | 665 can_migrate_ = false; |
| 606 } | 666 } |
| 607 | 667 |
| 608 bool QuicChromiumClientStream::IsFirstStream() { | 668 bool QuicChromiumClientStream::IsFirstStream() { |
| 609 return id() == kHeadersStreamId + 2; | 669 return id() == kHeadersStreamId + 2; |
| 610 } | 670 } |
| 611 | 671 |
| 612 } // namespace net | 672 } // namespace net |
| OLD | NEW |