| 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" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/string_piece.h" | 13 #include "base/strings/string_piece.h" |
| 14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
| 15 #include "net/quic/core/quic_bug_tracker.h" | 15 #include "net/quic/core/quic_bug_tracker.h" |
| 16 #include "net/quic/core/quic_flags.h" | 16 #include "net/quic/core/quic_flags.h" |
| 17 #include "net/quic/core/quic_spdy_stream.h" | 17 #include "net/quic/core/quic_spdy_stream.h" |
| 18 #include "net/quic/core/spdy_utils.h" | 18 #include "net/quic/core/spdy_utils.h" |
| 19 #include "net/spdy/spdy_protocol.h" | 19 #include "net/spdy/spdy_protocol.h" |
| 20 #include "net/tools/quic/quic_in_memory_cache.h" | 20 #include "net/tools/quic/quic_http_response_cache.h" |
| 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( | 29 QuicSimpleServerStream::QuicSimpleServerStream( |
| 30 QuicStreamId id, | 30 QuicStreamId id, |
| 31 QuicSpdySession* session, | 31 QuicSpdySession* session, |
| 32 QuicInMemoryCache* in_memory_cache) | 32 QuicHttpResponseCache* response_cache) |
| 33 : QuicSpdyStream(id, session), | 33 : QuicSpdyStream(id, session), |
| 34 content_length_(-1), | 34 content_length_(-1), |
| 35 in_memory_cache_(in_memory_cache) {} | 35 response_cache_(response_cache) {} |
| 36 | 36 |
| 37 QuicSimpleServerStream::~QuicSimpleServerStream() {} | 37 QuicSimpleServerStream::~QuicSimpleServerStream() {} |
| 38 | 38 |
| 39 void QuicSimpleServerStream::OnInitialHeadersComplete( | 39 void QuicSimpleServerStream::OnInitialHeadersComplete( |
| 40 bool fin, | 40 bool fin, |
| 41 size_t frame_len, | 41 size_t frame_len, |
| 42 const QuicHeaderList& header_list) { | 42 const QuicHeaderList& header_list) { |
| 43 QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list); | 43 QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list); |
| 44 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_, | 44 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_, |
| 45 &request_headers_)) { | 45 &request_headers_)) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 } | 123 } |
| 124 | 124 |
| 125 if (!base::ContainsKey(request_headers_, ":authority") || | 125 if (!base::ContainsKey(request_headers_, ":authority") || |
| 126 !base::ContainsKey(request_headers_, ":path")) { | 126 !base::ContainsKey(request_headers_, ":path")) { |
| 127 DVLOG(1) << "Request headers do not contain :authority or :path."; | 127 DVLOG(1) << "Request headers do not contain :authority or :path."; |
| 128 SendErrorResponse(); | 128 SendErrorResponse(); |
| 129 return; | 129 return; |
| 130 } | 130 } |
| 131 | 131 |
| 132 // Find response in cache. If not found, send error response. | 132 // Find response in cache. If not found, send error response. |
| 133 const QuicInMemoryCache::Response* response = nullptr; | 133 const QuicHttpResponseCache::Response* response = nullptr; |
| 134 auto authority = request_headers_.find(":authority"); | 134 auto authority = request_headers_.find(":authority"); |
| 135 auto path = request_headers_.find(":path"); | 135 auto path = request_headers_.find(":path"); |
| 136 if (authority != request_headers_.end() && path != request_headers_.end()) { | 136 if (authority != request_headers_.end() && path != request_headers_.end()) { |
| 137 response = in_memory_cache_->GetResponse(authority->second, path->second); | 137 response = response_cache_->GetResponse(authority->second, path->second); |
| 138 } | 138 } |
| 139 if (response == nullptr) { | 139 if (response == nullptr) { |
| 140 DVLOG(1) << "Response not found in cache."; | 140 DVLOG(1) << "Response not found in cache."; |
| 141 SendNotFoundResponse(); | 141 SendNotFoundResponse(); |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 | 144 |
| 145 if (response->response_type() == QuicInMemoryCache::CLOSE_CONNECTION) { | 145 if (response->response_type() == QuicHttpResponseCache::CLOSE_CONNECTION) { |
| 146 DVLOG(1) << "Special response: closing connection."; | 146 DVLOG(1) << "Special response: closing connection."; |
| 147 CloseConnectionWithDetails(QUIC_NO_ERROR, "Toy server forcing close"); | 147 CloseConnectionWithDetails(QUIC_NO_ERROR, "Toy server forcing close"); |
| 148 return; | 148 return; |
| 149 } | 149 } |
| 150 | 150 |
| 151 if (response->response_type() == QuicInMemoryCache::IGNORE_REQUEST) { | 151 if (response->response_type() == QuicHttpResponseCache::IGNORE_REQUEST) { |
| 152 DVLOG(1) << "Special response: ignoring request."; | 152 DVLOG(1) << "Special response: ignoring request."; |
| 153 return; | 153 return; |
| 154 } | 154 } |
| 155 | 155 |
| 156 // Examing response status, if it was not pure integer as typical h2 response | 156 // Examing response status, if it was not pure integer as typical h2 response |
| 157 // status, send error response. | 157 // status, send error response. |
| 158 string request_url = request_headers_[":authority"].as_string() + | 158 string request_url = request_headers_[":authority"].as_string() + |
| 159 request_headers_[":path"].as_string(); | 159 request_headers_[":path"].as_string(); |
| 160 int response_code; | 160 int response_code; |
| 161 const SpdyHeaderBlock& response_headers = response->headers(); | 161 const SpdyHeaderBlock& response_headers = response->headers(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 177 // and only 200 and 30X response codes are supported for server push. | 177 // and only 200 and 30X response codes are supported for server push. |
| 178 // This behavior mirrors the HTTP/2 implementation. | 178 // This behavior mirrors the HTTP/2 implementation. |
| 179 bool is_redirection = response_code / 100 == 3; | 179 bool is_redirection = response_code / 100 == 3; |
| 180 if (response_code != 200 && !is_redirection) { | 180 if (response_code != 200 && !is_redirection) { |
| 181 LOG(WARNING) << "Response to server push request " << request_url | 181 LOG(WARNING) << "Response to server push request " << request_url |
| 182 << " result in response code " << response_code; | 182 << " result in response code " << response_code; |
| 183 Reset(QUIC_STREAM_CANCELLED); | 183 Reset(QUIC_STREAM_CANCELLED); |
| 184 return; | 184 return; |
| 185 } | 185 } |
| 186 } | 186 } |
| 187 std::list<QuicInMemoryCache::ServerPushInfo> resources = | 187 std::list<QuicHttpResponseCache::ServerPushInfo> resources = |
| 188 in_memory_cache_->GetServerPushResources(request_url); | 188 response_cache_->GetServerPushResources(request_url); |
| 189 DVLOG(1) << "Found " << resources.size() << " push resources for stream " | 189 DVLOG(1) << "Found " << resources.size() << " push resources for stream " |
| 190 << id(); | 190 << id(); |
| 191 | 191 |
| 192 if (!resources.empty()) { | 192 if (!resources.empty()) { |
| 193 QuicSimpleServerSession* session = | 193 QuicSimpleServerSession* session = |
| 194 static_cast<QuicSimpleServerSession*>(spdy_session()); | 194 static_cast<QuicSimpleServerSession*>(spdy_session()); |
| 195 session->PromisePushResources(request_url, resources, id(), | 195 session->PromisePushResources(request_url, resources, id(), |
| 196 request_headers_); | 196 request_headers_); |
| 197 } | 197 } |
| 198 | 198 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 DVLOG(1) << "Writing trailers (fin = true): " | 258 DVLOG(1) << "Writing trailers (fin = true): " |
| 259 << response_trailers.DebugString(); | 259 << response_trailers.DebugString(); |
| 260 WriteTrailers(std::move(response_trailers), nullptr); | 260 WriteTrailers(std::move(response_trailers), nullptr); |
| 261 } | 261 } |
| 262 | 262 |
| 263 const char* const QuicSimpleServerStream::kErrorResponseBody = "bad"; | 263 const char* const QuicSimpleServerStream::kErrorResponseBody = "bad"; |
| 264 const char* const QuicSimpleServerStream::kNotFoundResponseBody = | 264 const char* const QuicSimpleServerStream::kNotFoundResponseBody = |
| 265 "file not found"; | 265 "file not found"; |
| 266 | 266 |
| 267 } // namespace net | 267 } // namespace net |
| OLD | NEW |