OLD | NEW |
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/quic_spdy_stream.h" | 5 #include "net/quic/quic_spdy_stream.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "net/quic/quic_bug_tracker.h" | 11 #include "net/quic/quic_bug_tracker.h" |
12 #include "net/quic/quic_spdy_session.h" | 12 #include "net/quic/quic_spdy_session.h" |
13 #include "net/quic/quic_utils.h" | 13 #include "net/quic/quic_utils.h" |
14 #include "net/quic/quic_write_blocked_list.h" | 14 #include "net/quic/quic_write_blocked_list.h" |
15 #include "net/quic/spdy_utils.h" | 15 #include "net/quic/spdy_utils.h" |
16 | 16 |
| 17 using base::IntToString; |
17 using base::StringPiece; | 18 using base::StringPiece; |
18 using net::SpdyPriority; | |
19 using std::min; | 19 using std::min; |
20 using std::string; | 20 using std::string; |
21 | 21 |
22 namespace net { | 22 namespace net { |
23 | 23 |
24 #define ENDPOINT \ | 24 #define ENDPOINT \ |
25 (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client:" \ | 25 (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client:" \ |
26 " ") | 26 " ") |
27 | 27 |
28 QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session) | 28 QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 QUIC_BUG << "Trailers cannot be sent after a FIN."; | 97 QUIC_BUG << "Trailers cannot be sent after a FIN."; |
98 return 0; | 98 return 0; |
99 } | 99 } |
100 | 100 |
101 // The header block must contain the final offset for this stream, as the | 101 // The header block must contain the final offset for this stream, as the |
102 // trailers may be processed out of order at the peer. | 102 // trailers may be processed out of order at the peer. |
103 DVLOG(1) << "Inserting trailer: (" << kFinalOffsetHeaderKey << ", " | 103 DVLOG(1) << "Inserting trailer: (" << kFinalOffsetHeaderKey << ", " |
104 << stream_bytes_written() + queued_data_bytes() << ")"; | 104 << stream_bytes_written() + queued_data_bytes() << ")"; |
105 trailer_block.insert(std::make_pair( | 105 trailer_block.insert(std::make_pair( |
106 kFinalOffsetHeaderKey, | 106 kFinalOffsetHeaderKey, |
107 base::IntToString(stream_bytes_written() + queued_data_bytes()))); | 107 IntToString(stream_bytes_written() + queued_data_bytes()))); |
108 | 108 |
109 // Write the trailing headers with a FIN, and close stream for writing: | 109 // Write the trailing headers with a FIN, and close stream for writing: |
110 // trailers are the last thing to be sent on a stream. | 110 // trailers are the last thing to be sent on a stream. |
111 const bool kFin = true; | 111 const bool kFin = true; |
112 size_t bytes_written = spdy_session_->WriteHeaders( | 112 size_t bytes_written = spdy_session_->WriteHeaders( |
113 id(), std::move(trailer_block), kFin, priority_, ack_notifier_delegate); | 113 id(), std::move(trailer_block), kFin, priority_, ack_notifier_delegate); |
114 set_fin_sent(kFin); | 114 set_fin_sent(kFin); |
115 | 115 |
116 // Trailers are the last thing to be sent on a stream, but if there is still | 116 // Trailers are the last thing to be sent on a stream, but if there is still |
117 // queued data then CloseWriteSide() will cause it never to be sent. | 117 // queued data then CloseWriteSide() will cause it never to be sent. |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 visitor_ = nullptr; | 354 visitor_ = nullptr; |
355 visitor->OnClose(this); | 355 visitor->OnClose(this); |
356 } | 356 } |
357 } | 357 } |
358 | 358 |
359 bool QuicSpdyStream::FinishedReadingHeaders() const { | 359 bool QuicSpdyStream::FinishedReadingHeaders() const { |
360 return headers_decompressed_ && decompressed_headers_.empty() && | 360 return headers_decompressed_ && decompressed_headers_.empty() && |
361 header_list_.empty(); | 361 header_list_.empty(); |
362 } | 362 } |
363 | 363 |
364 bool QuicSpdyStream::ParseHeaderStatusCode(SpdyHeaderBlock* header, | 364 bool QuicSpdyStream::ParseHeaderStatusCode(const SpdyHeaderBlock& header, |
365 int* status_code) const { | 365 int* status_code) const { |
366 StringPiece status = (*header)[":status"]; | 366 SpdyHeaderBlock::const_iterator it = header.find(":status"); |
| 367 if (it == header.end()) { |
| 368 return false; |
| 369 } |
| 370 const StringPiece status(it->second); |
367 if (status.size() != 3) { | 371 if (status.size() != 3) { |
368 return false; | 372 return false; |
369 } | 373 } |
370 // First character must be an integer in range [1,5]. | 374 // First character must be an integer in range [1,5]. |
371 if (status[0] < '1' || status[0] > '5') { | 375 if (status[0] < '1' || status[0] > '5') { |
372 return false; | 376 return false; |
373 } | 377 } |
374 // The remaining two characters must be integers. | 378 // The remaining two characters must be integers. |
375 if (!isdigit(status[1]) || !isdigit(status[2])) { | 379 if (!isdigit(status[1]) || !isdigit(status[2])) { |
376 return false; | 380 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
392 | 396 |
393 SpdyPriority QuicSpdyStream::priority() const { | 397 SpdyPriority QuicSpdyStream::priority() const { |
394 return priority_; | 398 return priority_; |
395 } | 399 } |
396 | 400 |
397 void QuicSpdyStream::ClearSession() { | 401 void QuicSpdyStream::ClearSession() { |
398 spdy_session_ = nullptr; | 402 spdy_session_ = nullptr; |
399 } | 403 } |
400 | 404 |
401 } // namespace net | 405 } // namespace net |
OLD | NEW |