Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Side by Side Diff: net/tools/quic/quic_in_memory_cache.cc

Issue 1032903002: Unify various QUIC server classes in net/quic and net/tools/quic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/tools/quic/quic_in_memory_cache.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_in_memory_cache.h" 5 #include "net/tools/quic/quic_in_memory_cache.h"
6 6
7 #include "base/files/file_enumerator.h" 7 #include "base/files/file_enumerator.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "net/tools/balsa/balsa_frame.h" 11 #include "base/strings/string_util.h"
12 #include "net/tools/balsa/balsa_headers.h" 12 #include "net/http/http_response_headers.h"
13 #include "net/tools/balsa/noop_balsa_visitor.h" 13 #include "net/http/http_util.h"
14 #include "net/tools/quic/spdy_utils.h" 14 #include "net/spdy/spdy_http_utils.h"
15 15
16 using base::FilePath; 16 using base::FilePath;
17 using base::IntToString;
17 using base::StringPiece; 18 using base::StringPiece;
18 using std::string; 19 using std::string;
19 20
20 namespace net { 21 namespace net {
21 namespace tools { 22 namespace tools {
22 23
23 namespace {
24
25 // BalsaVisitor implementation (glue) which caches response bodies.
26 class CachingBalsaVisitor : public NoOpBalsaVisitor {
27 public:
28 CachingBalsaVisitor() : done_framing_(false) {}
29 void ProcessBodyData(const char* input, size_t size) override {
30 AppendToBody(input, size);
31 }
32 void MessageDone() override { done_framing_ = true; }
33 void HandleHeaderError(BalsaFrame* framer) override { UnhandledError(); }
34 void HandleHeaderWarning(BalsaFrame* framer) override { UnhandledError(); }
35 void HandleChunkingError(BalsaFrame* framer) override { UnhandledError(); }
36 void HandleBodyError(BalsaFrame* framer) override { UnhandledError(); }
37 void UnhandledError() {
38 LOG(DFATAL) << "Unhandled error framing HTTP.";
39 }
40 void AppendToBody(const char* input, size_t size) {
41 body_.append(input, size);
42 }
43 bool done_framing() const { return done_framing_; }
44 const string& body() const { return body_; }
45
46 private:
47 bool done_framing_;
48 string body_;
49 };
50
51 } // namespace
52
53 QuicInMemoryCache::Response::Response() : response_type_(REGULAR_RESPONSE) {} 24 QuicInMemoryCache::Response::Response() : response_type_(REGULAR_RESPONSE) {}
54 25
55 QuicInMemoryCache::Response::~Response() {} 26 QuicInMemoryCache::Response::~Response() {}
56 27
57 // static 28 // static
58 QuicInMemoryCache* QuicInMemoryCache::GetInstance() { 29 QuicInMemoryCache* QuicInMemoryCache::GetInstance() {
59 return Singleton<QuicInMemoryCache>::get(); 30 return Singleton<QuicInMemoryCache>::get();
60 } 31 }
61 32
62 const QuicInMemoryCache::Response* QuicInMemoryCache::GetResponse( 33 const QuicInMemoryCache::Response* QuicInMemoryCache::GetResponse(
63 StringPiece host, 34 StringPiece host,
64 StringPiece path) const { 35 StringPiece path) const {
65 ResponseMap::const_iterator it = responses_.find(GetKey(host, path)); 36 ResponseMap::const_iterator it = responses_.find(GetKey(host, path));
66 if (it == responses_.end()) { 37 if (it == responses_.end()) {
67 return nullptr; 38 return nullptr;
68 } 39 }
69 return it->second; 40 return it->second;
70 } 41 }
71 42
72 void QuicInMemoryCache::AddSimpleResponse(StringPiece host, 43 void QuicInMemoryCache::AddSimpleResponse(StringPiece host,
73 StringPiece path, 44 StringPiece path,
74 int response_code, 45 int response_code,
75 StringPiece response_detail, 46 StringPiece response_detail,
76 StringPiece body) { 47 StringPiece body) {
77 SpdyHeaderBlock response_headers; 48 SpdyHeaderBlock response_headers;
78 response_headers[":version"] = "HTTP/1.1"; 49 response_headers[":version"] = "HTTP/1.1";
79 string status = base::IntToString(response_code) + " "; 50 string status = IntToString(response_code) + " ";
80 response_detail.AppendToString(&status); 51 response_detail.AppendToString(&status);
81 response_headers[":status"] = status; 52 response_headers[":status"] = status;
82 response_headers["content-length"] = base::IntToString(body.length()); 53 response_headers["content-length"] =
54 IntToString(static_cast<int>(body.length()));
83 AddResponse(host, path, response_headers, body); 55 AddResponse(host, path, response_headers, body);
84 } 56 }
85 57
86 void QuicInMemoryCache::AddResponse(StringPiece host, 58 void QuicInMemoryCache::AddResponse(StringPiece host,
87 StringPiece path, 59 StringPiece path,
88 const SpdyHeaderBlock& response_headers, 60 const SpdyHeaderBlock& response_headers,
89 StringPiece response_body) { 61 StringPiece response_body) {
90 AddResponseImpl(host, path, REGULAR_RESPONSE, response_headers, 62 AddResponseImpl(host, path, REGULAR_RESPONSE, response_headers,
91 response_body); 63 response_body);
92 } 64 }
(...skipping 10 matching lines...) Expand all
103 STLDeleteValues(&responses_); 75 STLDeleteValues(&responses_);
104 } 76 }
105 77
106 void QuicInMemoryCache::InitializeFromDirectory(const string& cache_directory) { 78 void QuicInMemoryCache::InitializeFromDirectory(const string& cache_directory) {
107 if (cache_directory.empty()) { 79 if (cache_directory.empty()) {
108 LOG(DFATAL) << "cache_directory must not be empty."; 80 LOG(DFATAL) << "cache_directory must not be empty.";
109 return; 81 return;
110 } 82 }
111 VLOG(1) << "Attempting to initialize QuicInMemoryCache from directory: " 83 VLOG(1) << "Attempting to initialize QuicInMemoryCache from directory: "
112 << cache_directory; 84 << cache_directory;
113 FilePath directory(cache_directory); 85 FilePath directory(FilePath::FromUTF8Unsafe(cache_directory));
114 base::FileEnumerator file_list(directory, 86 base::FileEnumerator file_list(directory,
115 true, 87 true,
116 base::FileEnumerator::FILES); 88 base::FileEnumerator::FILES);
117 89
118 for (FilePath file_iter = file_list.Next(); !file_iter.empty(); 90 for (FilePath file_iter = file_list.Next(); !file_iter.empty();
119 file_iter = file_list.Next()) { 91 file_iter = file_list.Next()) {
120 BalsaHeaders request_headers, response_headers;
121 // Need to skip files in .svn directories 92 // Need to skip files in .svn directories
122 if (file_iter.value().find("/.svn/") != string::npos) { 93 if (file_iter.value().find(FILE_PATH_LITERAL("/.svn/")) != string::npos) {
123 continue; 94 continue;
124 } 95 }
125 96
126 // Tease apart filename into host and path. 97 // Tease apart filename into host and path.
127 StringPiece file(file_iter.value()); 98 string file = file_iter.AsUTF8Unsafe();
128 file.remove_prefix(cache_directory.length()); 99 file.erase(0, cache_directory.length());
129 if (file[0] == '/') { 100 if (file[0] == '/') {
130 file.remove_prefix(1); 101 file.erase(0, 1);
131 } 102 }
132 103
133 string file_contents; 104 string file_contents;
134 base::ReadFileToString(file_iter, &file_contents); 105 base::ReadFileToString(file_iter, &file_contents);
135 106 int file_len = static_cast<int>(file_contents.length());
136 // Frame HTTP. 107 int headers_end = HttpUtil::LocateEndOfHeaders(file_contents.data(),
137 CachingBalsaVisitor caching_visitor; 108 file_len);
138 BalsaFrame framer; 109 if (headers_end < 1) {
139 framer.set_balsa_headers(&response_headers); 110 LOG(DFATAL) << "Headers invalid or empty, ignoring: " << file;
140 framer.set_balsa_visitor(&caching_visitor); 111 continue;
141 size_t processed = 0;
142 while (processed < file_contents.length() &&
143 !caching_visitor.done_framing()) {
144 processed += framer.ProcessInput(file_contents.c_str() + processed,
145 file_contents.length() - processed);
146 } 112 }
147 113
148 if (!caching_visitor.done_framing()) { 114 string raw_headers =
149 LOG(DFATAL) << "Did not frame entire message from file: " << file 115 HttpUtil::AssembleRawHeaders(file_contents.data(), headers_end);
150 << " (" << processed << " of " << file_contents.length() 116
151 << " bytes)."; 117 scoped_refptr<HttpResponseHeaders> response_headers =
152 } 118 new HttpResponseHeaders(raw_headers);
153 if (processed < file_contents.length()) { 119
154 // Didn't frame whole file. Assume remainder is body. 120 string base;
155 // This sometimes happens as a result of incompatibilities between 121 if (response_headers->GetNormalizedHeader("X-Original-Url", &base)) {
156 // BalsaFramer and wget's serialization of HTTP sans content-length. 122 response_headers->RemoveHeader("X-Original-Url");
157 caching_visitor.AppendToBody(file_contents.c_str() + processed, 123 // Remove the protocol so we can add it below.
158 file_contents.length() - processed); 124 if (StartsWithASCII(base, "https://", false)) {
159 processed += file_contents.length(); 125 base = base.substr(8);
126 } else if (StartsWithASCII(base, "http://", false)) {
127 base = base.substr(7);
128 }
129 } else {
130 base = file;
160 } 131 }
161 132
162 StringPiece base = file; 133 size_t path_start = base.find_first_of('/');
163 if (response_headers.HasHeader("X-Original-Url")) { 134 StringPiece host(StringPiece(base).substr(0, path_start));
164 base = response_headers.GetHeader("X-Original-Url"); 135 StringPiece path(StringPiece(base).substr(path_start));
165 response_headers.RemoveAllOfHeader("X-Original-Url");
166 // Remove the protocol so that the string is of the form host + path,
167 // which is parsed properly below.
168 if (StringPieceUtils::StartsWithIgnoreCase(base, "https://")) {
169 base.remove_prefix(8);
170 } else if (StringPieceUtils::StartsWithIgnoreCase(base, "http://")) {
171 base.remove_prefix(7);
172 }
173 }
174 int path_start = base.find_first_of('/');
175 DCHECK_LT(0, path_start);
176 StringPiece host(base.substr(0, path_start));
177 StringPiece path(base.substr(path_start));
178 if (path[path.length() - 1] == ',') { 136 if (path[path.length() - 1] == ',') {
179 path.remove_suffix(1); 137 path.remove_suffix(1);
180 } 138 }
181 AddResponse(host, path, 139
182 SpdyUtils::ResponseHeadersToSpdyHeaders(response_headers), 140 StringPiece body(file_contents.data() + headers_end,
183 caching_visitor.body()); 141 file_contents.size() - headers_end);
142 SpdyHeaderBlock header_block;
143 CreateSpdyHeadersFromHttpResponse(*response_headers, SPDY3, &header_block);
144 AddResponse(host, path, header_block, body);
184 } 145 }
185 } 146 }
186 147
187 QuicInMemoryCache::~QuicInMemoryCache() { 148 QuicInMemoryCache::~QuicInMemoryCache() {
188 STLDeleteValues(&responses_); 149 STLDeleteValues(&responses_);
189 } 150 }
190 151
191 void QuicInMemoryCache::AddResponseImpl( 152 void QuicInMemoryCache::AddResponseImpl(
192 StringPiece host, 153 StringPiece host,
193 StringPiece path, 154 StringPiece path,
(...skipping 12 matching lines...) Expand all
206 new_response->set_body(response_body); 167 new_response->set_body(response_body);
207 responses_[key] = new_response; 168 responses_[key] = new_response;
208 } 169 }
209 170
210 string QuicInMemoryCache::GetKey(StringPiece host, StringPiece path) const { 171 string QuicInMemoryCache::GetKey(StringPiece host, StringPiece path) const {
211 return host.as_string() + path.as_string(); 172 return host.as_string() + path.as_string();
212 } 173 }
213 174
214 } // namespace tools 175 } // namespace tools
215 } // namespace net 176 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/quic_in_memory_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698