| 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 |