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

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: constants Created 5 years, 7 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"
13 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h"
20 #include "components/cronet/android/cronet_url_request_context_adapter.h"
21 #include "components/cronet/android/url_request_context_adapter.h"
14 #include "jni/NativeTestServer_jni.h" 22 #include "jni/NativeTestServer_jni.h"
23 #include "net/base/url_util.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 kEchoBodyPath[] = "/echo_body";
26 const char echo_header_path[] = "/echo_header"; 37 const char kEchoHeaderPath[] = "/echo_header";
27 const char echo_all_headers_path[] = "/echo_all_headers"; 38 const char kEchoAllHeadersPath[] = "/echo_all_headers";
28 const char echo_method_path[] = "/echo_method"; 39 const char kEchoMethodPath[] = "/echo_method";
29 const char redirect_to_echo_body_path[] = "/redirect_to_echo_body"; 40 const char kRedirectToEchoBodyPath[] = "/redirect_to_echo_body";
41 const char kFakeSdchDomain[] = "fake.sdch.domain";
42 // Path that advertises the dictionary 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 kSdchPath[] = "/sdch/index";
46 // Path that returns encoded response if client has the right dictionary.
47 const char kSdchTestPath[] = "/sdch/test";
48 // Path where dictionaries are stored.
49 const char kSdchDictPath[] = "/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 == kEchoBodyPath) {
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 {
44 response->set_content("Request has no body. :("); 99 response->set_content("Request has no body. :(");
45 } 100 }
46 return response.Pass(); 101 return response.Pass();
47 } 102 }
48 103
49 if (StartsWithASCII(request.relative_url, echo_header_path, true)) { 104 if (StartsWithASCII(request.relative_url, kEchoHeaderPath, true)) {
50 GURL url = g_test_server->GetURL(request.relative_url); 105 GURL url = g_test_server->GetURL(request.relative_url);
51 auto it = request.headers.find(url.query()); 106 auto it = request.headers.find(url.query());
52 if (it != request.headers.end()) { 107 if (it != request.headers.end()) {
53 response->set_content(it->second); 108 response->set_content(it->second);
54 } else { 109 } else {
55 response->set_content("Header not found. :("); 110 response->set_content("Header not found. :(");
56 } 111 }
57 return response.Pass(); 112 return response.Pass();
58 } 113 }
59 114
60 if (request.relative_url == echo_all_headers_path) { 115 if (request.relative_url == kEchoAllHeadersPath) {
61 response->set_content(request.all_headers); 116 response->set_content(request.all_headers);
62 return response.Pass(); 117 return response.Pass();
63 } 118 }
64 119
65 if (request.relative_url == echo_method_path) { 120 if (request.relative_url == kEchoMethodPath) {
66 response->set_content(request.method_string); 121 response->set_content(request.method_string);
67 return response.Pass(); 122 return response.Pass();
68 } 123 }
69 124
70 if (request.relative_url == redirect_to_echo_body_path) { 125 if (request.relative_url == kRedirectToEchoBodyPath) {
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", kEchoBodyPath);
73 return response.Pass(); 128 return response.Pass();
74 } 129 }
75 130
131 // Unhandled requests result in the Embedded test server sending a 404.
132 return scoped_ptr<net::test_server::BasicHttpResponse>();
133 }
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, kSdchPath, 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 dictionary to advertise.
148 // For instance, ?q=dictionaryA will make the server advertise dictionaryA.
149 GURL url = g_test_server->GetURL(request.relative_url);
150 std::string dictionary;
151 if (!net::GetValueForKeyInQuery(url, "q", &dictionary)) {
152 CHECK(false) << "dictionary is not found in query params of "
153 << request.relative_url;
154 }
155 auto accept_encoding_header = request.headers.find("Accept-Encoding");
156 if (accept_encoding_header != request.headers.end()) {
157 if (accept_encoding_header->second.find("sdch") != std::string::npos)
158 response->AddHeader(base::StringPrintf(
159 "Get-Dictionary: %s%s", kSdchDictPath, dictionary.c_str()));
160 }
161 return response.Pass();
162 }
163
164 if (StartsWithASCII(request.relative_url, kSdchTestPath, true)) {
165 auto avail_dictionary_header = request.headers.find("Avail-Dictionary");
166 if (avail_dictionary_header != request.headers.end()) {
167 base::FilePath file_path = dir_path.Append(
168 "sdch/" + avail_dictionary_header->second + "_encoded");
169 return ConstructResponseBasedOnFile(file_path).Pass();
170 }
171 scoped_ptr<net::test_server::BasicHttpResponse> response(
172 new net::test_server::BasicHttpResponse());
173 response->set_content_type("text/plain");
174 response->set_content("Sdch is not used.\n");
175 return response.Pass();
176 }
177
76 // Unhandled requests result in the Embedded test server sending a 404. 178 // Unhandled requests result in the Embedded test server sending a 404.
77 return scoped_ptr<net::test_server::BasicHttpResponse>(); 179 return scoped_ptr<net::test_server::BasicHttpResponse>();
78 } 180 }
79 181
182 void RegisterHostResolverProcHelper(
183 net::URLRequestContext* url_request_context) {
184 net::HostResolverImpl* resolver =
185 static_cast<net::HostResolverImpl*>(url_request_context->host_resolver());
186 scoped_refptr<net::RuleBasedHostResolverProc> proc =
187 new net::RuleBasedHostResolverProc(NULL);
188 proc->AddRule(kFakeSdchDomain, "127.0.0.1");
189 resolver->set_proc_params_for_test(
190 net::HostResolverImpl::ProcTaskParams(proc.get(), 1u));
191 JNIEnv* env = base::android::AttachCurrentThread();
192 Java_NativeTestServer_onHostResolverProcRegistered(env);
193 }
194
195 void RegisterHostResolverProcOnNetworkThread(
196 CronetURLRequestContextAdapter* context_adapter) {
197 RegisterHostResolverProcHelper(context_adapter->GetURLRequestContext());
198 }
199
200 // TODO(xunjieli): Delete this once legacy API is removed.
201 void RegisterHostResolverProcOnNetworkThreadLegacyAPI(
202 URLRequestContextAdapter* context_adapter) {
203 RegisterHostResolverProcHelper(context_adapter->GetURLRequestContext());
204 }
205
80 } // namespace 206 } // namespace
81 207
82 jboolean StartNativeTestServer(JNIEnv* env, 208 jboolean StartNativeTestServer(JNIEnv* env,
83 jclass jcaller, 209 jclass jcaller,
84 jstring jtest_files_root) { 210 jstring jtest_files_root) {
85 // Shouldn't happen. 211 // Shouldn't happen.
86 if (g_test_server) 212 if (g_test_server)
87 return false; 213 return false;
88 g_test_server = new net::test_server::EmbeddedTestServer(); 214 g_test_server = new net::test_server::EmbeddedTestServer();
89 g_test_server->RegisterRequestHandler( 215 g_test_server->RegisterRequestHandler(
90 base::Bind(&UploadServerRequestHandler)); 216 base::Bind(&NativeTestServerRequestHandler));
91 // Add a second handler for paths that UploadServerRequestHandler does not 217 g_test_server->RegisterRequestHandler(base::Bind(&SdchRequestHandler));
92 // handle.
93 base::FilePath test_files_root( 218 base::FilePath test_files_root(
94 base::android::ConvertJavaStringToUTF8(env, jtest_files_root)); 219 base::android::ConvertJavaStringToUTF8(env, jtest_files_root));
220
221 // Add a third handler for paths that NativeTestServerRequestHandler does not
222 // handle.
95 g_test_server->ServeFilesFromDirectory(test_files_root); 223 g_test_server->ServeFilesFromDirectory(test_files_root);
96 return g_test_server->InitializeAndWaitUntilReady(); 224 return g_test_server->InitializeAndWaitUntilReady();
97 } 225 }
98 226
227 void RegisterHostResolverProc(JNIEnv* env,
228 jclass jcaller,
229 jlong jadapter,
230 jboolean jlegacy_api) {
231 if (jlegacy_api == JNI_TRUE) {
232 URLRequestContextAdapter* context_adapter =
233 reinterpret_cast<URLRequestContextAdapter*>(jadapter);
234 context_adapter->PostTaskToNetworkThread(
235 FROM_HERE, base::Bind(&RegisterHostResolverProcOnNetworkThreadLegacyAPI,
236 base::Unretained(context_adapter)));
237 } else {
238 CronetURLRequestContextAdapter* context_adapter =
239 reinterpret_cast<CronetURLRequestContextAdapter*>(jadapter);
240 context_adapter->PostTaskToNetworkThread(
241 FROM_HERE, base::Bind(&RegisterHostResolverProcOnNetworkThread,
242 base::Unretained(context_adapter)));
243 }
244 }
245
99 void ShutdownNativeTestServer(JNIEnv* env, jclass jcaller) { 246 void ShutdownNativeTestServer(JNIEnv* env, jclass jcaller) {
100 if (!g_test_server) 247 if (!g_test_server)
101 return; 248 return;
102 delete g_test_server; 249 delete g_test_server;
103 g_test_server = NULL; 250 g_test_server = NULL;
104 } 251 }
105 252
106 jstring GetEchoBodyURL(JNIEnv* env, jclass jcaller) { 253 jstring GetEchoBodyURL(JNIEnv* env, jclass jcaller) {
107 DCHECK(g_test_server); 254 DCHECK(g_test_server);
108 GURL url = g_test_server->GetURL(echo_body_path); 255 GURL url = g_test_server->GetURL(kEchoBodyPath);
109 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release(); 256 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
110 } 257 }
111 258
112 jstring GetEchoHeaderURL(JNIEnv* env, jclass jcaller, jstring jheader) { 259 jstring GetEchoHeaderURL(JNIEnv* env, jclass jcaller, jstring jheader) {
113 DCHECK(g_test_server); 260 DCHECK(g_test_server);
114 GURL url = g_test_server->GetURL(echo_header_path); 261 GURL url = g_test_server->GetURL(kEchoHeaderPath);
115 GURL::Replacements replacements; 262 GURL::Replacements replacements;
116 std::string header = base::android::ConvertJavaStringToUTF8(env, jheader); 263 std::string header = base::android::ConvertJavaStringToUTF8(env, jheader);
117 replacements.SetQueryStr(header.c_str()); 264 replacements.SetQueryStr(header.c_str());
118 url = url.ReplaceComponents(replacements); 265 url = url.ReplaceComponents(replacements);
119 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release(); 266 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
120 } 267 }
121 268
122 jstring GetEchoAllHeadersURL(JNIEnv* env, jclass jcaller) { 269 jstring GetEchoAllHeadersURL(JNIEnv* env, jclass jcaller) {
123 DCHECK(g_test_server); 270 DCHECK(g_test_server);
124 GURL url = g_test_server->GetURL(echo_all_headers_path); 271 GURL url = g_test_server->GetURL(kEchoAllHeadersPath);
125 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release(); 272 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
126 } 273 }
127 274
128 jstring GetEchoMethodURL(JNIEnv* env, jclass jcaller) { 275 jstring GetEchoMethodURL(JNIEnv* env, jclass jcaller) {
129 DCHECK(g_test_server); 276 DCHECK(g_test_server);
130 GURL url = g_test_server->GetURL(echo_method_path); 277 GURL url = g_test_server->GetURL(kEchoMethodPath);
131 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release(); 278 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
132 } 279 }
133 280
134 jstring GetRedirectToEchoBody(JNIEnv* env, jclass jcaller) { 281 jstring GetRedirectToEchoBody(JNIEnv* env, jclass jcaller) {
135 DCHECK(g_test_server); 282 DCHECK(g_test_server);
136 GURL url = g_test_server->GetURL(redirect_to_echo_body_path); 283 GURL url = g_test_server->GetURL(kRedirectToEchoBodyPath);
137 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release(); 284 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
138 } 285 }
139 286
140 jstring GetFileURL(JNIEnv* env, jclass jcaller, jstring jfile_path) { 287 jstring GetFileURL(JNIEnv* env, jclass jcaller, jstring jfile_path) {
141 DCHECK(g_test_server); 288 DCHECK(g_test_server);
142 std::string file = base::android::ConvertJavaStringToUTF8(env, jfile_path); 289 std::string file = base::android::ConvertJavaStringToUTF8(env, jfile_path);
143 GURL url = g_test_server->GetURL(file); 290 GURL url = g_test_server->GetURL(file);
144 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release(); 291 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
145 } 292 }
146 293
294 jstring GetSdchURL(JNIEnv* env, jclass jcaller) {
295 DCHECK(g_test_server);
296 std::string url(base::StringPrintf("http://%s:%d", kFakeSdchDomain,
297 g_test_server->port()));
298 return base::android::ConvertUTF8ToJavaString(env, url).Release();
299 }
300
147 bool RegisterNativeTestServer(JNIEnv* env) { 301 bool RegisterNativeTestServer(JNIEnv* env) {
148 return RegisterNativesImpl(env); 302 return RegisterNativesImpl(env);
149 } 303 }
150 304
151 } // namespace cronet 305 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698