summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-10 20:30:34 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-10 20:30:34 +0000
commit61d74983f154e4b6d3e8501b212be6b27de3c500 (patch)
tree1cbcc9b05c45dac5151ebdcde1b24784897b9801
parentbac96616d3ffdda096b65155c7dd9c2fd3d5bc4a (diff)
downloadchromium_src-61d74983f154e4b6d3e8501b212be6b27de3c500.zip
chromium_src-61d74983f154e4b6d3e8501b212be6b27de3c500.tar.gz
chromium_src-61d74983f154e4b6d3e8501b212be6b27de3c500.tar.bz2
Give the filter setup more context so it can figure out whether it's downloading a file or not. Only refuse to gunzip svgz files on download, so we can send an uncompressed svgz file to webkit.
BUG=9737 Review URL: http://codereview.chromium.org/62111 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13536 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc2
-rw-r--r--net/base/filter.cc7
-rw-r--r--net/base/filter.h3
-rw-r--r--net/base/filter_unittest.cc64
-rw-r--r--net/base/filter_unittest.h6
-rw-r--r--net/base/load_flags.h5
-rw-r--r--net/url_request/url_request_job.cc6
-rw-r--r--net/url_request/url_request_job.h6
8 files changed, 90 insertions, 9 deletions
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index 9538d7f..3169786 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -524,6 +524,8 @@ void ResourceDispatcherHost::BeginDownload(const GURL& url,
request->set_method("GET");
request->set_referrer(referrer.spec());
request->set_context(request_context);
+ request->set_load_flags(request->load_flags() |
+ net::LOAD_IS_DOWNLOAD);
ExtraRequestInfo* extra_info =
new ExtraRequestInfo(handler,
diff --git a/net/base/filter.cc b/net/base/filter.cc
index d0e950c..73cafd4 100644
--- a/net/base/filter.cc
+++ b/net/base/filter.cc
@@ -104,9 +104,14 @@ void Filter::FixupEncodingTypes(
// Firefox does not apply the filter to the following extensions.
// See Firefox's nsHttpChannel::nsContentEncodings::GetNext() and
// nonDecodableExtensions in nsExternalHelperAppService.cpp
+ // For the case of svgz files, we use the extension to distinguish
+ // between svgz files and svg files compressed with gzip by the server.
+ // When viewing a .svgz file, we need to uncompress it, but we don't
+ // want to do that when downloading.
if (0 == extension.compare(FILE_PATH_LITERAL(".gz")) ||
0 == extension.compare(FILE_PATH_LITERAL(".tgz")) ||
- 0 == extension.compare(FILE_PATH_LITERAL(".svgz"))) {
+ (0 == extension.compare(FILE_PATH_LITERAL(".svgz")) &&
+ filter_context.IsDownload())) {
encoding_types->clear();
}
}
diff --git a/net/base/filter.h b/net/base/filter.h
index e944918..852faba 100644
--- a/net/base/filter.h
+++ b/net/base/filter.h
@@ -65,6 +65,9 @@ class FilterContext {
// Is data supplied from cache, or fresh across the net?
virtual bool IsCachedContent() const = 0;
+ // Is this a download?
+ virtual bool IsDownload() const = 0;
+
// Was this data flagged as a response to a request with an SDCH dictionary?
virtual bool IsSdchResponse() const = 0;
diff --git a/net/base/filter_unittest.cc b/net/base/filter_unittest.cc
index 999a1e6..7a29867 100644
--- a/net/base/filter_unittest.cc
+++ b/net/base/filter_unittest.cc
@@ -77,7 +77,7 @@ TEST(FilterTest, ApacheGzip) {
encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
filter_context.SetMimeType(kGzipMime1);
Filter::FixupEncodingTypes(filter_context, &encoding_types);
- EXPECT_EQ(1U, encoding_types.size());
+ ASSERT_EQ(1U, encoding_types.size());
EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types.front());
// Check to be sure that gzip can survive with other mime types.
@@ -85,7 +85,7 @@ TEST(FilterTest, ApacheGzip) {
encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
filter_context.SetMimeType("other/mime");
Filter::FixupEncodingTypes(filter_context, &encoding_types);
- EXPECT_EQ(1U, encoding_types.size());
+ ASSERT_EQ(1U, encoding_types.size());
EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
}
@@ -104,7 +104,7 @@ TEST(FilterTest, SdchEncoding) {
encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
filter_context.SetMimeType(kTextHtmlMime);
Filter::FixupEncodingTypes(filter_context, &encoding_types);
- EXPECT_EQ(2U, encoding_types.size());
+ ASSERT_EQ(2U, encoding_types.size());
EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
@@ -114,7 +114,7 @@ TEST(FilterTest, SdchEncoding) {
encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
filter_context.SetMimeType("other/type");
Filter::FixupEncodingTypes(filter_context, &encoding_types);
- EXPECT_EQ(2U, encoding_types.size());
+ ASSERT_EQ(2U, encoding_types.size());
EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types[1]);
@@ -122,7 +122,7 @@ TEST(FilterTest, SdchEncoding) {
encoding_types.clear();
encoding_types.push_back(Filter::FILTER_TYPE_SDCH);
Filter::FixupEncodingTypes(filter_context, &encoding_types);
- EXPECT_EQ(2U, encoding_types.size());
+ ASSERT_EQ(2U, encoding_types.size());
EXPECT_EQ(Filter::FILTER_TYPE_SDCH, encoding_types[0]);
EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
}
@@ -140,7 +140,7 @@ TEST(FilterTest, MissingSdchEncoding) {
encoding_types.clear();
filter_context.SetMimeType(kTextHtmlMime);
Filter::FixupEncodingTypes(filter_context, &encoding_types);
- EXPECT_EQ(2U, encoding_types.size());
+ ASSERT_EQ(2U, encoding_types.size());
EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
@@ -152,7 +152,7 @@ TEST(FilterTest, MissingSdchEncoding) {
encoding_types.clear();
filter_context.SetMimeType("text/html; charset=UTF-8");
Filter::FixupEncodingTypes(filter_context, &encoding_types);
- EXPECT_EQ(2U, encoding_types.size());
+ ASSERT_EQ(2U, encoding_types.size());
EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
@@ -160,7 +160,55 @@ TEST(FilterTest, MissingSdchEncoding) {
encoding_types.clear();
filter_context.SetMimeType("other/mime");
Filter::FixupEncodingTypes(filter_context, &encoding_types);
- EXPECT_EQ(2U, encoding_types.size());
+ ASSERT_EQ(2U, encoding_types.size());
EXPECT_EQ(Filter::FILTER_TYPE_SDCH_POSSIBLE, encoding_types[0]);
EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
}
+
+TEST(FilterTest, Svgz) {
+ const int kInputBufferSize(100);
+ MockFilterContext filter_context(kInputBufferSize);
+
+ // Check that svgz files are only decompressed when not downloading.
+ const std::string kSvgzMime("image/svg+xml");
+ const std::string kSvgzUrl("http://ignore.com/foo.svgz");
+ const std::string kSvgUrl("http://ignore.com/foo.svg");
+ std::vector<Filter::FilterType> encoding_types;
+
+ // Test svgz extension
+ encoding_types.clear();
+ encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
+ filter_context.SetDownload(false);
+ filter_context.SetMimeType(kSvgzMime);
+ filter_context.SetURL(GURL(kSvgzUrl));
+ Filter::FixupEncodingTypes(filter_context, &encoding_types);
+ ASSERT_EQ(1U, encoding_types.size());
+ EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
+
+ encoding_types.clear();
+ encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
+ filter_context.SetDownload(true);
+ filter_context.SetMimeType(kSvgzMime);
+ filter_context.SetURL(GURL(kSvgzUrl));
+ Filter::FixupEncodingTypes(filter_context, &encoding_types);
+ EXPECT_TRUE(encoding_types.empty());
+
+ // Test svg extension
+ encoding_types.clear();
+ encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
+ filter_context.SetDownload(false);
+ filter_context.SetMimeType(kSvgzMime);
+ filter_context.SetURL(GURL(kSvgUrl));
+ Filter::FixupEncodingTypes(filter_context, &encoding_types);
+ ASSERT_EQ(1U, encoding_types.size());
+ EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
+
+ encoding_types.clear();
+ encoding_types.push_back(Filter::FILTER_TYPE_GZIP);
+ filter_context.SetDownload(true);
+ filter_context.SetMimeType(kSvgzMime);
+ filter_context.SetURL(GURL(kSvgUrl));
+ Filter::FixupEncodingTypes(filter_context, &encoding_types);
+ ASSERT_EQ(1U, encoding_types.size());
+ EXPECT_EQ(Filter::FILTER_TYPE_GZIP, encoding_types.front());
+}
diff --git a/net/base/filter_unittest.h b/net/base/filter_unittest.h
index 8ed572f..a15ae59 100644
--- a/net/base/filter_unittest.h
+++ b/net/base/filter_unittest.h
@@ -17,6 +17,7 @@ class MockFilterContext : public FilterContext {
explicit MockFilterContext(int buffer_size)
: buffer_size_(buffer_size),
is_cached_content_(false),
+ is_download_(false),
is_sdch_response_(false),
response_code_(-1) {
}
@@ -26,6 +27,7 @@ class MockFilterContext : public FilterContext {
void SetURL(const GURL& gurl) { gurl_ = gurl; }
void SetRequestTime(const base::Time time) { request_time_ = time; }
void SetCached(bool is_cached) { is_cached_content_ = is_cached; }
+ void SetDownload(bool is_download) { is_download_ = is_download; }
void SetResponseCode(int response_code) { response_code_ = response_code; }
void SetSdchResponse(bool is_sdch_response) {
is_sdch_response_ = is_sdch_response;
@@ -51,6 +53,9 @@ class MockFilterContext : public FilterContext {
// Is data supplied from cache, or fresh across the net?
virtual bool IsCachedContent() const { return is_cached_content_; }
+ // Is this a download?
+ virtual bool IsDownload() const { return is_download_; }
+
// Was this data flagged as a response to a request with an SDCH dictionary?
virtual bool IsSdchResponse() const { return is_sdch_response_; }
@@ -69,6 +74,7 @@ class MockFilterContext : public FilterContext {
GURL gurl_;
base::Time request_time_;
bool is_cached_content_;
+ bool is_download_;
bool is_sdch_response_;
int response_code_;
diff --git a/net/base/load_flags.h b/net/base/load_flags.h
index 354980c..c2c0d20 100644
--- a/net/base/load_flags.h
+++ b/net/base/load_flags.h
@@ -38,6 +38,8 @@ enum {
LOAD_ENABLE_UPLOAD_PROGRESS = 1 << 6,
// If present, try to download the resource to a standalone file.
+ // This hint tells the http cache to provide a native file handle
+ // of the cached file to the renderer process.
LOAD_ENABLE_DOWNLOAD_FILE = 1 << 7,
// If present, ignores certificate mismatches with the domain name.
@@ -71,6 +73,9 @@ enum {
// Do not resolve proxies. This override is used when downloading PAC files
// to avoid having a circular dependency.
LOAD_BYPASS_PROXY = 1 << 15,
+
+ // Indicate this request is for a download, as opposed to viewing.
+ LOAD_IS_DOWNLOAD = 1 << 16,
};
} // namespace net
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 4075ede..b5309c2 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -9,6 +9,7 @@
#include "googleurl/src/gurl.h"
#include "net/base/auth.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job_metrics.h"
@@ -30,6 +31,7 @@ URLRequestJob::URLRequestJob(URLRequest* request)
has_handled_response_(false),
expected_content_size_(-1),
filter_input_byte_count_(0) {
+ load_flags_ = request_->load_flags();
is_profiling_ = request->enable_profiling();
if (is_profiling()) {
metrics_.reset(new URLRequestJobMetrics());
@@ -53,6 +55,10 @@ void URLRequestJob::DetachRequest() {
request_ = NULL;
}
+bool URLRequestJob::IsDownload() const {
+ return (load_flags_ & net::LOAD_IS_DOWNLOAD) != 0;
+}
+
void URLRequestJob::SetupFilter() {
std::vector<Filter::FilterType> encoding_types;
if (GetContentEncodings(&encoding_types)) {
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
index c120bf1..2289ce7 100644
--- a/net/url_request/url_request_job.h
+++ b/net/url_request/url_request_job.h
@@ -119,6 +119,9 @@ class URLRequestJob : public base::RefCountedThreadSafe<URLRequestJob>,
return false;
}
+ // Find out if this is a download.
+ virtual bool IsDownload() const;
+
// Find out if this is a response to a request that advertised an SDCH
// dictionary. Only makes sense for some types of requests.
virtual bool IsSdchResponse() const { return false; }
@@ -293,6 +296,9 @@ class URLRequestJob : public base::RefCountedThreadSafe<URLRequestJob>,
// NotifyDone so that it is kept in sync with the request.
bool done_;
+ // Cache the load flags from request_ because it might go away.
+ int load_flags_;
+
// The data stream filter which is enabled on demand.
scoped_ptr<Filter> filter_;