summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authordavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-04 20:01:45 +0000
committerdavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-04 20:01:45 +0000
commit56d83182c6d4c815aab837e82ccccc6103bc4b6a (patch)
tree34944feee64dfe06f287c1ab6a063144e4c3958f /chrome
parent42f4f8bc7eb5b3d7e5af6b066c13e70d39e60d5d (diff)
downloadchromium_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.cc8
-rw-r--r--chrome/browser/chromeos/gview_request_interceptor.cc63
-rw-r--r--chrome/browser/chromeos/gview_request_interceptor.h41
-rw-r--r--chrome/browser/chromeos/gview_request_interceptor_unittest.cc99
-rw-r--r--chrome/chrome.gyp3
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h1
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[];