| 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/tools/quic/quic_spdy_server_stream.h" | 5 #include "net/tools/quic/quic_spdy_server_stream.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 | 25 |
| 26 QuicSpdyServerStream::QuicSpdyServerStream(QuicStreamId id, | 26 QuicSpdyServerStream::QuicSpdyServerStream(QuicStreamId id, |
| 27 QuicSpdySession* session) | 27 QuicSpdySession* session) |
| 28 : QuicSpdyStream(id, session), content_length_(-1) {} | 28 : QuicSpdyStream(id, session), content_length_(-1) {} |
| 29 | 29 |
| 30 QuicSpdyServerStream::~QuicSpdyServerStream() { | 30 QuicSpdyServerStream::~QuicSpdyServerStream() { |
| 31 } | 31 } |
| 32 | 32 |
| 33 void QuicSpdyServerStream::OnStreamHeadersComplete(bool fin, size_t frame_len) { | 33 void QuicSpdyServerStream::OnStreamHeadersComplete(bool fin, size_t frame_len) { |
| 34 QuicSpdyStream::OnStreamHeadersComplete(fin, frame_len); | 34 QuicSpdyStream::OnStreamHeadersComplete(fin, frame_len); |
| 35 if (!ParseRequestHeaders(decompressed_headers().data(), | 35 if (!SpdyUtils::ParseHeaders(decompressed_headers().data(), |
| 36 decompressed_headers().length())) { | 36 decompressed_headers().length(), |
| 37 &content_length_, &request_headers_)) { |
| 37 DVLOG(1) << "Invalid headers"; | 38 DVLOG(1) << "Invalid headers"; |
| 38 SendErrorResponse(); | 39 SendErrorResponse(); |
| 39 } | 40 } |
| 40 MarkHeadersConsumed(decompressed_headers().length()); | 41 MarkHeadersConsumed(decompressed_headers().length()); |
| 41 } | 42 } |
| 42 | 43 |
| 43 void QuicSpdyServerStream::OnDataAvailable() { | 44 void QuicSpdyServerStream::OnDataAvailable() { |
| 44 while (HasBytesToRead()) { | 45 while (HasBytesToRead()) { |
| 45 struct iovec iov; | 46 struct iovec iov; |
| 46 if (GetReadableRegions(&iov, 1) == 0) { | 47 if (GetReadableRegions(&iov, 1) == 0) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 content_length_ != static_cast<int>(body_.size())) { | 83 content_length_ != static_cast<int>(body_.size())) { |
| 83 DVLOG(1) << "Content length (" << content_length_ << ") != body size (" | 84 DVLOG(1) << "Content length (" << content_length_ << ") != body size (" |
| 84 << body_.size() << ")."; | 85 << body_.size() << ")."; |
| 85 SendErrorResponse(); | 86 SendErrorResponse(); |
| 86 return; | 87 return; |
| 87 } | 88 } |
| 88 | 89 |
| 89 SendResponse(); | 90 SendResponse(); |
| 90 } | 91 } |
| 91 | 92 |
| 92 bool QuicSpdyServerStream::ParseRequestHeaders(const char* data, | |
| 93 uint32 data_len) { | |
| 94 DCHECK(headers_decompressed()); | |
| 95 SpdyFramer framer(HTTP2); | |
| 96 if (!framer.ParseHeaderBlockInBuffer(data, data_len, &request_headers_) || | |
| 97 request_headers_.empty()) { | |
| 98 return false; // Headers were invalid. | |
| 99 } | |
| 100 | |
| 101 if (ContainsKey(request_headers_, "content-length")) { | |
| 102 string delimiter; | |
| 103 delimiter.push_back('\0'); | |
| 104 std::vector<string> values = | |
| 105 base::SplitString(request_headers_["content-length"], delimiter, | |
| 106 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 107 | |
| 108 for (const string& value : values) { | |
| 109 int new_value; | |
| 110 if (!StringToInt(value, &new_value) || new_value < 0) { | |
| 111 return false; | |
| 112 } | |
| 113 if (content_length_ < 0) { | |
| 114 content_length_ = new_value; | |
| 115 continue; | |
| 116 } | |
| 117 if (new_value != content_length_) { | |
| 118 return false; | |
| 119 } | |
| 120 } | |
| 121 } | |
| 122 | |
| 123 return true; | |
| 124 } | |
| 125 | |
| 126 void QuicSpdyServerStream::SendResponse() { | 93 void QuicSpdyServerStream::SendResponse() { |
| 127 if (!ContainsKey(request_headers_, ":authority") || | 94 if (!ContainsKey(request_headers_, ":authority") || |
| 128 !ContainsKey(request_headers_, ":path")) { | 95 !ContainsKey(request_headers_, ":path")) { |
| 129 DVLOG(1) << "Request headers do not contain :authority or :path."; | 96 DVLOG(1) << "Request headers do not contain :authority or :path."; |
| 130 SendErrorResponse(); | 97 SendErrorResponse(); |
| 131 return; | 98 return; |
| 132 } | 99 } |
| 133 | 100 |
| 134 // Find response in cache. If not found, send error response. | 101 // Find response in cache. If not found, send error response. |
| 135 const QuicInMemoryCache::Response* response = | 102 const QuicInMemoryCache::Response* response = |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 | 171 |
| 205 if (!body.empty()) { | 172 if (!body.empty()) { |
| 206 WriteOrBufferData(body, true, nullptr); | 173 WriteOrBufferData(body, true, nullptr); |
| 207 } | 174 } |
| 208 } | 175 } |
| 209 | 176 |
| 210 const char* const QuicSpdyServerStream::kErrorResponseBody = "bad"; | 177 const char* const QuicSpdyServerStream::kErrorResponseBody = "bad"; |
| 211 | 178 |
| 212 } // namespace tools | 179 } // namespace tools |
| 213 } // namespace net | 180 } // namespace net |
| OLD | NEW |