diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-04 20:01:45 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-04 20:01:45 +0000 |
commit | 56d83182c6d4c815aab837e82ccccc6103bc4b6a (patch) | |
tree | 34944feee64dfe06f287c1ab6a063144e4c3958f /chrome | |
parent | 42f4f8bc7eb5b3d7e5af6b066c13e70d39e60d5d (diff) | |
download | chromium_src-56d83182c6d4c815aab837e82ccccc6103bc4b6a.zip chromium_src-56d83182c6d4c815aab837e82ccccc6103bc4b6a.tar.gz chromium_src-56d83182c6d4c815aab837e82ccccc6103bc4b6a.tar.bz2 |
Intercept HTTP requests for documents that GView is capable of displaying (such
as pdf) and redirect the user to the appropriate URL for viewing.
Original patch by skrulx@gmail.com
http://codereview.chromium.org/174016
Review URL: http://codereview.chromium.org/199019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25496 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser_init.cc | 8 | ||||
-rw-r--r-- | chrome/browser/chromeos/gview_request_interceptor.cc | 63 | ||||
-rw-r--r-- | chrome/browser/chromeos/gview_request_interceptor.h | 41 | ||||
-rw-r--r-- | chrome/browser/chromeos/gview_request_interceptor_unittest.cc | 99 | ||||
-rw-r--r-- | chrome/chrome.gyp | 3 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 |
7 files changed, 219 insertions, 0 deletions
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc index 0accf67..2d87070 100644 --- a/chrome/browser/browser_init.cc +++ b/chrome/browser/browser_init.cc @@ -65,6 +65,7 @@ #endif #if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/gview_request_interceptor.h" #include "chrome/browser/views/tabs/tab_overview_message_listener.h" #endif @@ -349,6 +350,13 @@ bool LaunchBrowser(const CommandLine& command_line, Profile* profile, // Create the TabOverviewMessageListener so that it can listen for messages // regardless of what window has focus. TabOverviewMessageListener::instance(); + + // Install the GView request interceptor that will redirect requests + // of compatible documents (PDF, etc) to the GView document viewer. + const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); + if (parsed_command_line.HasSwitch(switches::kEnableGView)) { + GViewRequestInterceptor::GetGViewRequestInterceptor(); + } #endif return true; } diff --git a/chrome/browser/chromeos/gview_request_interceptor.cc b/chrome/browser/chromeos/gview_request_interceptor.cc new file mode 100644 index 0000000..735424b --- /dev/null +++ b/chrome/browser/chromeos/gview_request_interceptor.cc @@ -0,0 +1,63 @@ +// Copyright (c) 2009 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. + +#include "chrome/browser/chromeos/gview_request_interceptor.h" + +#include "net/base/escape.h" +#include "net/base/load_flags.h" +#include "net/url_request/url_request_job.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_redirect_job.h" +#include "googleurl/src/gurl.h" + +// This is the list of mime types currently supported by the Google +// Document Viewer. +static const char* const supported_mime_type_list[] = { + "application/pdf", + "application/vnd.ms-powerpoint" +}; + +static const char* const kGViewUrlPrefix = "http://docs.google.com/gview?url="; + +GViewRequestInterceptor::GViewRequestInterceptor() { + URLRequest::RegisterRequestInterceptor(this); + for (size_t i = 0; i < arraysize(supported_mime_type_list); ++i) { + supported_mime_types_.insert(supported_mime_type_list[i]); + } +} + +GViewRequestInterceptor::~GViewRequestInterceptor() { + URLRequest::UnregisterRequestInterceptor(this); +} + +URLRequestJob* GViewRequestInterceptor::MaybeIntercept(URLRequest* request) { + // Don't attempt to intercept here as we want to wait until the mime + // type is fully determined. + return NULL; +} + +URLRequestJob* GViewRequestInterceptor::MaybeInterceptResponse( + URLRequest* request) { + // Do not intercept this request if it is a download. + if (request->load_flags() & net::LOAD_IS_DOWNLOAD) { + return NULL; + } + + std::string mime_type; + request->GetMimeType(&mime_type); + // If supported, build the URL to the Google Document Viewer + // including the origial document's URL, then create a new job that + // will redirect the browser to this new URL. + if (supported_mime_types_.count(mime_type) > 0) { + std::string url(kGViewUrlPrefix); + url += EscapePath(request->url().spec()); + return new URLRequestRedirectJob(request, GURL(url)); + } + return NULL; +} + +URLRequest::Interceptor* GViewRequestInterceptor::GetGViewRequestInterceptor() { + return Singleton<GViewRequestInterceptor>::get(); +} + diff --git a/chrome/browser/chromeos/gview_request_interceptor.h b/chrome/browser/chromeos/gview_request_interceptor.h new file mode 100644 index 0000000..ca6d2ae --- /dev/null +++ b/chrome/browser/chromeos/gview_request_interceptor.h @@ -0,0 +1,41 @@ +// Copyright (c) 2009 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. + +#ifndef CHROME_BROWSER_CHROMEOS_GVIEW_REQUEST_INTERCEPTOR_H__ +#define CHROME_BROWSER_CHROMEOS_GVIEW_REQUEST_INTERCEPTOR_H__ + +#include <string> +#include "base/hash_tables.h" +#include "net/url_request/url_request.h" + +// This class integrates the Google Document Viewer into ChromeOS, +// enabling the viewing of supported document types that the user +// clicks on. This class will intercept requests to supported +// document types (such as PDF) and redirect the request to the Google +// Document Viewer, including the document's original URL as a +// parameter. +class GViewRequestInterceptor : public URLRequest::Interceptor { + public: + GViewRequestInterceptor(); + virtual ~GViewRequestInterceptor(); + + // Always returns NULL because we don't want to attempt a redirect + // before seeing the detected mime type of the request. + virtual URLRequestJob* MaybeIntercept(URLRequest* request); + + // Determines if the requested document can be viewed by the Google + // Document Viewer. If it can, returns a URLRequestJob that + // redirects the browser to the view URL. + virtual URLRequestJob* MaybeInterceptResponse(URLRequest* request); + + // Singleton accessor. + static URLRequest::Interceptor* GetGViewRequestInterceptor(); + + private: + // The list of supported mime types. + base::hash_set<std::string> supported_mime_types_; +}; + +#endif // CHROME_BROWSER_CHROMEOS_GVIEW_REQUEST_INTERCEPTOR_H__ + diff --git a/chrome/browser/chromeos/gview_request_interceptor_unittest.cc b/chrome/browser/chromeos/gview_request_interceptor_unittest.cc new file mode 100644 index 0000000..61978a7 --- /dev/null +++ b/chrome/browser/chromeos/gview_request_interceptor_unittest.cc @@ -0,0 +1,99 @@ +// Copyright (c) 2009 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. + +#include <string> +#include "base/message_loop.h" +#include "chrome/browser/chromeos/gview_request_interceptor.h" +#include "net/base/load_flags.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_job.h" +#include "net/url_request/url_request_test_job.h" +#include "net/url_request/url_request_unittest.h" +#include "testing/gtest/include/gtest/gtest.h" + +class GViewURLRequestTestJob : public URLRequestTestJob { + public: + explicit GViewURLRequestTestJob(URLRequest* request) + : URLRequestTestJob(request, true) { + } + + virtual bool GetMimeType(std::string* mime_type) const { + // During the course of a single test, two URLRequestJobs are + // created -- the first is for the viewable document URL, and the + // second is for the rediected URL. In order to test the + // interceptor, the mime type of the first request must be one of + // the supported viewable mime types. So when the URLRequestJob + // is a request for one of the test URLs that point to viewable + // content, return an appropraite mime type. Otherwise, return + // "text/html". + if (request_->url() == GURL("http://foo.com/file.pdf")) { + *mime_type = "application/pdf"; + } else if (request_->url() == GURL("http://foo.com/file.ppt")) { + *mime_type = "application/vnd.ms-powerpoint"; + } else { + *mime_type = "text/html"; + } + return true; + } +}; + +class GViewRequestInterceptorTest : public testing::Test { + public: + virtual void SetUp() { + URLRequest::RegisterProtocolFactory("http", + &GViewRequestInterceptorTest::Factory); + interceptor_ = GViewRequestInterceptor::GetGViewRequestInterceptor(); + } + + virtual void TearDown() { + URLRequest::RegisterProtocolFactory("http", NULL); + message_loop_.RunAllPending(); + } + + static URLRequestJob* Factory(URLRequest* request, + const std::string& scheme) { + return new GViewURLRequestTestJob(request); + } + + protected: + MessageLoopForIO message_loop_; + TestDelegate test_delegate_; + URLRequest::Interceptor* interceptor_; +}; + +TEST_F(GViewRequestInterceptorTest, DoNotInterceptHtml) { + URLRequest request(GURL("http://foo.com/index.html"), &test_delegate_); + request.Start(); + MessageLoop::current()->Run(); + EXPECT_EQ(0, test_delegate_.received_redirect_count()); + EXPECT_EQ(GURL("http://foo.com/index.html"), request.url()); +} + +TEST_F(GViewRequestInterceptorTest, DoNotInterceptDownload) { + URLRequest request(GURL("http://foo.com/file.pdf"), &test_delegate_); + request.set_load_flags(net::LOAD_IS_DOWNLOAD); + request.Start(); + MessageLoop::current()->Run(); + EXPECT_EQ(0, test_delegate_.received_redirect_count()); + EXPECT_EQ(GURL("http://foo.com/file.pdf"), request.url()); +} + +TEST_F(GViewRequestInterceptorTest, InterceptPdf) { + URLRequest request(GURL("http://foo.com/file.pdf"), &test_delegate_); + request.Start(); + MessageLoop::current()->Run(); + EXPECT_EQ(1, test_delegate_.received_redirect_count()); + EXPECT_EQ(GURL("http://docs.google.com/gview?url=http%3A//foo.com/file.pdf"), + request.url()); +} + +TEST_F(GViewRequestInterceptorTest, InterceptPowerpoint) { + URLRequest request(GURL("http://foo.com/file.ppt"), &test_delegate_); + request.Start(); + MessageLoop::current()->Run(); + EXPECT_EQ(1, test_delegate_.received_redirect_count()); + EXPECT_EQ(GURL("http://docs.google.com/gview?url=http%3A//foo.com/file.ppt"), + request.url()); +} + diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 2a3affa..a5e1440 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -829,6 +829,8 @@ 'browser/chromeos/pipe_reader.h', 'browser/chromeos/external_cookie_handler.cc', 'browser/chromeos/external_cookie_handler.h', + 'browser/chromeos/gview_request_interceptor.cc', + 'browser/chromeos/gview_request_interceptor.h', 'browser/chromeos/settings_page_view.cc', 'browser/chromeos/settings_page_view.h', 'browser/chromeos/status_area_view.cc', @@ -3956,6 +3958,7 @@ 'browser/chromeos/chromeos_version_loader_unittest.cc', 'browser/chromeos/pipe_reader_unittest.cc', 'browser/chromeos/external_cookie_handler_unittest.cc', + 'browser/chromeos/gview_request_interceptor_unittest.cc', # It is safe to list */cocoa/* files in the "common" file list # without an explicit exclusion since gyp is smart enough to # exclude them from non-Mac builds. diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 705f5a2..95e29e2 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -597,6 +597,10 @@ const wchar_t kSyncServiceURL[] = L"sync-url"; // The name of the pipe over which the Chrome OS login manager will send // single-sign-on cookies. const wchar_t kCookiePipe[] = L"cookie-pipe"; + +// Enable the redirection of viewable document requests to the Google +// Document Viewer. +const wchar_t kEnableGView[] = L"enable-gview"; #endif // Enable experimental support for cached byte-ranges. diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 4cfbff8..59cd449 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -239,6 +239,7 @@ extern const wchar_t kSyncServiceURL[]; #if defined(OS_CHROMEOS) extern const wchar_t kCookiePipe[]; +extern const wchar_t kEnableGView[]; #endif extern const wchar_t kEnableByteRangeSupport[]; |