2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "modules/filesystem/InspectorFileSystemAgent.h"
34 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
35 #include "core/dom/DOMImplementation.h"
36 #include "core/dom/Document.h"
37 #include "core/events/Event.h"
38 #include "core/fileapi/File.h"
39 #include "core/fileapi/FileError.h"
40 #include "core/fileapi/FileReader.h"
41 #include "core/frame/LocalFrame.h"
42 #include "core/html/VoidCallback.h"
43 #include "core/html/parser/TextResourceDecoder.h"
44 #include "core/inspector/InspectorState.h"
45 #include "core/page/Page.h"
46 #include "modules/filesystem/DOMFileSystem.h"
47 #include "modules/filesystem/DirectoryEntry.h"
48 #include "modules/filesystem/DirectoryReader.h"
49 #include "modules/filesystem/EntriesCallback.h"
50 #include "modules/filesystem/Entry.h"
51 #include "modules/filesystem/EntryCallback.h"
52 #include "modules/filesystem/ErrorCallback.h"
53 #include "modules/filesystem/FileCallback.h"
54 #include "modules/filesystem/FileEntry.h"
55 #include "modules/filesystem/FileSystemCallbacks.h"
56 #include "modules/filesystem/LocalFileSystem.h"
57 #include "modules/filesystem/Metadata.h"
58 #include "modules/filesystem/MetadataCallback.h"
59 #include "platform/MIMETypeRegistry.h"
60 #include "platform/heap/Handle.h"
61 #include "platform/weborigin/KURL.h"
62 #include "platform/weborigin/SecurityOrigin.h"
63 #include "wtf/ArrayBuffer.h"
64 #include "wtf/text/Base64.h"
65 #include "wtf/text/TextEncoding.h"
67 using blink::TypeBuilder::Array;
69 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::RequestFileSystemRootCallback RequestFileSystemRootCallback;
70 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::RequestDirectoryContentCallback RequestDirectoryContentCallback;
71 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::RequestMetadataCallback RequestMetadataCallback;
72 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::RequestFileContentCallback RequestFileContentCallback;
73 typedef blink::InspectorBackendDispatcher::FileSystemCommandHandler::DeleteEntryCallback DeleteEntryCallback;
77 namespace FileSystemAgentState {
78 static const char fileSystemAgentEnabled[] = "fileSystemAgentEnabled";
83 template<typename BaseCallback, typename Handler, typename Argument>
84 class CallbackDispatcher FINAL : public BaseCallback {
86 typedef bool (Handler::*HandlingMethod)(Argument);
88 static CallbackDispatcher* create(PassRefPtr<Handler> handler, HandlingMethod handlingMethod)
90 return new CallbackDispatcher(handler, handlingMethod);
93 virtual void handleEvent(Argument argument) OVERRIDE
95 (m_handler.get()->*m_handlingMethod)(argument);
99 CallbackDispatcher(PassRefPtr<Handler> handler, HandlingMethod handlingMethod)
101 , m_handlingMethod(handlingMethod) { }
103 RefPtr<Handler> m_handler;
104 HandlingMethod m_handlingMethod;
107 template<typename BaseCallback>
108 class CallbackDispatcherFactory {
110 template<typename Handler, typename Argument>
111 static CallbackDispatcher<BaseCallback, Handler, Argument>* create(Handler* handler, bool (Handler::*handlingMethod)(Argument))
113 return CallbackDispatcher<BaseCallback, Handler, Argument>::create(PassRefPtr<Handler>(handler), handlingMethod);
117 class FileSystemRootRequest : public RefCounted<FileSystemRootRequest> {
118 WTF_MAKE_NONCOPYABLE(FileSystemRootRequest);
120 static PassRefPtr<FileSystemRootRequest> create(PassRefPtrWillBeRawPtr<RequestFileSystemRootCallback> requestCallback, const String& type)
122 return adoptRef(new FileSystemRootRequest(requestCallback, type));
125 void start(ExecutionContext*);
128 bool didHitError(FileError* error)
130 reportResult(error->code());
134 bool didGetEntry(Entry*);
136 void reportResult(FileError::ErrorCode errorCode, PassRefPtr<TypeBuilder::FileSystem::Entry> entry = nullptr)
138 m_requestCallback->sendSuccess(static_cast<int>(errorCode), entry);
141 FileSystemRootRequest(PassRefPtrWillBeRawPtr<RequestFileSystemRootCallback> requestCallback, const String& type)
142 : m_requestCallback(requestCallback)
145 RefPtrWillBePersistent<RequestFileSystemRootCallback> m_requestCallback;
149 void FileSystemRootRequest::start(ExecutionContext* executionContext)
151 ASSERT(executionContext);
153 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &FileSystemRootRequest::didHitError);
156 if (!DOMFileSystemBase::pathPrefixToFileSystemType(m_type, type)) {
157 errorCallback->handleEvent(FileError::create(FileError::SYNTAX_ERR).get());
161 KURL rootURL = DOMFileSystemBase::createFileSystemRootURL(executionContext->securityOrigin()->toString(), type);
162 if (!rootURL.isValid()) {
163 errorCallback->handleEvent(FileError::create(FileError::SYNTAX_ERR).get());
167 EntryCallback* successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &FileSystemRootRequest::didGetEntry);
168 OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback, errorCallback, executionContext);
169 LocalFileSystem::from(*executionContext)->resolveURL(executionContext, rootURL, fileSystemCallbacks.release());
172 bool FileSystemRootRequest::didGetEntry(Entry* entry)
174 RefPtr<TypeBuilder::FileSystem::Entry> result = TypeBuilder::FileSystem::Entry::create()
175 .setUrl(entry->toURL())
177 .setIsDirectory(true);
178 reportResult(static_cast<FileError::ErrorCode>(0), result);
182 class DirectoryContentRequest FINAL : public RefCounted<DirectoryContentRequest> {
183 WTF_MAKE_NONCOPYABLE(DirectoryContentRequest);
185 static PassRefPtr<DirectoryContentRequest> create(PassRefPtrWillBeRawPtr<RequestDirectoryContentCallback> requestCallback, const String& url)
187 return adoptRef(new DirectoryContentRequest(requestCallback, url));
190 ~DirectoryContentRequest()
192 reportResult(FileError::ABORT_ERR);
195 void start(ExecutionContext*);
198 bool didHitError(FileError* error)
200 reportResult(error->code());
204 bool didGetEntry(Entry*);
205 bool didReadDirectoryEntries(const EntryHeapVector&);
207 void reportResult(FileError::ErrorCode errorCode, PassRefPtr<Array<TypeBuilder::FileSystem::Entry> > entries = nullptr)
209 m_requestCallback->sendSuccess(static_cast<int>(errorCode), entries);
212 DirectoryContentRequest(PassRefPtrWillBeRawPtr<RequestDirectoryContentCallback> requestCallback, const String& url)
213 : m_requestCallback(requestCallback)
214 , m_url(ParsedURLString, url) { }
216 void readDirectoryEntries();
218 RefPtrWillBePersistent<RequestDirectoryContentCallback> m_requestCallback;
220 RefPtr<Array<TypeBuilder::FileSystem::Entry> > m_entries;
221 Persistent<DirectoryReader> m_directoryReader;
224 void DirectoryContentRequest::start(ExecutionContext* executionContext)
226 ASSERT(executionContext);
228 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &DirectoryContentRequest::didHitError);
229 EntryCallback* successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &DirectoryContentRequest::didGetEntry);
231 OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback, errorCallback, executionContext);
233 LocalFileSystem::from(*executionContext)->resolveURL(executionContext, m_url, fileSystemCallbacks.release());
236 bool DirectoryContentRequest::didGetEntry(Entry* entry)
238 if (!entry->isDirectory()) {
239 reportResult(FileError::TYPE_MISMATCH_ERR);
243 m_directoryReader = toDirectoryEntry(entry)->createReader();
244 m_entries = Array<TypeBuilder::FileSystem::Entry>::create();
245 readDirectoryEntries();
249 void DirectoryContentRequest::readDirectoryEntries()
251 if (!m_directoryReader->filesystem()->executionContext()) {
252 reportResult(FileError::ABORT_ERR);
256 EntriesCallback* successCallback = CallbackDispatcherFactory<EntriesCallback>::create(this, &DirectoryContentRequest::didReadDirectoryEntries);
257 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &DirectoryContentRequest::didHitError);
258 m_directoryReader->readEntries(successCallback, errorCallback);
261 bool DirectoryContentRequest::didReadDirectoryEntries(const EntryHeapVector& entries)
263 if (entries.isEmpty()) {
264 reportResult(static_cast<FileError::ErrorCode>(0), m_entries);
268 for (size_t i = 0; i < entries.size(); ++i) {
269 Entry* entry = entries[i];
270 RefPtr<TypeBuilder::FileSystem::Entry> entryForFrontend = TypeBuilder::FileSystem::Entry::create()
271 .setUrl(entry->toURL())
272 .setName(entry->name())
273 .setIsDirectory(entry->isDirectory());
275 using TypeBuilder::Page::ResourceType;
276 if (!entry->isDirectory()) {
277 String mimeType = MIMETypeRegistry::getMIMETypeForPath(entry->name());
278 ResourceType::Enum resourceType;
279 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) {
280 resourceType = ResourceType::Image;
281 entryForFrontend->setIsTextFile(false);
282 } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType)) {
283 resourceType = ResourceType::Script;
284 entryForFrontend->setIsTextFile(true);
285 } else if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) {
286 resourceType = ResourceType::Document;
287 entryForFrontend->setIsTextFile(true);
289 resourceType = ResourceType::Other;
290 entryForFrontend->setIsTextFile(DOMImplementation::isXMLMIMEType(mimeType) || DOMImplementation::isTextMIMEType(mimeType));
293 entryForFrontend->setMimeType(mimeType);
294 entryForFrontend->setResourceType(resourceType);
297 m_entries->addItem(entryForFrontend);
299 readDirectoryEntries();
303 class MetadataRequest FINAL : public RefCounted<MetadataRequest> {
304 WTF_MAKE_NONCOPYABLE(MetadataRequest);
306 static PassRefPtr<MetadataRequest> create(PassRefPtrWillBeRawPtr<RequestMetadataCallback> requestCallback, const String& url)
308 return adoptRef(new MetadataRequest(requestCallback, url));
313 reportResult(FileError::ABORT_ERR);
316 void start(ExecutionContext*);
319 bool didHitError(FileError* error)
321 reportResult(error->code());
325 bool didGetEntry(Entry*);
326 bool didGetMetadata(Metadata*);
328 void reportResult(FileError::ErrorCode errorCode, PassRefPtr<TypeBuilder::FileSystem::Metadata> metadata = nullptr)
330 m_requestCallback->sendSuccess(static_cast<int>(errorCode), metadata);
333 MetadataRequest(PassRefPtrWillBeRawPtr<RequestMetadataCallback> requestCallback, const String& url)
334 : m_requestCallback(requestCallback)
335 , m_url(ParsedURLString, url) { }
337 RefPtrWillBePersistent<RequestMetadataCallback> m_requestCallback;
342 void MetadataRequest::start(ExecutionContext* executionContext)
344 ASSERT(executionContext);
346 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &MetadataRequest::didHitError);
347 EntryCallback* successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &MetadataRequest::didGetEntry);
348 OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback, errorCallback, executionContext);
349 LocalFileSystem::from(*executionContext)->resolveURL(executionContext, m_url, fileSystemCallbacks.release());
352 bool MetadataRequest::didGetEntry(Entry* entry)
354 if (!entry->filesystem()->executionContext()) {
355 reportResult(FileError::ABORT_ERR);
359 MetadataCallback* successCallback = CallbackDispatcherFactory<MetadataCallback>::create(this, &MetadataRequest::didGetMetadata);
360 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &MetadataRequest::didHitError);
361 entry->getMetadata(successCallback, errorCallback);
362 m_isDirectory = entry->isDirectory();
366 bool MetadataRequest::didGetMetadata(Metadata* metadata)
368 using TypeBuilder::FileSystem::Metadata;
369 RefPtr<Metadata> result = Metadata::create()
370 .setModificationTime(metadata->modificationTime())
371 .setSize(metadata->size());
372 reportResult(static_cast<FileError::ErrorCode>(0), result);
376 class FileContentRequest FINAL : public EventListener {
377 WTF_MAKE_NONCOPYABLE(FileContentRequest);
379 static PassRefPtr<FileContentRequest> create(PassRefPtrWillBeRawPtr<RequestFileContentCallback> requestCallback, const String& url, bool readAsText, long long start, long long end, const String& charset)
381 return adoptRef(new FileContentRequest(requestCallback, url, readAsText, start, end, charset));
384 virtual ~FileContentRequest()
386 reportResult(FileError::ABORT_ERR);
389 void start(ExecutionContext*);
391 virtual bool operator==(const EventListener& other) OVERRIDE
393 return this == &other;
396 virtual void handleEvent(ExecutionContext*, Event* event) OVERRIDE
398 if (event->type() == EventTypeNames::load)
400 else if (event->type() == EventTypeNames::error)
401 didHitError(m_reader->error().get());
405 bool didHitError(FileError* error)
407 reportResult(error->code());
411 bool didGetEntry(Entry*);
412 bool didGetFile(File*);
415 void reportResult(FileError::ErrorCode errorCode, const String* result = 0, const String* charset = 0)
417 m_requestCallback->sendSuccess(static_cast<int>(errorCode), result, charset);
420 FileContentRequest(PassRefPtrWillBeRawPtr<RequestFileContentCallback> requestCallback, const String& url, bool readAsText, long long start, long long end, const String& charset)
421 : EventListener(EventListener::CPPEventListenerType)
422 , m_requestCallback(requestCallback)
423 , m_url(ParsedURLString, url)
424 , m_readAsText(readAsText)
427 , m_charset(charset) { }
429 RefPtrWillBePersistent<RequestFileContentCallback> m_requestCallback;
437 RefPtrWillBePersistent<FileReader> m_reader;
440 void FileContentRequest::start(ExecutionContext* executionContext)
442 ASSERT(executionContext);
444 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &FileContentRequest::didHitError);
445 EntryCallback* successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &FileContentRequest::didGetEntry);
447 OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback, errorCallback, executionContext);
448 LocalFileSystem::from(*executionContext)->resolveURL(executionContext, m_url, fileSystemCallbacks.release());
451 bool FileContentRequest::didGetEntry(Entry* entry)
453 if (entry->isDirectory()) {
454 reportResult(FileError::TYPE_MISMATCH_ERR);
458 if (!entry->filesystem()->executionContext()) {
459 reportResult(FileError::ABORT_ERR);
463 FileCallback* successCallback = CallbackDispatcherFactory<FileCallback>::create(this, &FileContentRequest::didGetFile);
464 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &FileContentRequest::didHitError);
465 toFileEntry(entry)->file(successCallback, errorCallback);
467 m_reader = FileReader::create(entry->filesystem()->executionContext());
468 m_mimeType = MIMETypeRegistry::getMIMETypeForPath(entry->name());
473 bool FileContentRequest::didGetFile(File* file)
475 RefPtrWillBeRawPtr<Blob> blob = static_cast<Blob*>(file)->slice(m_start, m_end, IGNORE_EXCEPTION);
476 m_reader->setOnload(this);
477 m_reader->setOnerror(this);
479 m_reader->readAsArrayBuffer(blob.get(), IGNORE_EXCEPTION);
483 void FileContentRequest::didRead()
485 RefPtr<ArrayBuffer> buffer = m_reader->arrayBufferResult();
488 String result = base64Encode(static_cast<char*>(buffer->data()), buffer->byteLength());
489 reportResult(static_cast<FileError::ErrorCode>(0), &result, 0);
493 OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create(m_mimeType, m_charset, true);
494 String result = decoder->decode(static_cast<char*>(buffer->data()), buffer->byteLength());
495 result = result + decoder->flush();
496 m_charset = decoder->encoding().name();
497 reportResult(static_cast<FileError::ErrorCode>(0), &result, &m_charset);
500 class DeleteEntryRequest FINAL : public RefCounted<DeleteEntryRequest> {
502 static PassRefPtr<DeleteEntryRequest> create(PassRefPtrWillBeRawPtr<DeleteEntryCallback> requestCallback, const KURL& url)
504 return adoptRef(new DeleteEntryRequest(requestCallback, url));
507 ~DeleteEntryRequest()
509 reportResult(FileError::ABORT_ERR);
512 void start(ExecutionContext*);
515 // CallbackDispatcherFactory doesn't handle 0-arg handleEvent methods
516 class VoidCallbackImpl FINAL : public VoidCallback {
518 explicit VoidCallbackImpl(PassRefPtr<DeleteEntryRequest> handler)
523 virtual void handleEvent() OVERRIDE
525 m_handler->didDeleteEntry();
529 RefPtr<DeleteEntryRequest> m_handler;
532 bool didHitError(FileError* error)
534 reportResult(error->code());
538 bool didGetEntry(Entry*);
539 bool didDeleteEntry();
541 void reportResult(FileError::ErrorCode errorCode)
543 m_requestCallback->sendSuccess(static_cast<int>(errorCode));
546 DeleteEntryRequest(PassRefPtrWillBeRawPtr<DeleteEntryCallback> requestCallback, const KURL& url)
547 : m_requestCallback(requestCallback)
550 RefPtrWillBePersistent<DeleteEntryCallback> m_requestCallback;
554 void DeleteEntryRequest::start(ExecutionContext* executionContext)
556 ASSERT(executionContext);
558 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &DeleteEntryRequest::didHitError);
562 if (!DOMFileSystemBase::crackFileSystemURL(m_url, type, path)) {
563 errorCallback->handleEvent(FileError::create(FileError::SYNTAX_ERR).get());
568 VoidCallback* successCallback = new VoidCallbackImpl(this);
569 OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = VoidCallbacks::create(successCallback, errorCallback, executionContext, nullptr);
570 LocalFileSystem::from(*executionContext)->deleteFileSystem(executionContext, type, fileSystemCallbacks.release());
572 EntryCallback* successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &DeleteEntryRequest::didGetEntry);
573 OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback, errorCallback, executionContext);
574 LocalFileSystem::from(*executionContext)->resolveURL(executionContext, m_url, fileSystemCallbacks.release());
578 bool DeleteEntryRequest::didGetEntry(Entry* entry)
580 VoidCallback* successCallback = new VoidCallbackImpl(this);
581 ErrorCallback* errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &DeleteEntryRequest::didHitError);
582 if (entry->isDirectory()) {
583 DirectoryEntry* directoryEntry = toDirectoryEntry(entry);
584 directoryEntry->removeRecursively(successCallback, errorCallback);
586 entry->remove(successCallback, errorCallback);
591 bool DeleteEntryRequest::didDeleteEntry()
593 reportResult(static_cast<FileError::ErrorCode>(0));
597 } // anonymous namespace
600 PassOwnPtrWillBeRawPtr<InspectorFileSystemAgent> InspectorFileSystemAgent::create(Page* page)
602 return adoptPtrWillBeNoop(new InspectorFileSystemAgent(page));
605 InspectorFileSystemAgent::~InspectorFileSystemAgent()
609 void InspectorFileSystemAgent::enable(ErrorString*)
614 m_state->setBoolean(FileSystemAgentState::fileSystemAgentEnabled, m_enabled);
617 void InspectorFileSystemAgent::disable(ErrorString*)
622 m_state->setBoolean(FileSystemAgentState::fileSystemAgentEnabled, m_enabled);
625 void InspectorFileSystemAgent::requestFileSystemRoot(ErrorString* error, const String& origin, const String& type, PassRefPtrWillBeRawPtr<RequestFileSystemRootCallback> requestCallback)
627 if (!assertEnabled(error))
630 ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::createFromString(origin).get());
631 if (!executionContext)
634 FileSystemRootRequest::create(requestCallback, type)->start(executionContext);
637 void InspectorFileSystemAgent::requestDirectoryContent(ErrorString* error, const String& url, PassRefPtrWillBeRawPtr<RequestDirectoryContentCallback> requestCallback)
639 if (!assertEnabled(error))
642 ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::createFromString(url).get());
643 if (!executionContext)
646 DirectoryContentRequest::create(requestCallback, url)->start(executionContext);
649 void InspectorFileSystemAgent::requestMetadata(ErrorString* error, const String& url, PassRefPtrWillBeRawPtr<RequestMetadataCallback> requestCallback)
651 if (!assertEnabled(error))
654 ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::createFromString(url).get());
655 if (!executionContext)
658 MetadataRequest::create(requestCallback, url)->start(executionContext);
661 void InspectorFileSystemAgent::requestFileContent(ErrorString* error, const String& url, bool readAsText, const int* start, const int* end, const String* charset, PassRefPtrWillBeRawPtr<RequestFileContentCallback> requestCallback)
663 if (!assertEnabled(error))
666 ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::createFromString(url).get());
667 if (!executionContext)
670 long long startPosition = start ? *start : 0;
671 long long endPosition = end ? *end : std::numeric_limits<long long>::max();
672 FileContentRequest::create(requestCallback, url, readAsText, startPosition, endPosition, charset ? *charset : "")->start(executionContext);
675 void InspectorFileSystemAgent::deleteEntry(ErrorString* error, const String& urlString, PassRefPtrWillBeRawPtr<DeleteEntryCallback> requestCallback)
677 if (!assertEnabled(error))
680 KURL url(ParsedURLString, urlString);
682 ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::create(url).get());
683 if (!executionContext)
686 DeleteEntryRequest::create(requestCallback, url)->start(executionContext);
689 void InspectorFileSystemAgent::clearFrontend()
692 m_state->setBoolean(FileSystemAgentState::fileSystemAgentEnabled, m_enabled);
695 void InspectorFileSystemAgent::restore()
697 m_enabled = m_state->getBoolean(FileSystemAgentState::fileSystemAgentEnabled);
700 InspectorFileSystemAgent::InspectorFileSystemAgent(Page* page)
701 : InspectorBaseAgent<InspectorFileSystemAgent>("FileSystem")
708 bool InspectorFileSystemAgent::assertEnabled(ErrorString* error)
711 *error = "FileSystem agent is not enabled.";
717 ExecutionContext* InspectorFileSystemAgent::assertExecutionContextForOrigin(ErrorString* error, SecurityOrigin* origin)
719 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
720 if (!frame->isLocalFrame())
722 LocalFrame* localFrame = toLocalFrame(frame);
723 if (localFrame->document() && localFrame->document()->securityOrigin()->isSameSchemeHostPort(origin))
724 return localFrame->document();
727 *error = "No frame is available for the request";
731 void InspectorFileSystemAgent::trace(Visitor* visitor)
733 visitor->trace(m_page);
734 InspectorBaseAgent::trace(visitor);