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

Side by Side Diff: net/quic/core/quic_headers_stream.cc

Issue 2547583002: Landing Recent QUIC changes until Fri Nov 18 23:21:04 2016 +0000 (Closed)
Patch Set: Remove explicit HTTP/2 enum usage Created 4 years 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
« no previous file with comments | « net/quic/core/quic_headers_stream.h ('k') | net/quic/core/quic_headers_stream_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/core/quic_headers_stream.h" 5 #include "net/quic/core/quic_headers_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 362
363 // PUSH_PROMISE must not be the last frame sent out, at least followed by 363 // PUSH_PROMISE must not be the last frame sent out, at least followed by
364 // response headers. 364 // response headers.
365 push_promise.set_fin(false); 365 push_promise.set_fin(false);
366 366
367 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); 367 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
368 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, nullptr); 368 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, nullptr);
369 return frame.size(); 369 return frame.size();
370 } 370 }
371 371
372 void QuicHeadersStream::WriteDataFrame(
373 QuicStreamId id,
374 StringPiece data,
375 bool fin,
376 QuicAckListenerInterface* ack_notifier_delegate) {
377 SpdyDataIR spdy_data(id, data);
378 spdy_data.set_fin(fin);
379 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data));
380 scoped_refptr<ForceHolAckListener> ack_listener;
381 if (ack_notifier_delegate != nullptr) {
382 ack_listener = new ForceHolAckListener(ack_notifier_delegate,
383 frame.size() - data.length());
384 }
385 // Use buffered writes so that coherence of framing is preserved
386 // between streams.
387 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
388 ack_listener.get());
389 }
390
372 QuicConsumedData QuicHeadersStream::WritevStreamData( 391 QuicConsumedData QuicHeadersStream::WritevStreamData(
373 QuicStreamId id, 392 QuicStreamId id,
374 QuicIOVector iov, 393 QuicIOVector iov,
375 QuicStreamOffset offset, 394 QuicStreamOffset offset,
376 bool fin, 395 bool fin,
377 QuicAckListenerInterface* ack_notifier_delegate) { 396 QuicAckListenerInterface* ack_notifier_delegate) {
378 const size_t max_len = 397 const size_t max_len =
379 kSpdyInitialFrameSizeLimit - SpdyConstants::kDataFrameMinimumSize; 398 kSpdyInitialFrameSizeLimit - SpdyConstants::kDataFrameMinimumSize;
380 399
381 QuicConsumedData result(0, false); 400 QuicConsumedData result(0, false);
382 size_t total_length = iov.total_length; 401 size_t total_length = iov.total_length;
383 402
384 // Encapsulate the data into HTTP/2 DATA frames. The outer loop 403 if (!FLAGS_quic_bugfix_fhol_writev_fin_only_v2) {
385 // handles each element of the source iov, the inner loop handles 404 // Encapsulate the data into HTTP/2 DATA frames. The outer loop
386 // the possibility of fragmenting eacho of those into multiple DATA 405 // handles each element of the source iov, the inner loop handles
387 // frames, as the DATA frames have a max size of 16KB. 406 // the possibility of fragmenting eacho of those into multiple DATA
388 for (int i = 0; i < iov.iov_count; i++) { 407 // frames, as the DATA frames have a max size of 16KB.
389 size_t offset = 0; 408 for (int i = 0; i < iov.iov_count; i++) {
390 const struct iovec* src_iov = &iov.iov[i]; 409 size_t offset = 0;
391 do { 410 const struct iovec* src_iov = &iov.iov[i];
392 size_t len = 411 do {
393 std::min(std::min(src_iov->iov_len - offset, max_len), total_length); 412 size_t len = std::min(std::min(src_iov->iov_len - offset, max_len),
394 char* data = static_cast<char*>(src_iov->iov_base) + offset; 413 total_length);
395 SpdyDataIR spdy_data(id, StringPiece(data, len)); 414 char* data = static_cast<char*>(src_iov->iov_base) + offset;
396 offset += len; 415 SpdyDataIR spdy_data(id, StringPiece(data, len));
397 // fin handling, set it only it only very last generated HTTP/2 416 offset += len;
398 // DATA frame. 417 // fin handling, only set it for the final HTTP/2 DATA frame.
399 bool last_iov = i == iov.iov_count - 1; 418 bool last_iov = i == iov.iov_count - 1;
400 bool last_fragment_within_iov = offset >= src_iov->iov_len; 419 bool last_fragment_within_iov = offset >= src_iov->iov_len;
401 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false; 420 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false;
402 spdy_data.set_fin(frame_fin); 421 spdy_data.set_fin(frame_fin);
403 if (frame_fin) { 422 if (frame_fin) {
404 result.fin_consumed = true; 423 result.fin_consumed = true;
405 } 424 }
406 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data)); 425 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data));
407 DVLOG(1) << "Encapsulating in DATA frame for stream " << id << " len " 426 DVLOG(1) << "Encapsulating in DATA frame for stream " << id << " len "
408 << len << " fin " << spdy_data.fin() << " remaining " 427 << len << " fin " << spdy_data.fin() << " remaining "
409 << src_iov->iov_len - offset; 428 << src_iov->iov_len - offset;
410 429
411 scoped_refptr<ForceHolAckListener> ack_listener; 430 scoped_refptr<ForceHolAckListener> ack_listener;
412 if (ack_notifier_delegate != nullptr) { 431 if (ack_notifier_delegate != nullptr) {
413 ack_listener = 432 ack_listener = new ForceHolAckListener(ack_notifier_delegate,
414 new ForceHolAckListener(ack_notifier_delegate, frame.size() - len); 433 frame.size() - len);
415 } 434 }
416 435
417 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, 436 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
418 ack_listener.get()); 437 ack_listener.get());
419 result.bytes_consumed += len; 438 result.bytes_consumed += len;
420 total_length -= len; 439 total_length -= len;
421 if (total_length <= 0) { 440 if (total_length <= 0) {
422 return result; 441 return result;
423 } 442 }
424 } while (offset < src_iov->iov_len); 443 } while (offset < src_iov->iov_len);
444 }
445 } else {
446 if (total_length == 0 && fin) {
447 WriteDataFrame(id, StringPiece(), true, ack_notifier_delegate);
448 result.fin_consumed = true;
449 return result;
450 }
451
452 // Encapsulate the data into HTTP/2 DATA frames. The outer loop
453 // handles each element of the source iov, the inner loop handles
454 // the possibility of fragmenting each of those into multiple DATA
455 // frames, as the DATA frames have a max size of 16KB.
456 for (int i = 0; i < iov.iov_count; i++) {
457 size_t src_iov_offset = 0;
458 const struct iovec* src_iov = &iov.iov[i];
459 do {
460 if (queued_data_bytes() > 0) {
461 // Limit the amount of buffering to the minimum needed to
462 // preserve framing.
463 return result;
464 }
465 size_t len = std::min(
466 std::min(src_iov->iov_len - src_iov_offset, max_len), total_length);
467 char* data = static_cast<char*>(src_iov->iov_base) + src_iov_offset;
468 src_iov_offset += len;
469 offset += len;
470 // fin handling, only set it for the final HTTP/2 DATA frame.
471 bool last_iov = i == iov.iov_count - 1;
472 bool last_fragment_within_iov = src_iov_offset >= src_iov->iov_len;
473 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false;
474 WriteDataFrame(id, StringPiece(data, len), frame_fin,
475 ack_notifier_delegate);
476 result.bytes_consumed += len;
477 if (frame_fin) {
478 result.fin_consumed = true;
479 }
480 DCHECK_GE(total_length, len);
481 total_length -= len;
482 if (total_length <= 0) {
483 return result;
484 }
485 } while (src_iov_offset < src_iov->iov_len);
486 }
425 } 487 }
488
426 return result; 489 return result;
427 } 490 }
428 491
429 void QuicHeadersStream::OnDataAvailable() { 492 void QuicHeadersStream::OnDataAvailable() {
430 char buffer[1024]; 493 char buffer[1024];
431 struct iovec iov; 494 struct iovec iov;
432 QuicTime timestamp(QuicTime::Zero()); 495 QuicTime timestamp(QuicTime::Zero());
433 while (true) { 496 while (true) {
434 iov.iov_base = buffer; 497 iov.iov_base = buffer;
435 iov.iov_len = arraysize(buffer); 498 iov.iov_len = arraysize(buffer);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 return true; 653 return true;
591 } 654 }
592 frame_len_ -= len; 655 frame_len_ -= len;
593 // Ignore fin_ while there is more data coming, if frame_len_ > 0. 656 // Ignore fin_ while there is more data coming, if frame_len_ > 0.
594 spdy_session_->OnStreamFrameData(stream_id, data, len, 657 spdy_session_->OnStreamFrameData(stream_id, data, len,
595 frame_len_ > 0 ? false : fin_); 658 frame_len_ > 0 ? false : fin_);
596 return true; 659 return true;
597 } 660 }
598 661
599 } // namespace net 662 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_headers_stream.h ('k') | net/quic/core/quic_headers_stream_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698