Index: Source/core/inspector/InspectorPageAgent.cpp |
diff --git a/Source/core/inspector/InspectorPageAgent.cpp b/Source/core/inspector/InspectorPageAgent.cpp |
index 51f34a4baad00791969311c8a6eacd217e689107..37ae986d8c7552339654f789149983a697905eee 100644 |
--- a/Source/core/inspector/InspectorPageAgent.cpp |
+++ b/Source/core/inspector/InspectorPageAgent.cpp |
@@ -47,6 +47,9 @@ |
#include "core/fetch/ResourceFetcher.h" |
#include "core/fetch/ScriptResource.h" |
#include "core/fetch/TextResourceDecoder.h" |
+#include "core/fileapi/Blob.h" |
+#include "core/fileapi/FileReaderLoader.h" |
+#include "core/fileapi/FileReaderLoaderClient.h" |
#include "core/html/HTMLFrameOwnerElement.h" |
#include "core/inspector/ContentSearchUtils.h" |
#include "core/inspector/DOMPatchSupport.h" |
@@ -77,6 +80,8 @@ |
#include "wtf/text/Base64.h" |
#include "wtf/text/TextEncoding.h" |
+typedef WebCore::InspectorBackendDispatcher::PageCommandHandler::GetResourceContentCallback GetResourceContentCallback; |
+ |
namespace WebCore { |
namespace PageAgentState { |
@@ -101,6 +106,66 @@ static const char forceCompositingMode[] = "forceCompositingMode"; |
namespace { |
+class InspectorPageFileReaderLoaderClient : public FileReaderLoaderClient { |
+ WTF_MAKE_NONCOPYABLE(InspectorPageFileReaderLoaderClient); |
+public: |
+ InspectorPageFileReaderLoaderClient(PassRefPtr<GetResourceContentCallback> callback) |
+ : m_callback(callback) { } |
+ |
+ void didStartLoading() |
+ { |
+ ASSERT(m_loader); |
+ } |
+ |
+ void didReceiveData() |
+ { |
+ ASSERT(m_loader); |
+ } |
+ |
+ void didFinishLoading() |
+ { |
+ ASSERT(m_loader); |
+ if (!m_decoder) { |
+ m_callback->sendSuccess(String(""), false); |
+ } else { |
+ RefPtr<ArrayBuffer> buffer = m_loader->arrayBufferResult(); |
+ String content = m_decoder->decode(static_cast<const char*>(buffer->data()), buffer->byteLength()); |
+ m_callback->sendSuccess(content + m_decoder->flush(), false); |
+ } |
+ dispose(); |
+ } |
+ |
+ void didFail(FileError::ErrorCode errorCode) |
+ { |
+ m_callback->sendFailure("Failed to load Blob: error code = " + String::number(errorCode)); // FIXME: Generate human-friendly reason message. |
+ dispose(); |
+ } |
+ |
+ void setLoader(PassOwnPtr<FileReaderLoader> loader) |
+ { |
+ m_loader = loader; |
+ } |
+ |
+ void start(Document* document, PassRefPtr<Blob> prpBlob, const String& textEncodingName) |
+ { |
+ ASSERT(m_loader); |
+ RefPtr<Blob> blob = prpBlob; |
+ m_decoder = InspectorPageAgent::createXHRTextDecoder(blob->type(), textEncodingName); |
+ m_loader->start(document, *blob); |
+ } |
+ |
+private: |
+ void dispose() |
+ { |
+ m_loader.clear(); |
+ delete this; |
+ } |
+ |
+ OwnPtr<FileReaderLoader> m_loader; |
+ RefPtr<GetResourceContentCallback> m_callback; |
+ RefPtr<TextResourceDecoder> m_decoder; |
+}; |
+ |
KURL urlWithoutFragment(const KURL& url) |
{ |
KURL result = url; |
@@ -122,12 +187,18 @@ static bool decodeBuffer(const char* buffer, unsigned size, const String& textEn |
return false; |
} |
-static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize) |
+static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize, bool* hasBlob) |
{ |
*hasZeroSize = false; |
+ *hasBlob = false; |
if (!cachedResource) |
return false; |
+ if (!cachedResource->response().downloadedFilePath().isEmpty()) { |
+ *hasBlob = true; |
+ return true; |
+ } |
+ |
// Zero-sized resources don't have data at all -- so fake the empty buffer, instead of indicating error by returning 0. |
if (!cachedResource->encodedSize()) { |
*hasZeroSize = true; |
@@ -154,7 +225,7 @@ static bool hasTextContent(Resource* cachedResource) |
return type == InspectorPageAgent::DocumentResource || type == InspectorPageAgent::StylesheetResource || type == InspectorPageAgent::ScriptResource || type == InspectorPageAgent::XHRResource; |
} |
-static PassRefPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeType, const String& textEncodingName) |
+PassRefPtr<TextResourceDecoder> InspectorPageAgent::createXHRTextDecoder(const String& mimeType, const String& textEncodingName) |
{ |
RefPtr<TextResourceDecoder> decoder; |
if (!textEncodingName.isEmpty()) |
@@ -169,13 +240,24 @@ static PassRefPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeTy |
return decoder; |
} |
-bool InspectorPageAgent::cachedResourceContent(Resource* cachedResource, String* result, bool* base64Encoded) |
+bool InspectorPageAgent::cachedResourceContentOrBlob(Resource* cachedResource, String* result, bool* base64Encoded, RefPtr<Blob>* blob, String* textEncodingName) |
{ |
bool hasZeroSize; |
- bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize); |
+ bool hasBlob; |
+ bool prepared = prepareResourceBuffer(cachedResource, &hasZeroSize, &hasBlob); |
if (!prepared) |
return false; |
+ if (hasBlob) { |
+ const String& filePath = cachedResource->response().downloadedFilePath(); |
+ OwnPtr<BlobData> blobData = BlobData::create(); |
+ blobData->appendFile(filePath); |
+ blobData->setContentType(cachedResource->response().mimeType()); |
+ *blob = Blob::create(blobData.release(), cachedResource->encodedSize()); |
+ *textEncodingName = cachedResource->response().textEncodingName(); |
+ return true; |
+ } |
+ |
*base64Encoded = !hasTextContent(cachedResource); |
if (*base64Encoded) { |
RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer(); |
@@ -244,12 +326,12 @@ PassOwnPtr<InspectorPageAgent> InspectorPageAgent::create(InstrumentingAgents* i |
} |
// static |
-void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame, const KURL& url, String* result, bool* base64Encoded) |
+void InspectorPageAgent::resourceContentOrBlob(ErrorString* errorString, Frame* frame, const KURL& url, String* result, bool* base64Encoded, RefPtr<Blob>* blob, String* textEncodingName) |
{ |
DocumentLoader* loader = assertDocumentLoader(errorString, frame); |
if (!loader) |
return; |
- if (!cachedResourceContent(cachedResource(frame, url), result, base64Encoded)) |
+ if (!cachedResourceContentOrBlob(cachedResource(frame, url), result, base64Encoded, blob, textEncodingName)) |
*errorString = "No resource with given URL found"; |
} |
@@ -569,12 +651,38 @@ void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page: |
object = buildObjectForFrameTree(m_page->mainFrame()); |
} |
-void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, String* content, bool* base64Encoded) |
+void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, PassRefPtr<GetResourceContentCallback> prpCallback) |
{ |
+ RefPtr<GetResourceContentCallback> callback = prpCallback; |
+ if (!callback->isActive()) |
+ return; |
+ |
Frame* frame = assertFrame(errorString, frameId); |
if (!frame) |
return; |
- resourceContent(errorString, frame, KURL(ParsedURLString, url), content, base64Encoded); |
+ |
+ Document* document = frame->document(); |
+ if (!document) { |
+ *errorString = "No Document instance for the specified frame"; |
+ return; |
+ } |
+ |
+ String content; |
+ bool base64Encoded; |
+ RefPtr<Blob> blob; |
+ String textEncodingName; |
+ resourceContentOrBlob(errorString, frame, KURL(ParsedURLString, url), &content, &base64Encoded, &blob, &textEncodingName); |
+ if (!errorString->isEmpty()) |
+ return; |
+ |
+ if (blob) { |
+ InspectorPageFileReaderLoaderClient* client = new InspectorPageFileReaderLoaderClient(callback); |
+ OwnPtr<FileReaderLoader> loader = adoptPtr(new FileReaderLoader(FileReaderLoader::ReadAsArrayBuffer, client)); |
+ client->setLoader(loader.release()); |
+ client->start(document, blob.release(), textEncodingName); |
+ } else { |
+ callback->sendSuccess(content, base64Encoded); |
+ } |
} |
static bool textContentForResource(Resource* cachedResource, String* result) |
@@ -582,9 +690,12 @@ static bool textContentForResource(Resource* cachedResource, String* result) |
if (hasTextContent(cachedResource)) { |
String content; |
bool base64Encoded; |
- if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) { |
+ RefPtr<Blob> blob; |
+ String textEncodingName; |
+ if (InspectorPageAgent::cachedResourceContentOrBlob(cachedResource, result, &base64Encoded, &blob, &textEncodingName)) { |
ASSERT(!base64Encoded); |
- return true; |
+ if (!blob) |
+ return true; |
} |
} |
return false; |