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_simple_server_stream.h" | 5 #include "net/tools/quic/quic_simple_server_stream.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "net/tools/quic/quic_simple_server_session.h" | 21 #include "net/tools/quic/quic_simple_server_session.h" |
22 | 22 |
23 using base::StringPiece; | 23 using base::StringPiece; |
24 using base::StringToInt; | 24 using base::StringToInt; |
25 using std::string; | 25 using std::string; |
26 | 26 |
27 namespace net { | 27 namespace net { |
28 | 28 |
29 QuicSimpleServerStream::QuicSimpleServerStream(QuicStreamId id, | 29 QuicSimpleServerStream::QuicSimpleServerStream(QuicStreamId id, |
30 QuicSpdySession* session) | 30 QuicSpdySession* session) |
31 : QuicSpdyStream(id, session), content_length_(-1) {} | 31 : QuicSpdyStream(id, session), |
| 32 content_length_(-1), |
| 33 response_started_(false) {} |
32 | 34 |
33 QuicSimpleServerStream::~QuicSimpleServerStream() {} | 35 QuicSimpleServerStream::~QuicSimpleServerStream() {} |
34 | 36 |
35 void QuicSimpleServerStream::OnInitialHeadersComplete(bool fin, | 37 void QuicSimpleServerStream::OnInitialHeadersComplete(bool fin, |
36 size_t frame_len) { | 38 size_t frame_len) { |
37 QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len); | 39 QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len); |
38 if (!SpdyUtils::ParseHeaders(decompressed_headers().data(), | 40 if (!SpdyUtils::ParseHeaders(decompressed_headers().data(), |
39 decompressed_headers().length(), | 41 decompressed_headers().length(), |
40 &content_length_, &request_headers_)) { | 42 &content_length_, &request_headers_)) { |
41 DVLOG(1) << "Invalid headers"; | 43 DVLOG(1) << "Invalid headers"; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 } | 98 } |
97 | 99 |
98 // If the sequencer is closed, then all the body, including the fin, has been | 100 // If the sequencer is closed, then all the body, including the fin, has been |
99 // consumed. | 101 // consumed. |
100 OnFinRead(); | 102 OnFinRead(); |
101 | 103 |
102 if (write_side_closed() || fin_buffered()) { | 104 if (write_side_closed() || fin_buffered()) { |
103 return; | 105 return; |
104 } | 106 } |
105 | 107 |
106 if (request_headers_.empty()) { | 108 // Subclass could have manually invoked SendResponse earlier. |
107 DVLOG(1) << "Request headers empty."; | 109 if (!response_started_) { |
108 SendErrorResponse(); | 110 SendResponse(); |
109 return; | |
110 } | 111 } |
111 | |
112 if (content_length_ > 0 && | |
113 static_cast<uint64_t>(content_length_) != body_.size()) { | |
114 DVLOG(1) << "Content length (" << content_length_ << ") != body size (" | |
115 << body_.size() << ")."; | |
116 SendErrorResponse(); | |
117 return; | |
118 } | |
119 | |
120 SendResponse(); | |
121 } | 112 } |
122 | 113 |
123 void QuicSimpleServerStream::PushResponse( | 114 void QuicSimpleServerStream::PushResponse( |
124 SpdyHeaderBlock push_request_headers) { | 115 SpdyHeaderBlock push_request_headers) { |
125 if (id() % 2 != 0) { | 116 if (id() % 2 != 0) { |
126 QUIC_BUG << "Client initiated stream shouldn't be used as promised stream."; | 117 QUIC_BUG << "Client initiated stream shouldn't be used as promised stream."; |
127 return; | 118 return; |
128 } | 119 } |
129 // Change the stream state to emulate a client request. | 120 // Change the stream state to emulate a client request. |
130 request_headers_ = std::move(push_request_headers); | 121 request_headers_ = std::move(push_request_headers); |
131 content_length_ = 0; | 122 content_length_ = 0; |
132 DVLOG(1) << "Stream " << id() << ": Ready to receive server push response."; | 123 DVLOG(1) << "Stream " << id() << ": Ready to receive server push response."; |
133 | 124 |
134 // Set as if stream decompresed the headers and received fin. | 125 // Set as if stream decompresed the headers and received fin. |
135 QuicSpdyStream::OnInitialHeadersComplete(/*fin=*/true, 0); | 126 QuicSpdyStream::OnInitialHeadersComplete(/*fin=*/true, 0); |
136 } | 127 } |
137 | 128 |
138 void QuicSimpleServerStream::SendResponse() { | 129 void QuicSimpleServerStream::SendResponse() { |
| 130 DCHECK(!response_started_); |
| 131 response_started_ = true; |
| 132 |
| 133 if (request_headers_.empty()) { |
| 134 DVLOG(1) << "Request headers empty."; |
| 135 SendErrorResponse(); |
| 136 return; |
| 137 } |
| 138 |
| 139 if (content_length_ > 0 && |
| 140 static_cast<uint64_t>(content_length_) != body_.size()) { |
| 141 DVLOG(1) << "Content length (" << content_length_ << ") != body size (" |
| 142 << body_.size() << ")."; |
| 143 SendErrorResponse(); |
| 144 return; |
| 145 } |
| 146 |
139 if (!base::ContainsKey(request_headers_, ":authority") || | 147 if (!base::ContainsKey(request_headers_, ":authority") || |
140 !base::ContainsKey(request_headers_, ":path")) { | 148 !base::ContainsKey(request_headers_, ":path")) { |
141 DVLOG(1) << "Request headers do not contain :authority or :path."; | 149 DVLOG(1) << "Request headers do not contain :authority or :path."; |
142 SendErrorResponse(); | 150 SendErrorResponse(); |
143 return; | 151 return; |
144 } | 152 } |
145 | 153 |
146 // Find response in cache. If not found, send error response. | 154 // Find response in cache. If not found, send error response. |
147 const QuicInMemoryCache::Response* response = | 155 const QuicInMemoryCache::Response* response = |
148 QuicInMemoryCache::GetInstance()->GetResponse( | 156 QuicInMemoryCache::GetInstance()->GetResponse( |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 DVLOG(1) << "Writing trailers (fin = true): " | 272 DVLOG(1) << "Writing trailers (fin = true): " |
265 << response_trailers.DebugString(); | 273 << response_trailers.DebugString(); |
266 WriteTrailers(std::move(response_trailers), nullptr); | 274 WriteTrailers(std::move(response_trailers), nullptr); |
267 } | 275 } |
268 | 276 |
269 const char* const QuicSimpleServerStream::kErrorResponseBody = "bad"; | 277 const char* const QuicSimpleServerStream::kErrorResponseBody = "bad"; |
270 const char* const QuicSimpleServerStream::kNotFoundResponseBody = | 278 const char* const QuicSimpleServerStream::kNotFoundResponseBody = |
271 "file not found"; | 279 "file not found"; |
272 | 280 |
273 } // namespace net | 281 } // namespace net |
OLD | NEW |