Revert of Refactor the avatar button/icon class (patchset #14 id:320001 of https...
[chromium-blink-merge.git] / components / cronet / android / test / native_test_server.cc
blobce8c95153845286f36953e25c212413d66503cca
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
3 // found in the LICENSE file.
5 #include "native_test_server.h"
7 #include <string>
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "base/android/path_utils.h"
12 #include "base/bind.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/macros.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/path_service.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"
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"
26 #include "net/http/http_status_code.h"
27 #include "net/test/embedded_test_server/embedded_test_server.h"
28 #include "net/test/embedded_test_server/http_request.h"
29 #include "net/test/embedded_test_server/http_response.h"
30 #include "url/gurl.h"
32 namespace cronet {
34 namespace {
36 const char kEchoBodyPath[] = "/echo_body";
37 const char kEchoHeaderPath[] = "/echo_header";
38 const char kEchoAllHeadersPath[] = "/echo_all_headers";
39 const char kEchoMethodPath[] = "/echo_method";
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/";
51 net::test_server::EmbeddedTestServer* g_test_server = nullptr;
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) {}
58 std::string ToResponseString() const override {
59 return headers_ + "\r\n" + contents_;
62 void AddHeader(const std::string& key_value_pair) {
63 headers_.append(base::StringPrintf("%s\r\n", key_value_pair.c_str()));
66 private:
67 std::string headers_;
68 std::string contents_;
70 DISALLOW_COPY_AND_ASSIGN(CustomHttpResponse);
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();
88 scoped_ptr<net::test_server::HttpResponse> NativeTestServerRequestHandler(
89 const net::test_server::HttpRequest& request) {
90 DCHECK(g_test_server);
91 scoped_ptr<net::test_server::BasicHttpResponse> response(
92 new net::test_server::BasicHttpResponse());
93 response->set_content_type("text/plain");
95 if (request.relative_url == kEchoBodyPath) {
96 if (request.has_content) {
97 response->set_content(request.content);
98 } else {
99 response->set_content("Request has no body. :(");
101 return response.Pass();
104 if (StartsWithASCII(request.relative_url, kEchoHeaderPath, true)) {
105 GURL url = g_test_server->GetURL(request.relative_url);
106 auto it = request.headers.find(url.query());
107 if (it != request.headers.end()) {
108 response->set_content(it->second);
109 } else {
110 response->set_content("Header not found. :(");
112 return response.Pass();
115 if (request.relative_url == kEchoAllHeadersPath) {
116 response->set_content(request.all_headers);
117 return response.Pass();
120 if (request.relative_url == kEchoMethodPath) {
121 response->set_content(request.method_string);
122 return response.Pass();
125 if (request.relative_url == kRedirectToEchoBodyPath) {
126 response->set_code(net::HTTP_TEMPORARY_REDIRECT);
127 response->AddCustomHeader("Location", kEchoBodyPath);
128 return response.Pass();
131 // Unhandled requests result in the Embedded test server sending a 404.
132 return scoped_ptr<net::test_server::BasicHttpResponse>();
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"));
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;
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()));
161 return response.Pass();
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();
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();
178 // Unhandled requests result in the Embedded test server sending a 404.
179 return scoped_ptr<net::test_server::BasicHttpResponse>();
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);
195 void RegisterHostResolverProcOnNetworkThread(
196 CronetURLRequestContextAdapter* context_adapter) {
197 RegisterHostResolverProcHelper(context_adapter->GetURLRequestContext());
200 // TODO(xunjieli): Delete this once legacy API is removed.
201 void RegisterHostResolverProcOnNetworkThreadLegacyAPI(
202 URLRequestContextAdapter* context_adapter) {
203 RegisterHostResolverProcHelper(context_adapter->GetURLRequestContext());
206 } // namespace
208 jboolean StartNativeTestServer(JNIEnv* env,
209 jclass jcaller,
210 jstring jtest_files_root) {
211 // Shouldn't happen.
212 if (g_test_server)
213 return false;
214 g_test_server = new net::test_server::EmbeddedTestServer();
215 g_test_server->RegisterRequestHandler(
216 base::Bind(&NativeTestServerRequestHandler));
217 g_test_server->RegisterRequestHandler(base::Bind(&SdchRequestHandler));
218 base::FilePath test_files_root(
219 base::android::ConvertJavaStringToUTF8(env, jtest_files_root));
221 // Add a third handler for paths that NativeTestServerRequestHandler does not
222 // handle.
223 g_test_server->ServeFilesFromDirectory(test_files_root);
224 return g_test_server->InitializeAndWaitUntilReady();
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)));
246 void ShutdownNativeTestServer(JNIEnv* env, jclass jcaller) {
247 if (!g_test_server)
248 return;
249 delete g_test_server;
250 g_test_server = NULL;
253 jstring GetEchoBodyURL(JNIEnv* env, jclass jcaller) {
254 DCHECK(g_test_server);
255 GURL url = g_test_server->GetURL(kEchoBodyPath);
256 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
259 jstring GetEchoHeaderURL(JNIEnv* env, jclass jcaller, jstring jheader) {
260 DCHECK(g_test_server);
261 GURL url = g_test_server->GetURL(kEchoHeaderPath);
262 GURL::Replacements replacements;
263 std::string header = base::android::ConvertJavaStringToUTF8(env, jheader);
264 replacements.SetQueryStr(header.c_str());
265 url = url.ReplaceComponents(replacements);
266 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
269 jstring GetEchoAllHeadersURL(JNIEnv* env, jclass jcaller) {
270 DCHECK(g_test_server);
271 GURL url = g_test_server->GetURL(kEchoAllHeadersPath);
272 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
275 jstring GetEchoMethodURL(JNIEnv* env, jclass jcaller) {
276 DCHECK(g_test_server);
277 GURL url = g_test_server->GetURL(kEchoMethodPath);
278 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
281 jstring GetRedirectToEchoBody(JNIEnv* env, jclass jcaller) {
282 DCHECK(g_test_server);
283 GURL url = g_test_server->GetURL(kRedirectToEchoBodyPath);
284 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
287 jstring GetFileURL(JNIEnv* env, jclass jcaller, jstring jfile_path) {
288 DCHECK(g_test_server);
289 std::string file = base::android::ConvertJavaStringToUTF8(env, jfile_path);
290 GURL url = g_test_server->GetURL(file);
291 return base::android::ConvertUTF8ToJavaString(env, url.spec()).Release();
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();
301 bool RegisterNativeTestServer(JNIEnv* env) {
302 return RegisterNativesImpl(env);
305 } // namespace cronet