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

Side by Side Diff: components/cronet/android/test/native_test_server.cc

Issue 1085903002: Enable Sdch in Cronet (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make sure a second request to get dictionary is serviced from cache Created 5 years, 8 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "native_test_server.h" 5 #include "native_test_server.h"
6 6
7 #include <string>
8
7 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h" 10 #include "base/android/jni_string.h"
11 #include "base/android/path_utils.h"
9 #include "base/bind.h" 12 #include "base/bind.h"
10 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/macros.h"
11 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
12 #include "base/path_service.h" 17 #include "base/path_service.h"
18 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h"
21 #include "components/cronet/android/cronet_url_request_context_adapter.h"
22 #include "components/cronet/android/url_request_context_adapter.h"
14 #include "jni/NativeTestServer_jni.h" 23 #include "jni/NativeTestServer_jni.h"
24 #include "net/dns/host_resolver_impl.h"
25 #include "net/dns/mock_host_resolver.h"
15 #include "net/http/http_status_code.h" 26 #include "net/http/http_status_code.h"
16 #include "net/test/embedded_test_server/embedded_test_server.h" 27 #include "net/test/embedded_test_server/embedded_test_server.h"
17 #include "net/test/embedded_test_server/http_request.h" 28 #include "net/test/embedded_test_server/http_request.h"
18 #include "net/test/embedded_test_server/http_response.h" 29 #include "net/test/embedded_test_server/http_response.h"
19 #include "url/gurl.h" 30 #include "url/gurl.h"
20 31
21 namespace cronet { 32 namespace cronet {
22 33
23 namespace { 34 namespace {
24 35
25 const char echo_body_path[] = "/echo_body"; 36 const char echo_body_path[] = "/echo_body";
26 const char echo_header_path[] = "/echo_header"; 37 const char echo_header_path[] = "/echo_header";
27 const char echo_all_headers_path[] = "/echo_all_headers"; 38 const char echo_all_headers_path[] = "/echo_all_headers";
28 const char echo_method_path[] = "/echo_method"; 39 const char echo_method_path[] = "/echo_method";
29 const char redirect_to_echo_body_path[] = "/redirect_to_echo_body"; 40 const char redirect_to_echo_body_path[] = "/redirect_to_echo_body";
41 const char fake_sdch_domain[] = "fake.sdch.domain";
42 // Path that advertises the dictionaries passed in query params if client
43 // supports Sdch encoding. E.g. /sdch/index?q=LeQxM80O will make the server
44 // responds with "Get-Dictionary: /sdch/dict/LeQxM80O".
45 const char sdch_path[] = "/sdch/index";
46 // Path that returns encoded response if client has the right dictionary.
47 const char sdch_test_path[] = "/sdch/test";
48 // Path where dictionaries are stored.
49 const char sdch_dict_path[] = "/sdch/dict/";
30 50
31 net::test_server::EmbeddedTestServer* g_test_server = nullptr; 51 net::test_server::EmbeddedTestServer* g_test_server = nullptr;
32 52
33 scoped_ptr<net::test_server::HttpResponse> UploadServerRequestHandler( 53 class CustomHttpResponse : public net::test_server::HttpResponse {
54 public:
55 CustomHttpResponse(const std::string& headers, const std::string& contents)
56 : headers_(headers), contents_(contents) {}
57
58 std::string ToResponseString() const override {
59 return headers_ + "\r\n" + contents_;
60 }
61
62 void AddHeader(const std::string& key_value_pair) {
63 headers_.append(base::StringPrintf("%s\r\n", key_value_pair.c_str()));
64 }
65
66 private:
67 std::string headers_;
68 std::string contents_;
69
70 DISALLOW_COPY_AND_ASSIGN(CustomHttpResponse);
71 };
72
73 scoped_ptr<CustomHttpResponse> ConstructResponseBasedOnFile(
74 const base::FilePath& file_path) {
75 std::string file_contents;
76 bool read_file = base::ReadFileToString(file_path, &file_contents);
77 DCHECK(read_file);
78 base::FilePath headers_path(
79 file_path.AddExtension(FILE_PATH_LITERAL("mock-http-headers")));
80 std::string headers_contents;
81 bool read_headers = base::ReadFileToString(headers_path, &headers_contents);
82 DCHECK(read_headers);
83 scoped_ptr<CustomHttpResponse> http_response(
84 new CustomHttpResponse(headers_contents, file_contents));
85 return http_response.Pass();
86 }
87
88 scoped_ptr<net::test_server::HttpResponse> NativeTestServerRequestHandler(
34 const net::test_server::HttpRequest& request) { 89 const net::test_server::HttpRequest& request) {
35 DCHECK(g_test_server); 90 DCHECK(g_test_server);
36 scoped_ptr<net::test_server::BasicHttpResponse> response( 91 scoped_ptr<net::test_server::BasicHttpResponse> response(
37 new net::test_server::BasicHttpResponse()); 92 new net::test_server::BasicHttpResponse());
38 response->set_content_type("text/plain"); 93 response->set_content_type("text/plain");
39 94
40 if (request.relative_url == echo_body_path) { 95 if (request.relative_url == echo_body_path) {
41 if (request.has_content) { 96 if (request.has_content) {
42 response->set_content(request.content); 97 response->set_content(request.content);
43 } else { 98 } else {
(...skipping 26 matching lines...) Expand all
70 if (request.relative_url == redirect_to_echo_body_path) { 125 if (request.relative_url == redirect_to_echo_body_path) {
71 response->set_code(net::HTTP_TEMPORARY_REDIRECT); 126 response->set_code(net::HTTP_TEMPORARY_REDIRECT);
72 response->AddCustomHeader("Location", echo_body_path); 127 response->AddCustomHeader("Location", echo_body_path);
73 return response.Pass(); 128 return response.Pass();
74 } 129 }
75 130
76 // Unhandled requests result in the Embedded test server sending a 404. 131 // Unhandled requests result in the Embedded test server sending a 404.
77 return scoped_ptr<net::test_server::BasicHttpResponse>(); 132 return scoped_ptr<net::test_server::BasicHttpResponse>();
78 } 133 }
79 134
135 scoped_ptr<net::test_server::HttpResponse> SdchRequestHandler(
136 const net::test_server::HttpRequest& request) {
137 DCHECK(g_test_server);
138 base::FilePath dir_path;
139 bool get_data_dir = base::android::GetDataDirectory(&dir_path);
140 DCHECK(get_data_dir);
141 dir_path = dir_path.Append(FILE_PATH_LITERAL("test"));
142
143 if (StartsWithASCII(request.relative_url, sdch_path, true)) {
144 base::FilePath file_path = dir_path.Append("sdch/index");
145 scoped_ptr<CustomHttpResponse> response =
146 ConstructResponseBasedOnFile(file_path).Pass();
147 // Check for query params to see which dictionaries to advertise.
mef 2015/04/28 20:37:11 Need comment on what query params are used to defi
xunjieli 2015/04/29 02:05:09 Done.
148 GURL url = g_test_server->GetURL(request.relative_url);
149 base::StringPairs pairs;
150 if (!base::SplitStringIntoKeyValuePairs(url.query(), '=', '&', &pairs)) {
mef 2015/04/28 20:37:11 Suggest: using GetValueForKeyInQuery()
xunjieli 2015/04/29 02:05:09 Done. Was thinking we should support multiple dict
151 DCHECK(false) << "parsing query params failed";
152 }
153 auto it = request.headers.find("Accept-Encoding");
mef 2015/04/28 20:37:10 'it' is a bit generic, suggest calling it 'accept_
xunjieli 2015/04/29 02:05:09 Done.
154 if (it != request.headers.end()) {
155 if (it->second.find("sdch") != std::string::npos) {
156 std::string get_dictionary_header = "";
157 for (base::StringPairs::const_iterator it = pairs.begin();
mef 2015/04/28 20:37:11 This 'it' masks upper level 'it', which makes it c
xunjieli 2015/04/29 02:05:09 Done.
158 it != pairs.end(); ++it) {
mef 2015/04/28 20:37:10 Could we use range-based for loop here? Why do we
xunjieli 2015/04/29 02:05:09 Done. Was thinking of supporting multiple dictiona
159 get_dictionary_header += sdch_dict_path + it->second + ", ";
160 }
161 if (!get_dictionary_header.empty()) {
162 // Remove trailing comma and space.
163 get_dictionary_header =
164 get_dictionary_header.substr(0, get_dictionary_header.size() - 2);
165 response->AddHeader("Get-Dictionary: " + get_dictionary_header);
166 }
167 }
168 }
169 return response.Pass();
170 }
171
172 if (StartsWithASCII(request.relative_url, sdch_test_path, true)) {
173 auto it = request.headers.find("Avail-Dictionary");
mef 2015/04/28 20:37:10 more descriptive name than 'it'?
xunjieli 2015/04/29 02:05:09 Done.
174 if (it != request.headers.end()) {
175 base::FilePath file_path =
176 dir_path.Append("sdch/" + it->second + "_encoded");
177 return ConstructResponseBasedOnFile(file_path).Pass();
178 }
179 scoped_ptr<net::test_server::BasicHttpResponse> response(
180 new net::test_server::BasicHttpResponse());
181 response->set_content_type("text/plain");
182 response->set_content("Sdch is not used.\n");
mef 2015/04/28 20:37:10 maybe construct response based on another file wit
xunjieli 2015/04/29 02:05:09 Hmm.. but we just want to make sure here that sdch
mef 2015/04/29 15:37:29 sg, thanks!
183 return response.Pass();
184 }
185
186 // Unhandled requests result in the Embedded test server sending a 404.
187 return scoped_ptr<net::test_server::BasicHttpResponse>();
188 }
189
190 void RegisterHostResolverProcHelper(
191 net::URLRequestContext* url_request_context) {
192 net::HostResolverImpl* resolver =
193 static_cast<net::HostResolverImpl*>(url_request_context->host_resolver());
194 scoped_refptr<net::RuleBasedHostResolverProc> proc =
195 new net::RuleBasedHostResolverProc(NULL);
196 proc->AddRule(fake_sdch_domain, "127.0.0.1");
197 resolver->set_proc_params_for_test(
198 net::HostResolverImpl::ProcTaskParams(proc.get(), 1u));
199 JNIEnv* env = base::android::AttachCurrentThread();
200 Java_NativeTestServer_onHostResolverProcRegistered(env);
201 }
202
203 void RegisterHostResolverProcOnNetworkThread(
204 CronetURLRequestContextAdapter* context_adapter) {
205 RegisterHostResolverProcHelper(context_adapter->GetURLRequestContext());
206 }
207
208 // TODO(xunjieli): Delete this once legacy API is removed.
209 void RegisterHostResolverProcOnNetworkThreadLegacyAPI(
210 URLRequestContextAdapter* context_adapter) {
211 RegisterHostResolverProcHelper(context_adapter->GetURLRequestContext());
212 }
213
80 } // namespace 214 } // namespace
81 215
82 jboolean StartNativeTestServer(JNIEnv* env, 216 jboolean StartNativeTestServer(JNIEnv* env,
83 jclass jcaller, 217 jclass jcaller,
84 jstring jtest_files_root) { 218 jstring jtest_files_root) {
85 // Shouldn't happen. 219 // Shouldn't happen.
86 if (g_test_server) 220 if (g_test_server)
87 return false; 221 return false;
88 g_test_server = new net::test_server::EmbeddedTestServer(); 222 g_test_server = new net::test_server::EmbeddedTestServer();
89 g_test_server->RegisterRequestHandler( 223 g_test_server->RegisterRequestHandler(
90 base::Bind(&UploadServerRequestHandler)); 224 base::Bind(&NativeTestServerRequestHandler));
91 // Add a second handler for paths that UploadServerRequestHandler does not 225 g_test_server->RegisterRequestHandler(base::Bind(&SdchRequestHandler));
92 // handle.
93 base::FilePath test_files_root( 226 base::FilePath test_files_root(
94 base::android::ConvertJavaStringToUTF8(env, jtest_files_root)); 227 base::android::ConvertJavaStringToUTF8(env, jtest_files_root));
228
229 // Add a third handler for paths that NativeTestServerRequestHandler does not
230 // handle.
95 g_test_server->ServeFilesFromDirectory(test_files_root); 231 g_test_server->ServeFilesFromDirectory(test_files_root);
96 return g_test_server->InitializeAndWaitUntilReady(); 232 return g_test_server->InitializeAndWaitUntilReady();
97 } 233 }
98 234
235 void RegisterHostResolverProc(JNIEnv* env,
236 jclass jcaller,
237 jlong jadapter,
238 jboolean jlegacy_api) {
239 if (jlegacy_api == JNI_TRUE) {
240 URLRequestContextAdapter* context_adapter =
241 reinterpret_cast<URLRequestContextAdapter*>(jadapter);
242 context_adapter->PostTaskToNetworkThread(
243 FROM_HERE, base::Bind(&RegisterHostResolverProcOnNetworkThreadLegacyAPI,
244 base::Unretained(context_adapter)));
245 } else {
246 CronetURLRequestContextAdapter* context_adapter =
247 reinterpret_cast<CronetURLRequestContextAdapter*>(jadapter);
248 context_adapter->PostTaskToNetworkThread(
249 FROM_HERE, base::Bind(&RegisterHostResolverProcOnNetworkThread,
250 base::Unretained(context_adapter)));
251 }
252 }
253
99 void ShutdownNativeTestServer(JNIEnv* env, jclass jcaller) { 254 void ShutdownNativeTestServer(JNIEnv* env, jclass jcaller) {
100 if (!g_test_server) 255 if (!g_test_server)
101 return; 256 return;
102 delete g_test_server; 257 delete g_test_server;
103 g_test_server = NULL; 258 g_test_server = NULL;
104 } 259 }
105 260
106 jstring GetEchoBodyURL(JNIEnv* env, jclass jcaller) { 261 jstring GetEchoBodyURL(JNIEnv* env, jclass jcaller) {
107 DCHECK(g_test_server); 262 DCHECK(g_test_server);
108 GURL url = g_test_server->GetURL(echo_body_path); 263 GURL url = g_test_server->GetURL(echo_body_path);
(...skipping 28 matching lines...) Expand all
137 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release(); 292 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
138 } 293 }
139 294
140 jstring GetFileURL(JNIEnv* env, jclass jcaller, jstring jfile_path) { 295 jstring GetFileURL(JNIEnv* env, jclass jcaller, jstring jfile_path) {
141 DCHECK(g_test_server); 296 DCHECK(g_test_server);
142 std::string file = base::android::ConvertJavaStringToUTF8(env, jfile_path); 297 std::string file = base::android::ConvertJavaStringToUTF8(env, jfile_path);
143 GURL url = g_test_server->GetURL(file); 298 GURL url = g_test_server->GetURL(file);
144 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release(); 299 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
145 } 300 }
146 301
302 jstring GetSdchURL(JNIEnv* env, jclass jcaller) {
303 DCHECK(g_test_server);
304 std::string url(base::StringPrintf("http://%s:%d", fake_sdch_domain,
305 g_test_server->port()));
306 return base::android::ConvertUTF8ToJavaString(env, url).Release();
307 }
308
147 bool RegisterNativeTestServer(JNIEnv* env) { 309 bool RegisterNativeTestServer(JNIEnv* env) {
148 return RegisterNativesImpl(env); 310 return RegisterNativesImpl(env);
149 } 311 }
150 312
151 } // namespace cronet 313 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698