summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/cache/CachedScript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader/cache/CachedScript.cpp')
-rw-r--r--Source/WebCore/loader/cache/CachedScript.cpp83
1 files changed, 60 insertions, 23 deletions
diff --git a/Source/WebCore/loader/cache/CachedScript.cpp b/Source/WebCore/loader/cache/CachedScript.cpp
index 48facd7bc..84de38ebe 100644
--- a/Source/WebCore/loader/cache/CachedScript.cpp
+++ b/Source/WebCore/loader/cache/CachedScript.cpp
@@ -29,24 +29,20 @@
#include "CachedResourceClient.h"
#include "CachedResourceClientWalker.h"
+#include "CachedResourceRequest.h"
+#include "HTTPHeaderNames.h"
#include "HTTPParsers.h"
#include "MIMETypeRegistry.h"
-#include "MemoryCache.h"
-#include "ResourceBuffer.h"
#include "RuntimeApplicationChecks.h"
+#include "SharedBuffer.h"
#include "TextResourceDecoder.h"
-#include <wtf/Vector.h>
namespace WebCore {
-CachedScript::CachedScript(const ResourceRequest& resourceRequest, const String& charset)
- : CachedResource(resourceRequest, Script)
- , m_decoder(TextResourceDecoder::create(ASCIILiteral("application/javascript"), charset))
+CachedScript::CachedScript(CachedResourceRequest&& request, SessionID sessionID)
+ : CachedResource(WTFMove(request), Script, sessionID)
+ , m_decoder(TextResourceDecoder::create(ASCIILiteral("application/javascript"), request.charset()))
{
- // It's javascript we want.
- // But some websites think their scripts are <some wrong mimetype here>
- // and refuse to serve them if we only accept application/x-javascript.
- setAccept("*/*");
}
CachedScript::~CachedScript()
@@ -65,27 +61,55 @@ String CachedScript::encoding() const
String CachedScript::mimeType() const
{
- return extractMIMETypeFromMediaType(m_response.httpHeaderField("Content-Type")).lower();
+ return extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)).convertToASCIILowercase();
}
-const String& CachedScript::script()
+StringView CachedScript::script()
{
- ASSERT(!isPurgeable());
+ if (!m_data)
+ return { };
- if (!m_script && m_data) {
- m_script = m_decoder->decode(m_data->data(), encodedSize());
- m_script.append(m_decoder->flush());
+ if (m_decodingState == NeverDecoded
+ && TextEncoding(encoding()).isByteBasedEncoding()
+ && m_data->size()
+ && charactersAreAllASCII(reinterpret_cast<const LChar*>(m_data->data()), m_data->size())) {
+
+ m_decodingState = DataAndDecodedStringHaveSameBytes;
+
+ // If the encoded and decoded data are the same, there is no decoded data cost!
+ setDecodedSize(0);
+ m_decodedDataDeletionTimer.stop();
+
+ m_scriptHash = StringHasher::computeHashAndMaskTop8Bits(reinterpret_cast<const LChar*>(m_data->data()), m_data->size());
+ }
+
+ if (m_decodingState == DataAndDecodedStringHaveSameBytes)
+ return { reinterpret_cast<const LChar*>(m_data->data()), m_data->size() };
+
+ if (!m_script) {
+ m_script = m_decoder->decodeAndFlush(m_data->data(), encodedSize());
+ ASSERT(!m_scriptHash || m_scriptHash == m_script.impl()->hash());
+ if (m_decodingState == NeverDecoded)
+ m_scriptHash = m_script.impl()->hash();
+ m_decodingState = DataAndDecodedStringHaveDifferentBytes;
setDecodedSize(m_script.sizeInBytes());
}
+
m_decodedDataDeletionTimer.restart();
-
return m_script;
}
-void CachedScript::finishLoading(ResourceBuffer* data)
+unsigned CachedScript::scriptHash()
+{
+ if (m_decodingState == NeverDecoded)
+ script();
+ return m_scriptHash;
+}
+
+void CachedScript::finishLoading(SharedBuffer* data)
{
m_data = data;
- setEncodedSize(m_data.get() ? m_data->size() : 0);
+ setEncodedSize(data ? data->size() : 0);
CachedResource::finishLoading(data);
}
@@ -93,27 +117,40 @@ void CachedScript::destroyDecodedData()
{
m_script = String();
setDecodedSize(0);
- if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
- makePurgeable(true);
+}
+
+void CachedScript::setBodyDataFrom(const CachedResource& resource)
+{
+ ASSERT(resource.type() == type());
+ auto& script = static_cast<const CachedScript&>(resource);
+
+ CachedResource::setBodyDataFrom(resource);
+
+ m_script = script.m_script;
+ m_scriptHash = script.m_scriptHash;
+ m_decodingState = script.m_decodingState;
+ m_decoder = script.m_decoder;
}
#if ENABLE(NOSNIFF)
bool CachedScript::mimeTypeAllowedByNosniff() const
{
- return !parseContentTypeOptionsHeader(m_response.httpHeaderField("X-Content-Type-Options")) == ContentTypeOptionsNosniff || MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType());
+ return parseContentTypeOptionsHeader(m_response.httpHeaderField(HTTPHeaderName::XContentTypeOptions)) != ContentTypeOptionsNosniff || MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType());
}
#endif
bool CachedScript::shouldIgnoreHTTPStatusCodeErrors() const
{
+#if PLATFORM(MAC)
// This is a workaround for <rdar://problem/13916291>
// REGRESSION (r119759): Adobe Flash Player "smaller" installer relies on the incorrect firing
// of a load event and needs an app-specific hack for compatibility.
// The installer in question tries to load .js file that doesn't exist, causing the server to
// return a 404 response. Normally, this would trigger an error event to be dispatched, but the
// installer expects a load event instead so we work around it here.
- if (applicationIsSolidStateNetworksDownloader())
+ if (MacApplication::isSolidStateNetworksDownloader())
return true;
+#endif
return CachedResource::shouldIgnoreHTTPStatusCodeErrors();
}