Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1284)

Side by Side Diff: content/browser/loader/resource_dispatcher_host_impl.cc

Issue 2910063003: Fix Docs links from Files app on ChromeOS not working with PlzNavigate. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/loader/resource_dispatcher_host_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading
6 6
7 #include "content/browser/loader/resource_dispatcher_host_impl.h" 7 #include "content/browser/loader/resource_dispatcher_host_impl.h"
8 8
9 #include <stddef.h> 9 #include <stddef.h>
10 10
(...skipping 1137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 net::HttpRequestHeaders headers; 1148 net::HttpRequestHeaders headers;
1149 headers.AddHeadersFromString(request_data.headers); 1149 headers.AddHeadersFromString(request_data.headers);
1150 1150
1151 if (is_shutdown_ || 1151 if (is_shutdown_ ||
1152 !ShouldServiceRequest(child_id, request_data, headers, requester_info, 1152 !ShouldServiceRequest(child_id, request_data, headers, requester_info,
1153 resource_context)) { 1153 resource_context)) {
1154 AbortRequestBeforeItStarts(requester_info->filter(), sync_result_handler, 1154 AbortRequestBeforeItStarts(requester_info->filter(), sync_result_handler,
1155 request_id, std::move(url_loader_client)); 1155 request_id, std::move(url_loader_client));
1156 return; 1156 return;
1157 } 1157 }
1158 // Check if we have a registered interceptor for the headers passed in. If
1159 // yes then we need to mark the current request as pending and wait for the
1160 // interceptor to invoke the callback with a status code indicating whether
1161 // the request needs to be aborted or continued.
1162 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) {
1163 HeaderInterceptorMap::iterator index =
1164 http_header_interceptor_map_.find(it.name());
1165 if (index != http_header_interceptor_map_.end()) {
1166 HeaderInterceptorInfo& interceptor_info = index->second;
1167 1158
1168 bool call_interceptor = true; 1159 if (!is_navigation_stream_request) {
1169 if (!interceptor_info.starts_with.empty()) { 1160 // Check if we have a registered interceptor for the headers passed in. If
1170 call_interceptor = 1161 // yes then we need to mark the current request as pending and wait for the
1171 base::StartsWith(it.value(), interceptor_info.starts_with, 1162 // interceptor to invoke the callback with a status code indicating whether
1172 base::CompareCase::INSENSITIVE_ASCII); 1163 // the request needs to be aborted or continued.
1173 } 1164 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) {
1174 if (call_interceptor) { 1165 HeaderInterceptorMap::iterator index =
1175 interceptor_info.interceptor.Run( 1166 http_header_interceptor_map_.find(it.name());
1176 it.name(), it.value(), child_id, resource_context, 1167 if (index != http_header_interceptor_map_.end()) {
1177 base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest, 1168 HeaderInterceptorInfo& interceptor_info = index->second;
1178 base::Unretained(this), requester_info, request_id, 1169
1179 request_data, sync_result_handler, route_id, headers, 1170 bool call_interceptor = true;
1180 base::Passed(std::move(mojo_request)), 1171 if (!interceptor_info.starts_with.empty()) {
1181 base::Passed(std::move(url_loader_client)))); 1172 call_interceptor =
1182 return; 1173 base::StartsWith(it.value(), interceptor_info.starts_with,
1174 base::CompareCase::INSENSITIVE_ASCII);
1175 }
1176 if (call_interceptor) {
1177 interceptor_info.interceptor.Run(
1178 it.name(), it.value(), child_id, resource_context,
1179 base::Bind(
1180 &ResourceDispatcherHostImpl::ContinuePendingBeginRequest,
1181 base::Unretained(this), requester_info, request_id,
1182 request_data, sync_result_handler, route_id, headers,
1183 base::Passed(std::move(mojo_request)),
1184 base::Passed(std::move(url_loader_client))));
1185 return;
1186 }
1183 } 1187 }
1184 } 1188 }
1185 } 1189 }
1186 ContinuePendingBeginRequest( 1190 ContinuePendingBeginRequest(
1187 requester_info, request_id, request_data, sync_result_handler, route_id, 1191 requester_info, request_id, request_data, sync_result_handler, route_id,
1188 headers, std::move(mojo_request), std::move(url_loader_client), 1192 headers, std::move(mojo_request), std::move(url_loader_client),
1189 HeaderInterceptorResult::CONTINUE); 1193 HeaderInterceptorResult::CONTINUE);
1190 } 1194 }
1191 1195
1192 void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( 1196 void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
(...skipping 14 matching lines...) Expand all
1207 // in a non-content error code is not safe, but future header interceptors 1211 // in a non-content error code is not safe, but future header interceptors
1208 // might say to kill for reasons other than illegal origins. 1212 // might say to kill for reasons other than illegal origins.
1209 bad_message::ReceivedBadMessage(requester_info->filter(), 1213 bad_message::ReceivedBadMessage(requester_info->filter(),
1210 bad_message::RDH_ILLEGAL_ORIGIN); 1214 bad_message::RDH_ILLEGAL_ORIGIN);
1211 } 1215 }
1212 AbortRequestBeforeItStarts(requester_info->filter(), sync_result_handler, 1216 AbortRequestBeforeItStarts(requester_info->filter(), sync_result_handler,
1213 request_id, std::move(url_loader_client)); 1217 request_id, std::move(url_loader_client));
1214 return; 1218 return;
1215 } 1219 }
1216 int child_id = requester_info->child_id(); 1220 int child_id = requester_info->child_id();
1217 1221 storage::BlobStorageContext* blob_context = nullptr;
1222 bool allow_download = false;
1223 bool do_not_prompt_for_login = false;
1224 bool report_raw_headers = false;
1225 bool is_sync_load = !!sync_result_handler;
1226 int load_flags = BuildLoadFlagsForRequest(request_data, is_sync_load);
1218 bool is_navigation_stream_request = 1227 bool is_navigation_stream_request =
1219 IsBrowserSideNavigationEnabled() && 1228 IsBrowserSideNavigationEnabled() &&
1220 IsResourceTypeFrame(request_data.resource_type); 1229 IsResourceTypeFrame(request_data.resource_type);
1221 1230
1222 ResourceContext* resource_context = NULL; 1231 ResourceContext* resource_context = NULL;
1223 net::URLRequestContext* request_context = NULL; 1232 net::URLRequestContext* request_context = NULL;
1224 requester_info->GetContexts(request_data.resource_type, &resource_context, 1233 requester_info->GetContexts(request_data.resource_type, &resource_context,
1225 &request_context); 1234 &request_context);
1226 1235
1227 // Allow the observer to block/handle the request. 1236 // Allow the observer to block/handle the request.
1228 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method, 1237 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method,
1229 request_data.url, 1238 request_data.url,
1230 request_data.resource_type, 1239 request_data.resource_type,
1231 resource_context)) { 1240 resource_context)) {
1232 AbortRequestBeforeItStarts(requester_info->filter(), sync_result_handler, 1241 AbortRequestBeforeItStarts(requester_info->filter(), sync_result_handler,
1233 request_id, std::move(url_loader_client)); 1242 request_id, std::move(url_loader_client));
1234 return; 1243 return;
1235 } 1244 }
1236 1245
1237 // Construct the request. 1246 // Construct the request.
1238 std::unique_ptr<net::URLRequest> new_request = request_context->CreateRequest( 1247 std::unique_ptr<net::URLRequest> new_request = request_context->CreateRequest(
1239 is_navigation_stream_request ? request_data.resource_body_stream_url 1248 is_navigation_stream_request ? request_data.resource_body_stream_url
1240 : request_data.url, 1249 : request_data.url,
1241 request_data.priority, nullptr, kTrafficAnnotation); 1250 request_data.priority, nullptr, kTrafficAnnotation);
1242 1251
1243 // Log that this request is a service worker navigation preload request here, 1252 if (is_navigation_stream_request) {
1244 // since navigation preload machinery has no access to netlog. 1253 // PlzNavigate: Always set the method to GET when gaining access to the
1245 // TODO(falken): Figure out how mojom::URLLoaderClient can 1254 // stream that contains the response body of a navigation. Otherwise the
1246 // access the request's netlog. 1255 // data that was already fetched by the browser will not be transmitted to
1247 if (requester_info->IsNavigationPreload()) { 1256 // the renderer.
1248 new_request->net_log().AddEvent( 1257 new_request->set_method("GET");
1249 net::NetLogEventType::SERVICE_WORKER_NAVIGATION_PRELOAD_REQUEST); 1258 } else {
1250 } 1259 // Log that this request is a service worker navigation preload request
1260 // here, since navigation preload machinery has no access to netlog.
1261 // TODO(falken): Figure out how mojom::URLLoaderClient can
1262 // access the request's netlog.
1263 if (requester_info->IsNavigationPreload()) {
1264 new_request->net_log().AddEvent(
1265 net::NetLogEventType::SERVICE_WORKER_NAVIGATION_PRELOAD_REQUEST);
1266 }
1251 1267
1252 // PlzNavigate: Always set the method to GET when gaining access to the
1253 // stream that contains the response body of a navigation. Otherwise the data
1254 // that was already fetched by the browser will not be transmitted to the
1255 // renderer.
1256 if (is_navigation_stream_request)
1257 new_request->set_method("GET");
1258 else
1259 new_request->set_method(request_data.method); 1268 new_request->set_method(request_data.method);
1260 1269
1261 new_request->set_first_party_for_cookies( 1270 new_request->set_first_party_for_cookies(
1262 request_data.first_party_for_cookies); 1271 request_data.first_party_for_cookies);
1263 1272
1264 // The initiator should normally be present, unless this is a navigation in a 1273 // The initiator should normally be present, unless this is a navigation in
1265 // top-level frame. It may be null for some top-level navigations (eg: 1274 // a top-level frame. It may be null for some top-level navigations (eg:
1266 // browser-initiated ones). 1275 // browser-initiated ones).
1267 DCHECK(request_data.request_initiator.has_value() || 1276 DCHECK(request_data.request_initiator.has_value() ||
1268 request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME); 1277 request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME);
1269 new_request->set_initiator(request_data.request_initiator); 1278 new_request->set_initiator(request_data.request_initiator);
1270 1279
1271 if (request_data.originated_from_service_worker) { 1280 if (request_data.originated_from_service_worker) {
1272 new_request->SetUserData(URLRequestServiceWorkerData::kUserDataKey, 1281 new_request->SetUserData(URLRequestServiceWorkerData::kUserDataKey,
1273 base::MakeUnique<URLRequestServiceWorkerData>()); 1282 base::MakeUnique<URLRequestServiceWorkerData>());
1274 } 1283 }
1275 1284
1276 // If the request is a MAIN_FRAME request, the first-party URL gets updated on 1285 // If the request is a MAIN_FRAME request, the first-party URL gets updated
1277 // redirects. 1286 // on redirects.
1278 if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME) { 1287 if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME) {
1279 new_request->set_first_party_url_policy( 1288 new_request->set_first_party_url_policy(
1280 net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); 1289 net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
1281 } 1290 }
1282 1291
1283 // For PlzNavigate, this request has already been made and the referrer was 1292 // For PlzNavigate, this request has already been made and the referrer was
1284 // checked previously. So don't set the referrer for this stream request, or 1293 // checked previously. So don't set the referrer for this stream request, or
1285 // else it will fail for SSL redirects since net/ will think the blob:https 1294 // else it will fail for SSL redirects since net/ will think the blob:https
1286 // for the stream is not a secure scheme (specifically, in the call to 1295 // for the stream is not a secure scheme (specifically, in the call to
1287 // ComputeReferrerForRedirect). 1296 // ComputeReferrerForRedirect).
1288 if (!is_navigation_stream_request) {
1289 const Referrer referrer( 1297 const Referrer referrer(
1290 request_data.referrer, request_data.referrer_policy); 1298 request_data.referrer, request_data.referrer_policy);
1291 Referrer::SetReferrerForRequest(new_request.get(), referrer); 1299 Referrer::SetReferrerForRequest(new_request.get(), referrer);
1300
1301 new_request->SetExtraRequestHeaders(headers);
1302
1303 blob_context =
1304 GetBlobStorageContext(requester_info->blob_storage_context());
1305 // Resolve elements from request_body and prepare upload data.
1306 if (request_data.request_body.get()) {
1307 // |blob_context| could be null when the request is from the plugins
1308 // because ResourceMessageFilters created in PluginProcessHost don't have
1309 // the blob context.
1310 if (blob_context) {
1311 // Attaches the BlobDataHandles to request_body not to free the blobs
1312 // and any attached shareable files until upload completion. These data
1313 // will be used in UploadDataStream and ServiceWorkerURLRequestJob.
1314 AttachRequestBodyBlobDataHandles(request_data.request_body.get(),
1315 resource_context);
1316 }
1317 new_request->set_upload(UploadDataStreamBuilder::Build(
1318 request_data.request_body.get(), blob_context,
1319 requester_info->file_system_context(),
1320 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get()));
1321 }
1322
1323 allow_download = request_data.allow_download &&
1324 IsResourceTypeFrame(request_data.resource_type);
1325 do_not_prompt_for_login = request_data.do_not_prompt_for_login;
1326
1327 // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only
1328 // allow requesting them if requester has ReadRawCookies permission.
1329 ChildProcessSecurityPolicyImpl* policy =
1330 ChildProcessSecurityPolicyImpl::GetInstance();
1331 report_raw_headers = request_data.report_raw_headers;
1332 if (report_raw_headers && !policy->CanReadRawCookies(child_id) &&
1333 !requester_info->IsNavigationPreload()) {
1334 // For navigation preload, the child_id is -1 so CanReadRawCookies would
1335 // return false. But |report_raw_headers| of the navigation preload
1336 // request was copied from the original request, so this check has already
1337 // been carried out.
1338 // TODO: crbug.com/523063 can we call bad_message::ReceivedBadMessage
1339 // here?
1340 VLOG(1) << "Denied unauthorized request for raw headers";
1341 report_raw_headers = false;
1342 }
1343
1344 if (request_data.resource_type == RESOURCE_TYPE_PREFETCH ||
1345 request_data.resource_type == RESOURCE_TYPE_FAVICON) {
1346 do_not_prompt_for_login = true;
1347 }
1348 if (request_data.resource_type == RESOURCE_TYPE_IMAGE &&
1349 HTTP_AUTH_RELATION_BLOCKED_CROSS ==
1350 HttpAuthRelationTypeOf(request_data.url,
1351 request_data.first_party_for_cookies)) {
1352 // Prevent third-party image content from prompting for login, as this
1353 // is often a scam to extract credentials for another domain from the
1354 // user. Only block image loads, as the attack applies largely to the
1355 // "src" property of the <img> tag. It is common for web properties to
1356 // allow untrusted values for <img src>; this is considered a fair thing
1357 // for an HTML sanitizer to do. Conversely, any HTML sanitizer that didn't
1358 // filter sources for <script>, <link>, <embed>, <object>, <iframe> tags
1359 // would be considered vulnerable in and of itself.
1360 do_not_prompt_for_login = true;
1361 load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
1362 }
1363
1364 // Sync loads should have maximum priority and should be the only
1365 // requets that have the ignore limits flag set.
1366 if (is_sync_load) {
1367 DCHECK_EQ(request_data.priority, net::MAXIMUM_PRIORITY);
1368 DCHECK_NE(load_flags & net::LOAD_IGNORE_LIMITS, 0);
1369 } else {
1370 DCHECK_EQ(load_flags & net::LOAD_IGNORE_LIMITS, 0);
1371 }
1292 } 1372 }
1293 1373
1294 new_request->SetExtraRequestHeaders(headers);
1295
1296 storage::BlobStorageContext* blob_context =
1297 GetBlobStorageContext(requester_info->blob_storage_context());
1298 // Resolve elements from request_body and prepare upload data.
1299 if (request_data.request_body.get()) {
1300 // |blob_context| could be null when the request is from the plugins because
1301 // ResourceMessageFilters created in PluginProcessHost don't have the blob
1302 // context.
1303 if (blob_context) {
1304 // Attaches the BlobDataHandles to request_body not to free the blobs and
1305 // any attached shareable files until upload completion. These data will
1306 // be used in UploadDataStream and ServiceWorkerURLRequestJob.
1307 AttachRequestBodyBlobDataHandles(request_data.request_body.get(),
1308 resource_context);
1309 }
1310 new_request->set_upload(UploadDataStreamBuilder::Build(
1311 request_data.request_body.get(), blob_context,
1312 requester_info->file_system_context(),
1313 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get()));
1314 }
1315
1316 bool allow_download = request_data.allow_download &&
1317 IsResourceTypeFrame(request_data.resource_type);
1318 bool do_not_prompt_for_login = request_data.do_not_prompt_for_login;
1319 bool is_sync_load = !!sync_result_handler;
1320
1321 // Raw headers are sensitive, as they include Cookie/Set-Cookie, so only
1322 // allow requesting them if requester has ReadRawCookies permission.
1323 ChildProcessSecurityPolicyImpl* policy =
1324 ChildProcessSecurityPolicyImpl::GetInstance();
1325 bool report_raw_headers = request_data.report_raw_headers;
1326 if (report_raw_headers && !policy->CanReadRawCookies(child_id) &&
1327 !requester_info->IsNavigationPreload()) {
1328 // For navigation preload, the child_id is -1 so CanReadRawCookies would
1329 // return false. But |report_raw_headers| of the navigation preload request
1330 // was copied from the original request, so this check has already been
1331 // carried out.
1332 // TODO: crbug.com/523063 can we call bad_message::ReceivedBadMessage here?
1333 VLOG(1) << "Denied unauthorized request for raw headers";
1334 report_raw_headers = false;
1335 }
1336 int load_flags = BuildLoadFlagsForRequest(request_data, is_sync_load);
1337 if (request_data.resource_type == RESOURCE_TYPE_PREFETCH ||
1338 request_data.resource_type == RESOURCE_TYPE_FAVICON) {
1339 do_not_prompt_for_login = true;
1340 }
1341 if (request_data.resource_type == RESOURCE_TYPE_IMAGE &&
1342 HTTP_AUTH_RELATION_BLOCKED_CROSS ==
1343 HttpAuthRelationTypeOf(request_data.url,
1344 request_data.first_party_for_cookies)) {
1345 // Prevent third-party image content from prompting for login, as this
1346 // is often a scam to extract credentials for another domain from the user.
1347 // Only block image loads, as the attack applies largely to the "src"
1348 // property of the <img> tag. It is common for web properties to allow
1349 // untrusted values for <img src>; this is considered a fair thing for an
1350 // HTML sanitizer to do. Conversely, any HTML sanitizer that didn't
1351 // filter sources for <script>, <link>, <embed>, <object>, <iframe> tags
1352 // would be considered vulnerable in and of itself.
1353 do_not_prompt_for_login = true;
1354 load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
1355 }
1356
1357 // Sync loads should have maximum priority and should be the only
1358 // requets that have the ignore limits flag set.
1359 if (is_sync_load) {
1360 DCHECK_EQ(request_data.priority, net::MAXIMUM_PRIORITY);
1361 DCHECK_NE(load_flags & net::LOAD_IGNORE_LIMITS, 0);
1362 } else {
1363 DCHECK_EQ(load_flags & net::LOAD_IGNORE_LIMITS, 0);
1364 }
1365 new_request->SetLoadFlags(load_flags); 1374 new_request->SetLoadFlags(load_flags);
1366 1375
1367 // Make extra info and read footer (contains request ID). 1376 // Make extra info and read footer (contains request ID).
1368 ResourceRequestInfoImpl* extra_info = new ResourceRequestInfoImpl( 1377 ResourceRequestInfoImpl* extra_info = new ResourceRequestInfoImpl(
1369 requester_info, route_id, 1378 requester_info, route_id,
1370 -1, // frame_tree_node_id 1379 -1, // frame_tree_node_id
1371 request_data.origin_pid, request_id, request_data.render_frame_id, 1380 request_data.origin_pid, request_id, request_data.render_frame_id,
1372 request_data.is_main_frame, request_data.parent_is_main_frame, 1381 request_data.is_main_frame, request_data.parent_is_main_frame,
1373 request_data.resource_type, request_data.transition_type, 1382 request_data.resource_type, request_data.transition_type,
1374 request_data.should_replace_current_entry, 1383 request_data.should_replace_current_entry,
(...skipping 13 matching lines...) Expand all
1388 1397
1389 if (new_request->url().SchemeIs(url::kBlobScheme)) { 1398 if (new_request->url().SchemeIs(url::kBlobScheme)) {
1390 // Hang on to a reference to ensure the blob is not released prior 1399 // Hang on to a reference to ensure the blob is not released prior
1391 // to the job being started. 1400 // to the job being started.
1392 storage::BlobProtocolHandler::SetRequestedBlobDataHandle( 1401 storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
1393 new_request.get(), requester_info->blob_storage_context() 1402 new_request.get(), requester_info->blob_storage_context()
1394 ->context() 1403 ->context()
1395 ->GetBlobDataFromPublicURL(new_request->url())); 1404 ->GetBlobDataFromPublicURL(new_request->url()));
1396 } 1405 }
1397 1406
1398 // Initialize the service worker handler for the request. We don't use 1407 std::unique_ptr<ResourceHandler> handler;
1399 // ServiceWorker for synchronous loads to avoid renderer deadlocks. 1408 if (is_navigation_stream_request) {
1400 const ServiceWorkerMode service_worker_mode = 1409 // PlzNavigate: do not add ResourceThrottles for main resource requests from
1401 is_sync_load ? ServiceWorkerMode::NONE : request_data.service_worker_mode; 1410 // the renderer. Decisions about the navigation should have been done in
1402 ServiceWorkerRequestHandler::InitializeHandler( 1411 // the initial request.
1403 new_request.get(), requester_info->service_worker_context(), blob_context, 1412 handler = CreateBaseResourceHandler(
1404 child_id, request_data.service_worker_provider_id, 1413 new_request.get(), std::move(mojo_request),
1405 service_worker_mode != ServiceWorkerMode::ALL, 1414 std::move(url_loader_client), request_data.resource_type);
1406 request_data.fetch_request_mode, request_data.fetch_credentials_mode, 1415 } else {
1407 request_data.fetch_redirect_mode, request_data.resource_type, 1416 // Initialize the service worker handler for the request. We don't use
1408 request_data.fetch_request_context_type, request_data.fetch_frame_type, 1417 // ServiceWorker for synchronous loads to avoid renderer deadlocks.
1409 request_data.request_body); 1418 const ServiceWorkerMode service_worker_mode =
1419 is_sync_load ? ServiceWorkerMode::NONE
1420 : request_data.service_worker_mode;
1421 ServiceWorkerRequestHandler::InitializeHandler(
1422 new_request.get(), requester_info->service_worker_context(),
1423 blob_context, child_id, request_data.service_worker_provider_id,
1424 service_worker_mode != ServiceWorkerMode::ALL,
1425 request_data.fetch_request_mode, request_data.fetch_credentials_mode,
1426 request_data.fetch_redirect_mode, request_data.resource_type,
1427 request_data.fetch_request_context_type, request_data.fetch_frame_type,
1428 request_data.request_body);
1410 1429
1411 ForeignFetchRequestHandler::InitializeHandler( 1430 ForeignFetchRequestHandler::InitializeHandler(
1412 new_request.get(), requester_info->service_worker_context(), blob_context, 1431 new_request.get(), requester_info->service_worker_context(),
1413 child_id, request_data.service_worker_provider_id, service_worker_mode, 1432 blob_context, child_id, request_data.service_worker_provider_id,
1414 request_data.fetch_request_mode, request_data.fetch_credentials_mode, 1433 service_worker_mode, request_data.fetch_request_mode,
1415 request_data.fetch_redirect_mode, request_data.resource_type, 1434 request_data.fetch_credentials_mode, request_data.fetch_redirect_mode,
1416 request_data.fetch_request_context_type, request_data.fetch_frame_type, 1435 request_data.resource_type, request_data.fetch_request_context_type,
1417 request_data.request_body, request_data.initiated_in_secure_context); 1436 request_data.fetch_frame_type, request_data.request_body,
1437 request_data.initiated_in_secure_context);
1418 1438
1419 // Have the appcache associate its extra info with the request. 1439 // Have the appcache associate its extra info with the request.
1420 AppCacheInterceptor::SetExtraRequestInfo( 1440 AppCacheInterceptor::SetExtraRequestInfo(
1421 new_request.get(), requester_info->appcache_service(), child_id, 1441 new_request.get(), requester_info->appcache_service(), child_id,
1422 request_data.appcache_host_id, request_data.resource_type, 1442 request_data.appcache_host_id, request_data.resource_type,
1423 request_data.should_reset_appcache); 1443 request_data.should_reset_appcache);
1424 1444 handler = CreateResourceHandler(
1425 std::unique_ptr<ResourceHandler> handler(CreateResourceHandler( 1445 requester_info.get(), new_request.get(), request_data,
1426 requester_info.get(), new_request.get(), request_data, 1446 sync_result_handler, route_id, child_id, resource_context,
1427 sync_result_handler, route_id, child_id, resource_context, 1447 std::move(mojo_request), std::move(url_loader_client));
1428 std::move(mojo_request), std::move(url_loader_client))); 1448 }
1429
1430 if (handler) 1449 if (handler)
1431 BeginRequestInternal(std::move(new_request), std::move(handler)); 1450 BeginRequestInternal(std::move(new_request), std::move(handler));
1432 } 1451 }
1433 1452
1434 std::unique_ptr<ResourceHandler> 1453 std::unique_ptr<ResourceHandler>
1435 ResourceDispatcherHostImpl::CreateResourceHandler( 1454 ResourceDispatcherHostImpl::CreateResourceHandler(
1436 ResourceRequesterInfo* requester_info, 1455 ResourceRequesterInfo* requester_info,
1437 net::URLRequest* request, 1456 net::URLRequest* request,
1438 const ResourceRequest& request_data, 1457 const ResourceRequest& request_data,
1439 const SyncLoadResultCallback& sync_result_handler, 1458 const SyncLoadResultCallback& sync_result_handler,
(...skipping 15 matching lines...) Expand all
1455 DCHECK(requester_info->IsRenderer()); 1474 DCHECK(requester_info->IsRenderer());
1456 bad_message::ReceivedBadMessage(requester_info->filter(), 1475 bad_message::ReceivedBadMessage(requester_info->filter(),
1457 bad_message::RDH_BAD_DOWNLOAD); 1476 bad_message::RDH_BAD_DOWNLOAD);
1458 return std::unique_ptr<ResourceHandler>(); 1477 return std::unique_ptr<ResourceHandler>();
1459 } 1478 }
1460 1479
1461 DCHECK(!mojo_request.is_pending()); 1480 DCHECK(!mojo_request.is_pending());
1462 DCHECK(!url_loader_client); 1481 DCHECK(!url_loader_client);
1463 handler.reset(new SyncResourceHandler(request, sync_result_handler, this)); 1482 handler.reset(new SyncResourceHandler(request, sync_result_handler, this));
1464 } else { 1483 } else {
1465 if (mojo_request.is_pending()) { 1484 handler = CreateBaseResourceHandler(request, std::move(mojo_request),
1466 handler.reset(new MojoAsyncResourceHandler(request, this, 1485 std::move(url_loader_client),
1467 std::move(mojo_request), 1486 request_data.resource_type);
1468 std::move(url_loader_client),
1469 request_data.resource_type));
1470 } else {
1471 handler.reset(new AsyncResourceHandler(request, this));
1472 }
1473 1487
1474 // The RedirectToFileResourceHandler depends on being next in the chain. 1488 // The RedirectToFileResourceHandler depends on being next in the chain.
1475 if (request_data.download_to_file) { 1489 if (request_data.download_to_file) {
1476 handler.reset( 1490 handler.reset(
1477 new RedirectToFileResourceHandler(std::move(handler), request)); 1491 new RedirectToFileResourceHandler(std::move(handler), request));
1478 } 1492 }
1479 } 1493 }
1480 1494
1481 bool start_detached = request_data.download_to_network_cache_only; 1495 bool start_detached = request_data.download_to_network_cache_only;
1482 1496
(...skipping 12 matching lines...) Expand all
1495 } 1509 }
1496 1510
1497 std::unique_ptr<DetachableResourceHandler> detachable_handler = 1511 std::unique_ptr<DetachableResourceHandler> detachable_handler =
1498 base::MakeUnique<DetachableResourceHandler>(request, timeout, 1512 base::MakeUnique<DetachableResourceHandler>(request, timeout,
1499 std::move(handler)); 1513 std::move(handler));
1500 if (start_detached) 1514 if (start_detached)
1501 detachable_handler->Detach(); 1515 detachable_handler->Detach();
1502 handler = std::move(detachable_handler); 1516 handler = std::move(detachable_handler);
1503 } 1517 }
1504 1518
1505 // PlzNavigate: do not add ResourceThrottles for main resource requests from
1506 // the renderer. Decisions about the navigation should have been done in the
1507 // initial request.
1508 if (IsBrowserSideNavigationEnabled() &&
1509 IsResourceTypeFrame(request_data.resource_type)) {
1510 DCHECK(request->url().SchemeIs(url::kBlobScheme));
1511 return handler;
1512 }
1513
1514 return AddStandardHandlers(request, request_data.resource_type, 1519 return AddStandardHandlers(request, request_data.resource_type,
1515 resource_context, 1520 resource_context,
1516 request_data.fetch_request_context_type, 1521 request_data.fetch_request_context_type,
1517 request_data.fetch_mixed_content_context_type, 1522 request_data.fetch_mixed_content_context_type,
1518 requester_info->appcache_service(), child_id, 1523 requester_info->appcache_service(), child_id,
1519 route_id, std::move(handler), nullptr, nullptr); 1524 route_id, std::move(handler), nullptr, nullptr);
1520 } 1525 }
1521 1526
1522 std::unique_ptr<ResourceHandler> 1527 std::unique_ptr<ResourceHandler>
1528 ResourceDispatcherHostImpl::CreateBaseResourceHandler(
1529 net::URLRequest* request,
1530 mojom::URLLoaderAssociatedRequest mojo_request,
1531 mojom::URLLoaderClientPtr url_loader_client,
1532 ResourceType resource_type) {
1533 std::unique_ptr<ResourceHandler> handler;
1534 if (mojo_request.is_pending()) {
1535 handler.reset(new MojoAsyncResourceHandler(
1536 request, this, std::move(mojo_request), std::move(url_loader_client),
1537 resource_type));
1538 } else {
1539 handler.reset(new AsyncResourceHandler(request, this));
1540 }
1541 return handler;
1542 }
1543
1544 std::unique_ptr<ResourceHandler>
1523 ResourceDispatcherHostImpl::AddStandardHandlers( 1545 ResourceDispatcherHostImpl::AddStandardHandlers(
1524 net::URLRequest* request, 1546 net::URLRequest* request,
1525 ResourceType resource_type, 1547 ResourceType resource_type,
1526 ResourceContext* resource_context, 1548 ResourceContext* resource_context,
1527 RequestContextType fetch_request_context_type, 1549 RequestContextType fetch_request_context_type,
1528 blink::WebMixedContentContextType fetch_mixed_content_context_type, 1550 blink::WebMixedContentContextType fetch_mixed_content_context_type,
1529 AppCacheService* appcache_service, 1551 AppCacheService* appcache_service,
1530 int child_id, 1552 int child_id,
1531 int route_id, 1553 int route_id,
1532 std::unique_ptr<ResourceHandler> handler, 1554 std::unique_ptr<ResourceHandler> handler,
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after
2603 } 2625 }
2604 2626
2605 bool ResourceDispatcherHostImpl::ShouldServiceRequest( 2627 bool ResourceDispatcherHostImpl::ShouldServiceRequest(
2606 int child_id, 2628 int child_id,
2607 const ResourceRequest& request_data, 2629 const ResourceRequest& request_data,
2608 const net::HttpRequestHeaders& headers, 2630 const net::HttpRequestHeaders& headers,
2609 ResourceRequesterInfo* requester_info, 2631 ResourceRequesterInfo* requester_info,
2610 ResourceContext* resource_context) { 2632 ResourceContext* resource_context) {
2611 ChildProcessSecurityPolicyImpl* policy = 2633 ChildProcessSecurityPolicyImpl* policy =
2612 ChildProcessSecurityPolicyImpl::GetInstance(); 2634 ChildProcessSecurityPolicyImpl::GetInstance();
2613 2635 bool is_navigation_stream_request =
2636 IsBrowserSideNavigationEnabled() &&
2637 IsResourceTypeFrame(request_data.resource_type);
2614 // Check if the renderer is permitted to request the requested URL. 2638 // Check if the renderer is permitted to request the requested URL.
2615 if (!policy->CanRequestURL(child_id, request_data.url)) { 2639 // PlzNavigate: no need to check the URL here. The browser already picked the
2640 // right renderer to send the request to. The original URL isn't used, as the
2641 // renderer is fetching the stream URL. Checking the original URL doesn't work
2642 // in case of redirects across schemes, since the original URL might not be
2643 // granted to the final URL's renderer.
2644 if (!is_navigation_stream_request &&
2645 !policy->CanRequestURL(child_id, request_data.url)) {
2616 VLOG(1) << "Denied unauthorized request for " 2646 VLOG(1) << "Denied unauthorized request for "
2617 << request_data.url.possibly_invalid_spec(); 2647 << request_data.url.possibly_invalid_spec();
2618 return false; 2648 return false;
2619 } 2649 }
2620 2650
2621 // Check if the renderer is using an illegal Origin header. If so, kill it. 2651 // Check if the renderer is using an illegal Origin header. If so, kill it.
2622 std::string origin_string; 2652 std::string origin_string;
2623 bool has_origin = 2653 bool has_origin =
2624 headers.GetHeader("Origin", &origin_string) && origin_string != "null"; 2654 headers.GetHeader("Origin", &origin_string) && origin_string != "null";
2625 if (has_origin) { 2655 if (has_origin) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 &throttles); 2706 &throttles);
2677 if (!throttles.empty()) { 2707 if (!throttles.empty()) {
2678 handler.reset(new ThrottlingResourceHandler(std::move(handler), request, 2708 handler.reset(new ThrottlingResourceHandler(std::move(handler), request,
2679 std::move(throttles))); 2709 std::move(throttles)));
2680 } 2710 }
2681 } 2711 }
2682 return handler; 2712 return handler;
2683 } 2713 }
2684 2714
2685 } // namespace content 2715 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_dispatcher_host_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698