| 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" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 ConsumeHeaderList(); | 53 ConsumeHeaderList(); |
| 54 Reset(QUIC_BAD_APPLICATION_PAYLOAD); | 54 Reset(QUIC_BAD_APPLICATION_PAYLOAD); |
| 55 return; | 55 return; |
| 56 } | 56 } |
| 57 | 57 |
| 58 ConsumeHeaderList(); | 58 ConsumeHeaderList(); |
| 59 session_->OnInitialHeadersComplete(id(), header_block); | 59 session_->OnInitialHeadersComplete(id(), header_block); |
| 60 | 60 |
| 61 if (delegate_) { | 61 if (delegate_) { |
| 62 // The delegate will receive the headers via a posted task. | 62 // The delegate will receive the headers via a posted task. |
| 63 NotifyDelegateOfHeadersCompleteLater(std::move(header_block), frame_len); | 63 NotifyDelegateOfInitialHeadersAvailableLater(std::move(header_block), |
| 64 frame_len); |
| 64 return; | 65 return; |
| 65 } | 66 } |
| 66 | 67 |
| 67 // Buffer the headers and deliver them when the delegate arrives. | 68 // Buffer the headers and deliver them when the delegate arrives. |
| 68 initial_headers_ = std::move(header_block); | 69 initial_headers_ = std::move(header_block); |
| 69 initial_headers_frame_len_ = frame_len; | 70 initial_headers_frame_len_ = frame_len; |
| 70 } | 71 } |
| 71 | 72 |
| 72 void QuicChromiumClientStream::OnTrailingHeadersComplete( | 73 void QuicChromiumClientStream::OnTrailingHeadersComplete( |
| 73 bool fin, | 74 bool fin, |
| 74 size_t frame_len, | 75 size_t frame_len, |
| 75 const QuicHeaderList& header_list) { | 76 const QuicHeaderList& header_list) { |
| 76 QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list); | 77 QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list); |
| 77 NotifyDelegateOfHeadersCompleteLater(received_trailers().Clone(), frame_len); | 78 NotifyDelegateOfTrailingHeadersAvailableLater(received_trailers().Clone(), |
| 79 frame_len); |
| 78 } | 80 } |
| 79 | 81 |
| 80 void QuicChromiumClientStream::OnPromiseHeaderList( | 82 void QuicChromiumClientStream::OnPromiseHeaderList( |
| 81 QuicStreamId promised_id, | 83 QuicStreamId promised_id, |
| 82 size_t frame_len, | 84 size_t frame_len, |
| 83 const QuicHeaderList& header_list) { | 85 const QuicHeaderList& header_list) { |
| 84 SpdyHeaderBlock promise_headers; | 86 SpdyHeaderBlock promise_headers; |
| 85 int64_t content_length = -1; | 87 int64_t content_length = -1; |
| 86 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length, | 88 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length, |
| 87 &promise_headers)) { | 89 &promise_headers)) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 | 194 |
| 193 void QuicChromiumClientStream::SetDelegate( | 195 void QuicChromiumClientStream::SetDelegate( |
| 194 QuicChromiumClientStream::Delegate* delegate) { | 196 QuicChromiumClientStream::Delegate* delegate) { |
| 195 DCHECK(!(delegate_ && delegate)); | 197 DCHECK(!(delegate_ && delegate)); |
| 196 delegate_ = delegate; | 198 delegate_ = delegate; |
| 197 if (delegate == nullptr) | 199 if (delegate == nullptr) |
| 198 return; | 200 return; |
| 199 | 201 |
| 200 // Should this perhaps be via PostTask to make reasoning simpler? | 202 // Should this perhaps be via PostTask to make reasoning simpler? |
| 201 if (!initial_headers_.empty()) { | 203 if (!initial_headers_.empty()) { |
| 202 delegate_->OnHeadersAvailable(std::move(initial_headers_), | 204 delegate_->OnInitialHeadersAvailable(std::move(initial_headers_), |
| 203 initial_headers_frame_len_); | 205 initial_headers_frame_len_); |
| 204 } | 206 } |
| 205 } | 207 } |
| 206 | 208 |
| 207 void QuicChromiumClientStream::OnError(int error) { | 209 void QuicChromiumClientStream::OnError(int error) { |
| 208 if (delegate_) { | 210 if (delegate_) { |
| 209 QuicChromiumClientStream::Delegate* delegate = delegate_; | 211 QuicChromiumClientStream::Delegate* delegate = delegate_; |
| 210 delegate_ = nullptr; | 212 delegate_ = nullptr; |
| 211 delegate->OnError(error); | 213 delegate->OnError(error); |
| 212 } | 214 } |
| 213 } | 215 } |
| 214 | 216 |
| 215 int QuicChromiumClientStream::Read(IOBuffer* buf, int buf_len) { | 217 int QuicChromiumClientStream::Read(IOBuffer* buf, int buf_len) { |
| 216 if (IsDoneReading()) | 218 if (IsDoneReading()) |
| 217 return 0; // EOF | 219 return 0; // EOF |
| 218 | 220 |
| 219 if (!HasBytesToRead()) | 221 if (!HasBytesToRead()) |
| 220 return ERR_IO_PENDING; | 222 return ERR_IO_PENDING; |
| 221 | 223 |
| 222 iovec iov; | 224 iovec iov; |
| 223 iov.iov_base = buf->data(); | 225 iov.iov_base = buf->data(); |
| 224 iov.iov_len = buf_len; | 226 iov.iov_len = buf_len; |
| 225 size_t bytes_read = Readv(&iov, 1); | 227 size_t bytes_read = Readv(&iov, 1); |
| 226 // Since HasBytesToRead is true, Readv() must of read some data. | 228 // Since HasBytesToRead is true, Readv() must of read some data. |
| 227 DCHECK_NE(0u, bytes_read); | 229 DCHECK_NE(0u, bytes_read); |
| 228 return bytes_read; | 230 return bytes_read; |
| 229 } | 231 } |
| 230 | 232 |
| 231 void QuicChromiumClientStream::NotifyDelegateOfHeadersCompleteLater( | 233 void QuicChromiumClientStream::NotifyDelegateOfInitialHeadersAvailableLater( |
| 232 SpdyHeaderBlock headers, | 234 SpdyHeaderBlock headers, |
| 233 size_t frame_len) { | 235 size_t frame_len) { |
| 234 DCHECK(delegate_); | 236 DCHECK(delegate_); |
| 235 base::ThreadTaskRunnerHandle::Get()->PostTask( | 237 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 236 FROM_HERE, | 238 FROM_HERE, |
| 237 base::Bind(&QuicChromiumClientStream::NotifyDelegateOfHeadersComplete, | 239 base::Bind( |
| 238 weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)), | 240 &QuicChromiumClientStream::NotifyDelegateOfInitialHeadersAvailable, |
| 239 frame_len)); | 241 weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)), |
| 242 frame_len)); |
| 240 } | 243 } |
| 241 | 244 |
| 242 void QuicChromiumClientStream::NotifyDelegateOfHeadersComplete( | 245 void QuicChromiumClientStream::NotifyDelegateOfInitialHeadersAvailable( |
| 243 SpdyHeaderBlock headers, | 246 SpdyHeaderBlock headers, |
| 244 size_t frame_len) { | 247 size_t frame_len) { |
| 245 if (!delegate_) | 248 if (!delegate_) |
| 246 return; | 249 return; |
| 250 |
| 251 DCHECK(!headers_delivered_); |
| 252 headers_delivered_ = true; |
| 253 net_log_.AddEvent( |
| 254 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS, |
| 255 base::Bind(&SpdyHeaderBlockNetLogCallback, &headers)); |
| 256 |
| 257 delegate_->OnInitialHeadersAvailable(headers, frame_len); |
| 258 } |
| 259 |
| 260 void QuicChromiumClientStream::NotifyDelegateOfTrailingHeadersAvailableLater( |
| 261 SpdyHeaderBlock headers, |
| 262 size_t frame_len) { |
| 263 DCHECK(delegate_); |
| 264 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 265 FROM_HERE, |
| 266 base::Bind( |
| 267 &QuicChromiumClientStream::NotifyDelegateOfTrailingHeadersAvailable, |
| 268 weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)), |
| 269 frame_len)); |
| 270 } |
| 271 |
| 272 void QuicChromiumClientStream::NotifyDelegateOfTrailingHeadersAvailable( |
| 273 SpdyHeaderBlock headers, |
| 274 size_t frame_len) { |
| 275 if (!delegate_) |
| 276 return; |
| 277 |
| 278 DCHECK(headers_delivered_); |
| 247 // Only mark trailers consumed when we are about to notify delegate. | 279 // Only mark trailers consumed when we are about to notify delegate. |
| 248 if (headers_delivered_) { | 280 MarkTrailersConsumed(); |
| 249 MarkTrailersConsumed(); | 281 // Post an async task to notify delegate of the FIN flag. |
| 250 // Post an async task to notify delegate of the FIN flag. | 282 NotifyDelegateOfDataAvailableLater(); |
| 251 NotifyDelegateOfDataAvailableLater(); | 283 net_log_.AddEvent( |
| 252 net_log_.AddEvent( | 284 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS, |
| 253 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS, | 285 base::Bind(&SpdyHeaderBlockNetLogCallback, &headers)); |
| 254 base::Bind(&SpdyHeaderBlockNetLogCallback, &headers)); | |
| 255 } else { | |
| 256 headers_delivered_ = true; | |
| 257 net_log_.AddEvent( | |
| 258 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS, | |
| 259 base::Bind(&SpdyHeaderBlockNetLogCallback, &headers)); | |
| 260 } | |
| 261 | 286 |
| 262 delegate_->OnHeadersAvailable(headers, frame_len); | 287 delegate_->OnTrailingHeadersAvailable(headers, frame_len); |
| 263 } | 288 } |
| 264 | 289 |
| 265 void QuicChromiumClientStream::NotifyDelegateOfDataAvailableLater() { | 290 void QuicChromiumClientStream::NotifyDelegateOfDataAvailableLater() { |
| 266 DCHECK(delegate_); | 291 DCHECK(delegate_); |
| 267 base::ThreadTaskRunnerHandle::Get()->PostTask( | 292 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 268 FROM_HERE, | 293 FROM_HERE, |
| 269 base::Bind(&QuicChromiumClientStream::NotifyDelegateOfDataAvailable, | 294 base::Bind(&QuicChromiumClientStream::NotifyDelegateOfDataAvailable, |
| 270 weak_factory_.GetWeakPtr())); | 295 weak_factory_.GetWeakPtr())); |
| 271 } | 296 } |
| 272 | 297 |
| 273 void QuicChromiumClientStream::NotifyDelegateOfDataAvailable() { | 298 void QuicChromiumClientStream::NotifyDelegateOfDataAvailable() { |
| 274 if (delegate_) | 299 if (delegate_) |
| 275 delegate_->OnDataAvailable(); | 300 delegate_->OnDataAvailable(); |
| 276 } | 301 } |
| 277 | 302 |
| 278 void QuicChromiumClientStream::DisableConnectionMigration() { | 303 void QuicChromiumClientStream::DisableConnectionMigration() { |
| 279 can_migrate_ = false; | 304 can_migrate_ = false; |
| 280 } | 305 } |
| 281 | 306 |
| 282 bool QuicChromiumClientStream::IsFirstStream() { | 307 bool QuicChromiumClientStream::IsFirstStream() { |
| 283 return id() == kHeadersStreamId + 2; | 308 return id() == kHeadersStreamId + 2; |
| 284 } | 309 } |
| 285 | 310 |
| 286 } // namespace net | 311 } // namespace net |
| OLD | NEW |