diff options
author | zhenghao@google.com <zhenghao@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-16 02:54:08 +0000 |
---|---|---|
committer | zhenghao@google.com <zhenghao@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-16 02:54:08 +0000 |
commit | 0577cfd2617c0c1ddcb04002a81738db95a1ab42 (patch) | |
tree | a1af7507440bf289672706b7f40954186fd0bd73 /webkit | |
parent | b51b6893eca496daf1367b4b1888d87430baec57 (diff) | |
download | chromium_src-0577cfd2617c0c1ddcb04002a81738db95a1ab42.zip chromium_src-0577cfd2617c0c1ddcb04002a81738db95a1ab42.tar.gz chromium_src-0577cfd2617c0c1ddcb04002a81738db95a1ab42.tar.bz2 |
Convert file request to http request for layout test for Android.
For the limited environment of Android, we cannot host all layout test
material on Android. We implemented a 'forwarder', which can forward all
http request on Android to the same port on the host machine running
Linux/Mac. However, most layout tests are file-based tests, so we need
to convert file request to http request for layout tests.
We enable file-over-http to bridge the file protocol to http protocol
in here, which can
(1) run the layout tests on android target device, but never need to
push the test files and corresponding resources to device, which saves
huge running time.
(2) still run non-http layout (tests not under LayoutTests/http) tests
via file protocol without breaking test environment / convention of webkit
layout tests, which are followed by current all webkit ports.
BUG=
TEST=
Review URL: http://codereview.chromium.org/7901009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101441 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/support/platform_support_android.cc | 14 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_resource_loader_bridge.cc | 131 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_resource_loader_bridge.h | 12 |
3 files changed, 153 insertions, 4 deletions
diff --git a/webkit/support/platform_support_android.cc b/webkit/support/platform_support_android.cc index 1483780..d069dbc 100644 --- a/webkit/support/platform_support_android.cc +++ b/webkit/support/platform_support_android.cc @@ -10,8 +10,10 @@ #include "base/path_service.h" #include "base/string16.h" #include "base/string_piece.h" +#include "googleurl/src/gurl.h" #include "grit/webkit_resources.h" #include "ui/base/resource/resource_bundle.h" +#include "webkit/tools/test_shell/simple_resource_loader_bridge.h" namespace webkit_support { @@ -27,6 +29,18 @@ void AfterInitialize(bool unit_test_mode) { PathService::Get(base::DIR_EXE, &data_path); data_path = data_path.Append("DumpRenderTree.pak"); ResourceBundle::InitSharedInstanceForTest(data_path); + + // We enable file-over-http to bridge the file protocol to http protocol + // in here, which can + // (1) run the layout tests on android target device, but never need to + // push the test files and corresponding resources to device, which saves + // huge running time. + // (2) still run non-http layout (tests not under LayoutTests/http) tests + // via file protocol without breaking test environment / convention of webkit + // layout tests, which are followed by current all webkit ports. + SimpleResourceLoaderBridge::AllowFileOverHTTP( + "third_party/WebKit/LayoutTests/", + GURL("http://127.0.0.1:8000/all-tests/")); } void BeforeShutdown() { diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc index 9a433a2..6498e75 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc @@ -40,6 +40,7 @@ #include "base/message_loop.h" #include "base/message_loop_proxy.h" #include "base/memory/ref_counted.h" +#include "base/string_util.h" #include "base/time.h" #include "base/timer.h" #include "base/threading/thread.h" @@ -48,6 +49,7 @@ #include "net/base/file_stream.h" #include "net/base/io_buffer.h" #include "net/base/load_flags.h" +#include "net/base/mime_util.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/base/static_cookie_policy.h" @@ -102,6 +104,17 @@ TestShellRequestContext* g_request_context = NULL; base::Thread* g_cache_thread = NULL; bool g_accept_all_cookies = false; +struct FileOverHTTPParams { + FileOverHTTPParams(std::string in_file_path_template, GURL in_http_prefix) + : file_path_template(in_file_path_template), + http_prefix(in_http_prefix) {} + + std::string file_path_template; + GURL http_prefix; +}; + +FileOverHTTPParams* g_file_over_http_params = NULL; + //----------------------------------------------------------------------------- class IOThread : public base::Thread { @@ -191,6 +204,7 @@ class RequestProxy : public net::URLRequest::Delegate, peer_ = peer; owner_loop_ = MessageLoop::current(); + ConvertRequestParamsForFileOverHTTPIfNeeded(params); // proxy over to the io thread g_io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( this, &RequestProxy::AsyncStart, params)); @@ -421,6 +435,8 @@ class RequestProxy : public net::URLRequest::Delegate, DCHECK(request->status().is_success()); ResourceResponseInfo info; PopulateResponseInfo(request, &info); + // For file protocol, should never have the redirect situation. + DCHECK(!ConvertResponseInfoForFileOverHTTPIfNeeded(request, &info)); OnReceivedRedirect(new_url, info, defer_redirect); } @@ -428,8 +444,14 @@ class RequestProxy : public net::URLRequest::Delegate, if (request->status().is_success()) { ResourceResponseInfo info; PopulateResponseInfo(request, &info); - OnReceivedResponse(info); - AsyncReadData(); // start reading + // If encountering error when requesting the file, cancel the request. + if (ConvertResponseInfoForFileOverHTTPIfNeeded(request, &info) && + failed_file_request_status_.get()) { + AsyncCancel(); + } else { + OnReceivedResponse(info); + AsyncReadData(); // start reading + } } else { Done(); } @@ -486,7 +508,12 @@ class RequestProxy : public net::URLRequest::Delegate, upload_progress_timer_.Stop(); } DCHECK(request_.get()); - OnCompletedRequest(request_->status(), std::string(), base::Time()); + // If |failed_file_request_status_| is not empty, which means the request + // was a file request and encountered an error, then we need to use the + // |failed_file_request_status_|. Otherwise use request_'s status. + OnCompletedRequest(failed_file_request_status_.get() ? + *failed_file_request_status_ : request_->status(), + std::string(), base::Time()); request_.reset(); // destroy on the io thread } @@ -541,6 +568,84 @@ class RequestProxy : public net::URLRequest::Delegate, &info->appcache_manifest_url); } + // Called on owner thread + void ConvertRequestParamsForFileOverHTTPIfNeeded(RequestParams* params) { + // Reset the status. + file_url_prefix_ .clear(); + failed_file_request_status_.reset(); + // Only do this when enabling file-over-http and request is file scheme. + if (!g_file_over_http_params || !params->url.SchemeIsFile()) + return; + + // For file protocol, method must be GET or NULL. + DCHECK(params->method == "GET" || params->method.empty()); + // File protocol doesn't support upload. + DCHECK(!params->upload); + DCHECK(params->referrer.is_empty()); + DCHECK(!params->download_to_file); + + // "GET" is the only method we allow. + params->method = "GET"; + std::string original_request = params->url.spec(); + std::string::size_type found = + original_request.find(g_file_over_http_params->file_path_template); + if (found == std::string::npos) + return; + found += g_file_over_http_params->file_path_template.size(); + file_url_prefix_ = original_request.substr(0, found); + original_request.replace(0, found, + g_file_over_http_params->http_prefix.spec()); + params->url = GURL(original_request); + params->first_party_for_cookies = params->url; + // For file protocol, nerver use cache. + params->load_flags = net::LOAD_BYPASS_CACHE; + } + + // Called on IO thread. + bool ConvertResponseInfoForFileOverHTTPIfNeeded(net::URLRequest* request, + ResourceResponseInfo* info) { + // Only do this when enabling file-over-http and request url + // matches the http prefix for file-over-http feature. + if (!g_file_over_http_params || file_url_prefix_.empty()) + return false; + std::string original_request = request->url().spec(); + std::string http_prefix = g_file_over_http_params->http_prefix.spec(); + DCHECK(!original_request.empty() && + StartsWithASCII(original_request, http_prefix, true)); + // Get the File URL. + original_request.replace(0, http_prefix.size(), file_url_prefix_); + + FilePath file_path; + if (!net::FileURLToFilePath(GURL(original_request), &file_path)) { + NOTREACHED(); + } + + info->mime_type.clear(); + DCHECK(info->headers); + int status_code = info->headers->response_code(); + // File protocol does not support response headers. + info->headers = NULL; + if (200 == status_code) { + // Don't use the MIME type from HTTP server, use net::GetMimeTypeFromFile + // instead. + net::GetMimeTypeFromFile(file_path, &info->mime_type); + } else { + // If the file does not exist, immediately call OnCompletedRequest with + // setting URLRequestStatus to FAILED. + DCHECK(status_code == 404 || status_code == 403); + if (status_code == 404) { + failed_file_request_status_.reset( + new net::URLRequestStatus(net::URLRequestStatus::FAILED, + net::ERR_FILE_NOT_FOUND)); + } else { + failed_file_request_status_.reset( + new net::URLRequestStatus(net::URLRequestStatus::FAILED, + net::ERR_ACCESS_DENIED)); + } + } + return true; + } + scoped_ptr<net::URLRequest> request_; // Support for request.download_to_file behavior. @@ -567,6 +672,11 @@ class RequestProxy : public net::URLRequest::Delegate, // Info used to determine whether or not to send an upload progress update. uint64 last_upload_position_; base::TimeTicks last_upload_ticks_; + + // Save the real FILE URL prefix for the FILE URL which converts to HTTP URL. + std::string file_url_prefix_; + // Save a failed file request status to pass it to webkit. + scoped_ptr<net::URLRequestStatus> failed_file_request_status_; }; //----------------------------------------------------------------------------- @@ -834,6 +944,11 @@ void SimpleResourceLoaderBridge::Shutdown() { } else { delete g_request_context_params; g_request_context_params = NULL; + + if (g_file_over_http_params) { + delete g_file_over_http_params; + g_file_over_http_params = NULL; + } } } @@ -914,3 +1029,13 @@ scoped_refptr<base::MessageLoopProxy> } return g_io_thread->message_loop_proxy(); } + +// static +void SimpleResourceLoaderBridge::AllowFileOverHTTP( + const std::string& file_path_template, const GURL& http_prefix) { + DCHECK(!file_path_template.empty()); + DCHECK(http_prefix.is_valid() && + (http_prefix.SchemeIs("http") || http_prefix.SchemeIs("https"))); + g_file_over_http_params = new FileOverHTTPParams(file_path_template, + http_prefix); +} diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.h b/webkit/tools/test_shell/simple_resource_loader_bridge.h index aa6ebd4..ba00544 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.h +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -42,6 +42,16 @@ class SimpleResourceLoaderBridge { // Init(), and destroyed upon a call to ShutDown(). static scoped_refptr<base::MessageLoopProxy> GetCacheThread(); static scoped_refptr<base::MessageLoopProxy> GetIoThread(); + + // Call this function to set up whether using file-over-http feature. + // |file_over_http| indicates whether using file-over-http or not. + // If yes, when the request url uses file scheme and matches sub string + // |file_path_template|, SimpleResourceLoaderBridge will use |http_prefix| + // plus string of after |file_path_template| in original request URl to + // generate a new http URL to get the data and send back to peer. + // That is how we implement file-over-http feature. + static void AllowFileOverHTTP(const std::string& file_path_template, + const GURL& http_prefix); }; #endif // WEBKIT_TOOLS_TEST_SHELL_SIMPLE_RESOURCE_LOADER_BRIDGE_H__ |