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 "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" |
11 #include "base/strings/string_split.h" | 11 #include "base/strings/string_split.h" |
12 #include "net/quic/quic_flags.h" | 12 #include "net/quic/quic_flags.h" |
13 #include "net/quic/quic_spdy_session.h" | |
14 #include "net/quic/quic_spdy_stream.h" | 13 #include "net/quic/quic_spdy_stream.h" |
15 #include "net/quic/spdy_utils.h" | 14 #include "net/quic/spdy_utils.h" |
16 #include "net/spdy/spdy_protocol.h" | 15 #include "net/spdy/spdy_protocol.h" |
17 #include "net/tools/quic/quic_in_memory_cache.h" | 16 #include "net/tools/quic/quic_in_memory_cache.h" |
| 17 #include "net/tools/quic/quic_simple_server_session.h" |
18 | 18 |
19 using base::StringPiece; | 19 using base::StringPiece; |
20 using base::StringToInt; | 20 using base::StringToInt; |
21 using std::string; | 21 using std::string; |
22 | 22 |
23 namespace net { | 23 namespace net { |
24 namespace tools { | 24 namespace tools { |
25 | 25 |
26 QuicSimpleServerStream::QuicSimpleServerStream(QuicStreamId id, | 26 QuicSimpleServerStream::QuicSimpleServerStream(QuicStreamId id, |
27 QuicSpdySession* session) | 27 QuicSpdySession* session) |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 return; | 136 return; |
137 } | 137 } |
138 | 138 |
139 if (response->response_type() == QuicInMemoryCache::IGNORE_REQUEST) { | 139 if (response->response_type() == QuicInMemoryCache::IGNORE_REQUEST) { |
140 DVLOG(1) << "Special response: ignoring request."; | 140 DVLOG(1) << "Special response: ignoring request."; |
141 return; | 141 return; |
142 } | 142 } |
143 | 143 |
144 // Examing response status, if it was not pure integer as typical h2 response | 144 // Examing response status, if it was not pure integer as typical h2 response |
145 // status, send error response. | 145 // status, send error response. |
146 string request_url = request_headers_[":scheme"].as_string() + "://" + | 146 string request_url; |
147 request_headers_[":authority"].as_string() + | 147 if (!request_headers_[":scheme"].as_string().empty()) { |
148 request_headers_[":path"].as_string(); | 148 request_url = request_headers_[":scheme"].as_string() +"://" + |
| 149 request_headers_[":authority"].as_string() + |
| 150 request_headers_[":path"].as_string(); |
| 151 } else { |
| 152 request_url = request_headers_[":authority"].as_string() + |
| 153 request_headers_[":path"].as_string(); |
| 154 } |
149 int response_code; | 155 int response_code; |
150 SpdyHeaderBlock response_headers = response->headers(); | 156 SpdyHeaderBlock response_headers = response->headers(); |
151 if (!base::StringToInt(response_headers[":status"], &response_code)) { | 157 if (!base::StringToInt(response_headers[":status"], &response_code)) { |
152 DVLOG(1) << "Illegal (non-integer) response :status from cache: " | 158 DVLOG(1) << "Illegal (non-integer) response :status from cache: " |
153 << response_headers[":status"].as_string() << " for request " | 159 << response_headers[":status"].as_string() << " for request " |
154 << request_url; | 160 << request_url; |
155 SendErrorResponse(); | 161 SendErrorResponse(); |
156 return; | 162 return; |
157 } | 163 } |
158 | 164 |
159 if (id() % 2 == 0) { | 165 if (id() % 2 == 0) { |
160 // A server initiated stream is only used for a server push response, | 166 // A server initiated stream is only used for a server push response, |
161 // and only 200 and 30X response codes are supported for server push. | 167 // and only 200 and 30X response codes are supported for server push. |
162 // This behavior mirrors the HTTP/2 implementation. | 168 // This behavior mirrors the HTTP/2 implementation. |
163 bool is_redirection = response_code / 100 == 3; | 169 bool is_redirection = response_code / 100 == 3; |
164 if (response_code != 200 && !is_redirection) { | 170 if (response_code != 200 && !is_redirection) { |
165 LOG(WARNING) << "Response to server push request " << request_url | 171 LOG(WARNING) << "Response to server push request " << request_url |
166 << " result in response code " << response_code; | 172 << " result in response code " << response_code; |
167 Reset(QUIC_STREAM_CANCELLED); | 173 Reset(QUIC_STREAM_CANCELLED); |
168 return; | 174 return; |
169 } | 175 } |
170 } | 176 } |
| 177 list<QuicInMemoryCache::ServerPushInfo> resources = |
| 178 QuicInMemoryCache::GetInstance()->GetServerPushResources(request_url); |
| 179 DVLOG(1) << "Found " << resources.size() << " push resources for stream " |
| 180 << id(); |
| 181 |
| 182 if (!resources.empty()) { |
| 183 QuicSimpleServerSession* session = |
| 184 static_cast<QuicSimpleServerSession*>(spdy_session()); |
| 185 session->PromisePushResources(request_url, resources, id(), |
| 186 request_headers_); |
| 187 } |
| 188 |
171 DVLOG(1) << "Sending response for stream " << id(); | 189 DVLOG(1) << "Sending response for stream " << id(); |
172 SendHeadersAndBodyAndTrailers(response->headers(), response->body(), | 190 SendHeadersAndBodyAndTrailers(response->headers(), response->body(), |
173 response->trailers()); | 191 response->trailers()); |
174 } | 192 } |
175 | 193 |
176 void QuicSimpleServerStream::SendErrorResponse() { | 194 void QuicSimpleServerStream::SendErrorResponse() { |
177 DVLOG(1) << "Sending error response for stream " << id(); | 195 DVLOG(1) << "Sending error response for stream " << id(); |
178 SpdyHeaderBlock headers; | 196 SpdyHeaderBlock headers; |
179 headers[":status"] = "500"; | 197 headers[":status"] = "500"; |
180 headers["content-length"] = base::UintToString(strlen(kErrorResponseBody)); | 198 headers["content-length"] = base::UintToString(strlen(kErrorResponseBody)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 // Send the trailers. A FIN is always sent with trailers. | 238 // Send the trailers. A FIN is always sent with trailers. |
221 DVLOG(1) << "Writing trailers (fin = true): " | 239 DVLOG(1) << "Writing trailers (fin = true): " |
222 << response_trailers.DebugString(); | 240 << response_trailers.DebugString(); |
223 WriteTrailers(response_trailers, nullptr); | 241 WriteTrailers(response_trailers, nullptr); |
224 } | 242 } |
225 | 243 |
226 const char* const QuicSimpleServerStream::kErrorResponseBody = "bad"; | 244 const char* const QuicSimpleServerStream::kErrorResponseBody = "bad"; |
227 | 245 |
228 } // namespace tools | 246 } // namespace tools |
229 } // namespace net | 247 } // namespace net |
OLD | NEW |