Index: content/browser/webui/url_data_manager_backend.cc |
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc |
index 4274eeb8fadc0a0684c9b980a23f337ab2655e55..9fd75219ce82872b48ee4e5540f7b7abe760a8a5 100644 |
--- a/content/browser/webui/url_data_manager_backend.cc |
+++ b/content/browser/webui/url_data_manager_backend.cc |
@@ -4,6 +4,7 @@ |
#include "content/browser/webui/url_data_manager_backend.h" |
+#include <algorithm> |
#include <set> |
#include "base/bind.h" |
@@ -47,6 +48,7 @@ |
#include "net/url_request/url_request_error_job.h" |
#include "net/url_request/url_request_job.h" |
#include "net/url_request/url_request_job_factory.h" |
+#include "ui/base/template_expressions.h" |
#include "url/url_util.h" |
namespace content { |
@@ -370,8 +372,69 @@ void URLRequestChromeJob::GetResponseInfo(net::HttpResponseInfo* info) { |
info->headers->AddHeader("Content-Encoding: gzip"); |
} |
+class I18nFilter : public net::Filter { |
+ public: |
+ I18nFilter(const ui::TemplateReplacements* replacements) |
+ : net::Filter(net::Filter::FILTER_TYPE_UNSUPPORTED), |
+ replacements_(replacements) { |
+ CHECK(replacements_); |
+ } |
+ |
+ net::Filter::FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override { |
+ if (!dest_buffer || !dest_len) |
+ return net::Filter::FILTER_ERROR; |
+ |
+ if (*dest_len <= 0) { |
+ *dest_len = 0; |
+ return net::Filter::FILTER_ERROR; |
+ } |
+ |
+ if (stream_data_len_) { |
+ decoded_.append(next_stream_data_, stream_data_len_); |
+ return net::Filter::FILTER_NEED_MORE_DATA; |
+ } |
+ |
+ if (!replaced_) { |
+ decoded_ = ui::ReplaceTemplateExpressions(base::StringPiece(decoded_), *replacements_); |
+ replaced_ = true; |
+ } |
+ |
+ *dest_len = std::min(static_cast<int>(decoded_.size()), *dest_len); |
+ memcpy(dest_buffer, decoded_.data(), *dest_len); |
+ decoded_.erase(0, *dest_len); |
+ return decoded_.empty() ? net::Filter::FILTER_DONE : |
+ net::Filter::FILTER_OK; |
+ } |
+ |
+ private: |
+ const ui::TemplateReplacements* replacements_; // weak |
+ std::string decoded_; |
+ bool replaced_ = false; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(I18nFilter); |
+}; |
+ |
std::unique_ptr<net::Filter> URLRequestChromeJob::SetupFilter() const { |
- return is_gzipped_ ? net::Filter::GZipFactory() : nullptr; |
+ URLDataSourceImpl* data_source = |
+ backend_->GetDataSourceFromURL(request_->url()); |
+ |
+ const ui::TemplateReplacements* replacements = data_source ? |
+ data_source->GetTemplateReplacements() : nullptr; |
+ |
+ std::unique_ptr<net::Filter> i18n_filter; |
+ |
+ if (replacements) |
+ i18n_filter = base::MakeUnique<I18nFilter>(replacements); |
+ |
+ if (!is_gzipped_) |
+ return i18n_filter; |
+ |
+ std::unique_ptr<net::Filter> gzip_filter = net::Filter::GZipFactory(); |
+ |
+ if (i18n_filter) |
+ gzip_filter->TakeNextFilter(std::move(i18n_filter)); |
+ |
+ return gzip_filter; |
} |
void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) { |