#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
#include <string>
+#include <vector>
#include "base/base64.h"
+#include "base/guid.h"
#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/streams_private/streams_private_api.h"
#include "chrome/browser/extensions/extension_renderer_state.h"
#include "chrome/browser/extensions/user_script_listener.h"
-#include "chrome/browser/google/google_util.h"
#include "chrome/browser/metrics/variations/variations_http_header_provider.h"
#include "chrome/browser/prefetch/prefetch.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
+#include "components/google/core/browser/google_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#endif
#if defined(ENABLE_MANAGED_USERS)
-#include "chrome/browser/managed_mode/managed_mode_resource_throttle.h"
+#include "chrome/browser/supervised_user/supervised_user_resource_throttle.h"
#endif
#if defined(USE_SYSTEM_PROTOBUF)
#endif
#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/login/merge_session_throttle.h"
+#include "chrome/browser/chromeos/login/signin/merge_session_throttle.h"
// TODO(oshima): Enable this for other platforms.
#include "chrome/browser/renderer_host/offline_resource_throttle.h"
#endif
}
#if !defined(OS_ANDROID)
-// Goes through the extension's file browser handlers and checks if there is one
-// that can handle the |mime_type|.
-// |extension| must not be NULL.
-bool ExtensionCanHandleMimeType(const Extension* extension,
- const std::string& mime_type) {
- MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
- if (!handler)
- return false;
-
- return handler->CanHandleMIMEType(mime_type);
-}
-
void SendExecuteMimeTypeHandlerEvent(scoped_ptr<content::StreamHandle> stream,
int64 expected_content_size,
int render_process_id,
int render_view_id,
- const std::string& extension_id) {
+ const std::string& extension_id,
+ const std::string& view_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
content::WebContents* web_contents =
if (!streams_private)
return;
streams_private->ExecuteMimeTypeHandler(
- extension_id, web_contents, stream.Pass(), expected_content_size);
+ extension_id, web_contents, stream.Pass(), view_id,
+ expected_content_size);
}
-void LaunchURL(const GURL& url, int render_process_id, int render_view_id,
- bool user_gesture) {
+void LaunchURL(const GURL& url, int render_process_id, int render_view_id) {
// If there is no longer a WebContents, the request may have raced with tab
// closing. Don't fire the external request. (It may have been a prerender.)
content::WebContents* web_contents =
}
ExternalProtocolHandler::LaunchUrlWithDelegate(
- url, render_process_id, render_view_id,
- g_external_protocol_handler_delegate,
- user_gesture);
+ url,
+ render_process_id,
+ render_view_id,
+ g_external_protocol_handler_delegate);
}
#endif // !defined(OS_ANDROID)
if (crx_id) {
// We got a component we need to install, so throttle the resource
// until the component is installed.
- throttles->push_back(cus->GetOnDemandResourceThrottle(request, crx_id));
+ throttles->push_back(
+ cus->GetOnDemandUpdater().GetOnDemandResourceThrottle(request, crx_id));
}
}
}
ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() {
+ CHECK(stream_target_info_.empty());
}
bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest(
ProfileIOData* io_data = ProfileIOData::FromResourceContext(
resource_context);
- if (!is_prerendering && resource_type == ResourceType::MAIN_FRAME) {
#if defined(OS_ANDROID)
+ // TODO(davidben): This is insufficient to integrate with prerender properly.
+ // https://crbug.com/370595
+ if (resource_type == ResourceType::MAIN_FRAME && !is_prerendering) {
throttles->push_back(
InterceptNavigationDelegate::CreateThrottleFor(request));
+ }
#else
+ if (resource_type == ResourceType::MAIN_FRAME) {
// Redirect some navigations to apps that have registered matching URL
// handlers ('url_handlers' in the manifest).
content::ResourceThrottle* url_to_app_throttle =
if (url_to_app_throttle)
throttles->push_back(url_to_app_throttle);
- // Experimental: Launch ephemeral apps from search results.
- content::ResourceThrottle* ephemeral_app_throttle =
- EphemeralAppThrottle::MaybeCreateThrottleForLaunch(
- request, io_data);
- if (ephemeral_app_throttle)
- throttles->push_back(ephemeral_app_throttle);
-#endif
+ if (!is_prerendering) {
+ // Experimental: Launch ephemeral apps from search results.
+ content::ResourceThrottle* ephemeral_app_throttle =
+ EphemeralAppThrottle::MaybeCreateThrottleForLaunch(
+ request, io_data);
+ if (ephemeral_app_throttle)
+ throttles->push_back(ephemeral_app_throttle);
+ }
}
+#endif
#if defined(OS_CHROMEOS)
// Check if we need to add offline throttle. This should be done only
#if defined(ENABLE_CONFIGURATION_POLICY)
if (io_data->policy_header_helper())
- io_data->policy_header_helper()->AddPolicyHeaders(request);
+ io_data->policy_header_helper()->AddPolicyHeaders(request->url(), request);
#endif
signin::AppendMirrorRequestHeaderIfPossible(
new DownloadResourceThrottle(download_request_limiter_.get(),
child_id,
route_id,
- request_id,
+ request->url(),
request->method()));
#if defined(OS_ANDROID)
throttles->push_back(
bool ChromeResourceDispatcherHostDelegate::HandleExternalProtocol(
const GURL& url,
int child_id,
- int route_id,
- bool initiated_by_user_gesture) {
+ int route_id) {
#if defined(OS_ANDROID)
// Android use a resource throttle to handle external as well as internal
// protocols.
return false;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&LaunchURL, url, child_id, route_id,
- initiated_by_user_gesture));
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&LaunchURL, url, child_id, route_id));
return true;
#endif
}
#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
// Insert safe browsing at the front of the list, so it gets to decide on
// policies first.
- if (io_data->safe_browsing_enabled()->GetValue()) {
+ if (io_data->safe_browsing_enabled()->GetValue()
+#if defined(OS_ANDROID)
+ || io_data->data_reduction_proxy_enabled()->GetValue()
+#endif
+ ) {
bool is_subresource_request = resource_type != ResourceType::MAIN_FRAME;
content::ResourceThrottle* throttle =
SafeBrowsingResourceThrottleFactory::Create(request,
+ resource_context,
is_subresource_request,
safe_browsing_.get());
if (throttle)
#if defined(ENABLE_MANAGED_USERS)
bool is_subresource_request = resource_type != ResourceType::MAIN_FRAME;
- throttles->push_back(new ManagedModeResourceThrottle(
+ throttles->push_back(new SupervisedUserResourceThrottle(
request, !is_subresource_request,
- io_data->managed_mode_url_filter()));
+ io_data->supervised_user_url_filter()));
#endif
content::ResourceThrottle* throttle =
}
bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream(
- content::ResourceContext* resource_context,
- const GURL& url,
+ net::URLRequest* request,
const std::string& mime_type,
GURL* origin,
- std::string* target_id) {
+ std::string* payload) {
#if !defined(OS_ANDROID)
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
ProfileIOData* io_data =
- ProfileIOData::FromResourceContext(resource_context);
+ ProfileIOData::FromResourceContext(info->GetContext());
bool profile_is_off_the_record = io_data->IsOffTheRecord();
const scoped_refptr<const extensions::InfoMap> extension_info_map(
io_data->GetExtensionInfoMap());
continue;
}
- if (ExtensionCanHandleMimeType(extension, mime_type)) {
+ MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
+ if (handler && handler->CanHandleMIMEType(mime_type)) {
+ StreamTargetInfo target_info;
*origin = Extension::GetBaseURLFromExtensionId(extension_id);
- *target_id = extension_id;
+ target_info.extension_id = extension_id;
+ if (!handler->handler_url().empty()) {
+ target_info.view_id = base::GenerateGUID();
+ *payload = origin->spec() + handler->handler_url() +
+ "?id=" + target_info.view_id;
+ }
+ stream_target_info_[request] = target_info;
return true;
}
}
}
void ChromeResourceDispatcherHostDelegate::OnStreamCreated(
- content::ResourceContext* resource_context,
- int render_process_id,
- int render_view_id,
- const std::string& target_id,
- scoped_ptr<content::StreamHandle> stream,
- int64 expected_content_size) {
+ net::URLRequest* request,
+ scoped_ptr<content::StreamHandle> stream) {
#if !defined(OS_ANDROID)
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
+ std::map<net::URLRequest*, StreamTargetInfo>::iterator ix =
+ stream_target_info_.find(request);
+ CHECK(ix != stream_target_info_.end());
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&SendExecuteMimeTypeHandlerEvent, base::Passed(&stream),
- expected_content_size, render_process_id, render_view_id,
- target_id));
+ request->GetExpectedContentSize(),
+ info->GetChildID(), info->GetRouteID(),
+ ix->second.extension_id, ix->second.view_id));
+ stream_target_info_.erase(request);
#endif
}
if (request_spec == chrome::kChromeUIChromeSigninURL) {
#endif
net::HttpResponseHeaders* response_headers = request->response_headers();
- if (response_headers->HasHeader("x-frame-options"))
+ if (response_headers && response_headers->HasHeader("x-frame-options"))
response_headers->RemoveHeader("x-frame-options");
}
// management UI is built on top of it.
signin::AppendMirrorRequestHeaderIfPossible(request, redirect_url, io_data,
info->GetChildID(), info->GetRouteID());
+
+#if defined(ENABLE_CONFIGURATION_POLICY)
+ if (io_data->policy_header_helper())
+ io_data->policy_header_helper()->AddPolicyHeaders(redirect_url, request);
+#endif
}
// Notification that a request has completed.