void LinkLoader::createLinkPreloadResourceClient(Resource* resource) { if (!resource) return; switch (resource->getType()) { case Resource::Image: m_linkPreloadResourceClient = LinkPreloadImageResourceClient::create(this, toImageResource(resource)); break; case Resource::Script: m_linkPreloadResourceClient = LinkPreloadScriptResourceClient::create(this, toScriptResource(resource)); break; case Resource::CSSStyleSheet: m_linkPreloadResourceClient = LinkPreloadStyleResourceClient::create(this, toCSSStyleSheetResource(resource)); break; case Resource::Font: m_linkPreloadResourceClient = LinkPreloadFontResourceClient::create(this, toFontResource(resource)); break; case Resource::Media: case Resource::TextTrack: case Resource::Raw: case Resource::LinkPreload: m_linkPreloadResourceClient = LinkPreloadRawResourceClient::create(this, toRawResource(resource)); break; default: ASSERT_NOT_REACHED(); } }
void PendingScript::notifyFinished(Resource* resource) { // The following SRI checks need to be here because, unfortunately, fetches // are not done purely according to the Fetch spec. In particular, // different requests for the same resource do not have different // responses; the memory cache can (and will) return the exact same // Resource object. // // For different requests, the same Resource object will be returned and // will not be associated with the particular request. Therefore, when the // body of the response comes in, there's no way to validate the integrity // of the Resource object against a particular request (since there may be // several pending requests all tied to the identical object, and the // actual requests are not stored). // // In order to simulate the correct behavior, Blink explicitly does the SRI // checks here, when a PendingScript tied to a particular request is // finished (and in the case of a StyleSheet, at the point of execution), // while having proper Fetch checks in the fetch module for use in the // fetch JavaScript API. In a future world where the ResourceFetcher uses // the Fetch algorithm, this should be fixed by having separate Response // objects (perhaps attached to identical Resource objects) per request. // // See https://crbug.com/500701 for more information. if (m_element) { DCHECK_EQ(resource->getType(), Resource::Script); ScriptResource* scriptResource = toScriptResource(resource); String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityAttr); // It is possible to get back a script resource with integrity metadata // for a request with an empty integrity attribute. In that case, the // integrity check should be skipped, so this check ensures that the // integrity attribute isn't empty in addition to checking if the // resource has empty integrity metadata. if (!integrityAttr.isEmpty() && !scriptResource->integrityMetadata().isEmpty()) { ResourceIntegrityDisposition disposition = scriptResource->integrityDisposition(); if (disposition == ResourceIntegrityDisposition::Failed) { // TODO(jww): This should probably also generate a console // message identical to the one produced by // CheckSubresourceIntegrity below. See https://crbug.com/585267. m_integrityFailure = true; } else if (disposition == ResourceIntegrityDisposition::NotChecked && resource->resourceBuffer()) { m_integrityFailure = !SubresourceIntegrity::CheckSubresourceIntegrity( scriptResource->integrityMetadata(), *m_element, resource->resourceBuffer()->data(), resource->resourceBuffer()->size(), resource->url(), *resource); scriptResource->setIntegrityDisposition( m_integrityFailure ? ResourceIntegrityDisposition::Failed : ResourceIntegrityDisposition::Passed); } } } if (m_streamer) m_streamer->notifyFinished(resource); }
ResourcePtr<ScriptResource> ScriptResource::fetch(FetchRequest& request, ResourceFetcher* fetcher) { ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone); request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestContextScript); ResourcePtr<ScriptResource> resource = toScriptResource(fetcher->requestResource(request, ScriptResourceFactory())); if (resource && !request.integrityMetadata().isEmpty()) resource->setIntegrityMetadata(request.integrityMetadata()); return resource; }
bool InspectorPageAgent::cachedResourceContent(Resource* cachedResource, String* result, bool* base64Encoded) { bool hasZeroSize; bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize); if (!prepared) return false; *base64Encoded = !hasTextContent(cachedResource); if (*base64Encoded) { RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer(); if (!buffer) return false; *result = base64Encode(buffer->data(), buffer->size()); return true; } if (hasZeroSize) { *result = ""; return true; } if (cachedResource) { switch (cachedResource->type()) { case Resource::CSSStyleSheet: *result = toCSSStyleSheetResource(cachedResource)->sheetText(false); return true; case Resource::Script: *result = toScriptResource(cachedResource)->script(); return true; case Resource::MainResource: return false; case Resource::Raw: { SharedBuffer* buffer = cachedResource->resourceBuffer(); if (!buffer) return false; OwnPtr<TextResourceDecoder> decoder = createXHRTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName()); String content = decoder->decode(buffer->data(), buffer->size()); *result = content + decoder->flush(); return true; } default: SharedBuffer* buffer = cachedResource->resourceBuffer(); return decodeBuffer(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, cachedResource->response().textEncodingName(), result); } } return false; }
ResourcePtr<ScriptResource> ScriptResource::fetch(FetchRequest& request, ResourceFetcher* fetcher) { ASSERT(request.resourceRequest().frameType() == WebURLRequest::FrameTypeNone); request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestContextScript); return toScriptResource(fetcher->requestResource(request, ScriptResourceFactory())); }