Skip to content
Permalink
Browse files
Handle NP_ASFILE and NP_ASFILEONLY transfer modes
https://bugs.webkit.org/show_bug.cgi?id=42587

Reviewed by Darin Adler, Adam Roben, Dan Bernstein and Sam Weinig.

WebCore:

* WebCore.exp.in:
Export functions from FileSystem.h

* platform/mac/FileSystemMac.mm:
(WebCore::openTemporaryFile):
Try to create a temporary file using mkstemp.

WebKit2:

* WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
(WebKit::NetscapePlugin::NPP_StreamAsFile):
* WebProcess/Plugins/Netscape/NetscapePlugin.h:
Add NPP_ wrapper.

* WebProcess/Plugins/Netscape/NetscapePluginStream.cpp:
(WebKit::NetscapePluginStream::NetscapePluginStream):
Initialize m_fileHandle.

(WebKit::isSupportedTransferMode):
NP_ASFILE and NP_ASFILEONLY is now supported.

(WebKit::NetscapePluginStream::deliverData):
Call deliverDataToFile if necessary.

(WebKit::NetscapePluginStream::deliverDataToFile):
Create a temporary file and write the data into it.

(WebKit::NetscapePluginStream::stop):
If the transfer mode is either NP_ASFILE or NP_ASFILEONLY, make sure to
call NPP_StreamAsFile and close the file and delete it.

* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::cancelStreamLoad):
Keep a reference to the Stream since cancelling it will remove it from the map.

Canonical link: https://commits.webkit.org/54542@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@63704 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Anders Carlsson committed Jul 20, 2010
1 parent 4428b6f commit 9037abe57dd0c3938241a759c18392d79e1179d3
@@ -1,3 +1,17 @@
2010-07-19 Anders Carlsson <andersca@apple.com>

Reviewed by Darin Adler, Adam Roben, Dan Bernstein and Sam Weinig.

Handle NP_ASFILE and NP_ASFILEONLY transfer modes
https://bugs.webkit.org/show_bug.cgi?id=42587

* WebCore.exp.in:
Export functions from FileSystem.h

* platform/mac/FileSystemMac.mm:
(WebCore::openTemporaryFile):
Try to create a temporary file using mkstemp.

2010-07-19 Anders Carlsson <andersca@apple.com>

Reviewed by Sam Weinig.
@@ -139,6 +139,7 @@ __ZN7WebCore10ScrollView20setCanHaveScrollbarsEb
__ZN7WebCore10StringImpl14createCFStringEv
__ZN7WebCore10StringImplcvP8NSStringEv
__ZN7WebCore20SpaceSplitStringData12createVectorEv
__ZN7WebCore10deleteFileERKNS_6StringE
__ZN7WebCore10handCursorEv
__ZN7WebCore10setCookiesEPNS_8DocumentERKNS_4KURLERKNS_6StringE
__ZN7WebCore11BitmapImageC1EP7CGImagePNS_13ImageObserverE
@@ -202,9 +203,9 @@ __ZN7WebCore11HistoryItemD1Ev
__ZN7WebCore11IconFetcher6cancelEv
__ZN7WebCore11IconFetcher6createEPNS_5FrameEPNS_17IconFetcherClientE
__ZN7WebCore11RenderLayer19scrollRectToVisibleERKNS_7IntRectEbRKNS_15ScrollAlignmentES6_
__ZNK7WebCore11RenderLayer19absoluteBoundingBoxEv
__ZN7WebCore11globalPointERK8_NSPointP8NSWindow
__ZN7WebCore11toUserSpaceERK7_NSRectP8NSWindow
__ZN7WebCore11writeToFileEiPKci
__ZN7WebCore12ChromeClient20paintCustomScrollbarEPNS_15GraphicsContextERKNS_9FloatRectENS_20ScrollbarControlSizeEjNS_13ScrollbarPartEbffj
__ZN7WebCore12ChromeClient23paintCustomScrollCornerEPNS_15GraphicsContextERKNS_9FloatRectE
__ZN7WebCore12EventHandler10mouseMovedEP7NSEvent
@@ -401,6 +402,7 @@ __ZN7WebCore17GlyphPageTreeNode18treeGlyphPageCountEv
__ZN7WebCore17HTMLPlugInElement11getNPObjectEv
__ZN7WebCore17HistoryController26saveDocumentAndScrollStateEv
__ZN7WebCore17nameForCursorTypeENS_6Cursor4TypeE
__ZN7WebCore17openTemporaryFileEPKcRi
__ZN7WebCore18deprecatedParseURLERKNS_6StringE
__ZN7WebCore18isStartOfParagraphERKNS_15VisiblePositionE
__ZN7WebCore19AnimationController16resumeAnimationsEPNS_8DocumentE
@@ -785,10 +787,11 @@ __ZN7WebCore9TimerBase4stopEv
__ZN7WebCore9TimerBase5startEdd
__ZN7WebCore9TimerBaseC2Ev
__ZN7WebCore9TimerBaseD2Ev
__ZN7WebCore9toElementEN3JSC7JSValueE
__ZN7WebCore9closeFileERi
__ZN7WebCore9fontCacheEv
__ZN7WebCore9makeRangeERKNS_15VisiblePositionES2_
__ZN7WebCore9pageCacheEv
__ZN7WebCore9toElementEN3JSC7JSValueE
__ZN7WebCoreeqERKNS_19ResourceRequestBaseES2_
__ZNK3JSC8Bindings10RootObject12globalObjectEv
__ZNK7WebCore10FloatPointcv8_NSPointEv
@@ -825,6 +828,7 @@ __ZNK7WebCore11HistoryItem8childrenEv
__ZNK7WebCore11HistoryItem8referrerEv
__ZNK7WebCore11HistoryItem9urlStringEv
__ZNK7WebCore11HistoryItem9viewStateEv
__ZNK7WebCore11RenderLayer19absoluteBoundingBoxEv
__ZNK7WebCore11RenderStyle21visitedDependentColorEi
__ZNK7WebCore11ScriptValue9getStringEPN3JSC9ExecStateERNS_6StringE
__ZNK7WebCore12EventHandler20currentKeyboardEventEv
@@ -1070,7 +1070,7 @@
513F14540AB634C400094DDF /* IconLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 513F14520AB634C400094DDF /* IconLoader.h */; };
514185EE0CD65F0400763C99 /* ChangeVersionWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 514185EC0CD65F0400763C99 /* ChangeVersionWrapper.h */; };
514185EF0CD65F0400763C99 /* ChangeVersionWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514185ED0CD65F0400763C99 /* ChangeVersionWrapper.cpp */; };
514B3F730C722047000530DF /* FileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 514B3F720C722047000530DF /* FileSystem.h */; };
514B3F730C722047000530DF /* FileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 514B3F720C722047000530DF /* FileSystem.h */; settings = {ATTRIBUTES = (Private, ); }; };
514B3F760C722055000530DF /* FileSystemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 514B3F750C722055000530DF /* FileSystemMac.mm */; };
514C76370CE9225E007EF3CD /* JSSQLError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514C76350CE9225E007EF3CD /* JSSQLError.cpp */; };
514C76380CE9225E007EF3CD /* JSSQLTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514C76360CE9225E007EF3CD /* JSSQLTransaction.cpp */; };
@@ -29,6 +29,7 @@
#import "FileSystem.h"

#import "PlatformString.h"
#import <wtf/text/CString.h>

namespace WebCore {

@@ -37,4 +38,28 @@ String homeDirectoryPath()
return NSHomeDirectory();
}

CString openTemporaryFile(const char* prefix, PlatformFileHandle& platformFileHandle)
{
platformFileHandle = invalidPlatformFileHandle;

Vector<char> temporaryFilePath(PATH_MAX);
if (!confstr(_CS_DARWIN_USER_TEMP_DIR, temporaryFilePath.data(), temporaryFilePath.size()))
return CString();

// Shrink the vector.
temporaryFilePath.shrink(strlen(temporaryFilePath.data()));
ASSERT(temporaryFilePath.last() == '/');

// Append the file name.
temporaryFilePath.append(prefix, strlen(prefix));
temporaryFilePath.append("XXXXXX", 6);
temporaryFilePath.append('\0');

platformFileHandle = mkstemp(temporaryFilePath.data());
if (platformFileHandle == invalidPlatformFileHandle)
return CString();

return CString(temporaryFilePath.data());
}

} // namespace WebCore
@@ -1,3 +1,36 @@
2010-07-19 Anders Carlsson <andersca@apple.com>

Reviewed by Darin Adler, Adam Roben, Dan Bernstein and Sam Weinig.

Handle NP_ASFILE and NP_ASFILEONLY transfer modes
https://bugs.webkit.org/show_bug.cgi?id=42587

* WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
(WebKit::NetscapePlugin::NPP_StreamAsFile):
* WebProcess/Plugins/Netscape/NetscapePlugin.h:
Add NPP_ wrapper.

* WebProcess/Plugins/Netscape/NetscapePluginStream.cpp:
(WebKit::NetscapePluginStream::NetscapePluginStream):
Initialize m_fileHandle.

(WebKit::isSupportedTransferMode):
NP_ASFILE and NP_ASFILEONLY is now supported.

(WebKit::NetscapePluginStream::deliverData):
Call deliverDataToFile if necessary.

(WebKit::NetscapePluginStream::deliverDataToFile):
Create a temporary file and write the data into it.

(WebKit::NetscapePluginStream::stop):
If the transfer mode is either NP_ASFILE or NP_ASFILEONLY, make sure to
call NPP_StreamAsFile and close the file and delete it.

* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::cancelStreamLoad):
Keep a reference to the Stream since cancelling it will remove it from the map.

2010-07-19 Anders Carlsson <andersca@apple.com>

Reviewed by Sam Weinig.
@@ -190,6 +190,11 @@ NPError NetscapePlugin::NPP_DestroyStream(NPStream* stream, NPReason reason)
return m_pluginModule->pluginFuncs().destroystream(&m_npp, stream, reason);
}

void NetscapePlugin::NPP_StreamAsFile(NPStream* stream, const char* filename)
{
return m_pluginModule->pluginFuncs().asfile(&m_npp, stream, filename);
}

int32_t NetscapePlugin::NPP_WriteReady(NPStream* stream)
{
return m_pluginModule->pluginFuncs().writeready(&m_npp, stream);
@@ -73,6 +73,8 @@ class NetscapePlugin : public Plugin {
NPError NPP_SetWindow(NPWindow*);
NPError NPP_NewStream(NPMIMEType, NPStream*, NPBool seekable, uint16_t* stype);
NPError NPP_DestroyStream(NPStream*, NPReason);
void NPP_StreamAsFile(NPStream*, const char* filename);

int32_t NPP_WriteReady(NPStream*);
int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer);
void NPP_URLNotify(const char* url, NPReason, void* notifyData);
@@ -41,6 +41,7 @@ NetscapePluginStream::NetscapePluginStream(PassRefPtr<NetscapePlugin> plugin, ui
, m_npStream()
, m_transferMode(NP_NORMAL)
, m_offset(0)
, m_fileHandle(invalidPlatformFileHandle)
, m_isStarted(false)
#if !ASSERT_DISABLED
, m_urlNotifyHasBeenCalled(false)
@@ -54,6 +55,7 @@ NetscapePluginStream::~NetscapePluginStream()
{
ASSERT(!m_isStarted);
ASSERT(!m_sendNotification || m_urlNotifyHasBeenCalled);
ASSERT(m_fileHandle == invalidPlatformFileHandle);
}

void NetscapePluginStream::didReceiveResponse(const KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers)
@@ -127,12 +129,10 @@ NPError NetscapePluginStream::destroy(NPReason reason)
static bool isSupportedTransferMode(uint16_t transferMode)
{
switch (transferMode) {
case NP_NORMAL:
return true;
// FIXME: We don't support streaming to files.
case NP_ASFILEONLY:
case NP_ASFILE:
return false;
case NP_NORMAL:
return true;
// FIXME: We don't support seekable streams.
case NP_SEEK:
return false;
@@ -190,7 +190,8 @@ void NetscapePluginStream::deliverData(const char* bytes, int length)
deliverDataToPlugin();
}

// FIXME: Deliver the data to a file as well if needed.
if (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY)
deliverDataToFile(bytes, length);
}

void NetscapePluginStream::deliverDataToPlugin()
@@ -247,6 +248,31 @@ void NetscapePluginStream::deliverDataToPlugin()
}
}

void NetscapePluginStream::deliverDataToFile(const char* bytes, int length)
{
if (m_fileHandle == invalidPlatformFileHandle && m_filePath.isNull()) {
// Create a temporary file.
m_filePath = openTemporaryFile("WebKitPluginStream", m_fileHandle);

// We failed to open the file, stop the stream.
if (m_fileHandle == invalidPlatformFileHandle) {
stop(NPRES_NETWORK_ERR);
return;
}
}

if (!length)
return;

int byteCount = writeToFile(m_fileHandle, bytes, length);
if (byteCount != length) {
// This happens only rarely, when we are out of disk space or have a disk I/O error.
closeFile(m_fileHandle);

stop(NPRES_NETWORK_ERR);
}
}

void NetscapePluginStream::stop(NPReason reason)
{
ASSERT(m_isStarted);
@@ -265,6 +291,34 @@ void NetscapePluginStream::stop(NPReason reason)
m_deliveryData = 0;
m_deliveryDataTimer.stop();

if (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY) {
if (reason == NPRES_DONE) {
// Ensure that the file is created.
deliverDataToFile(0, 0);
if (m_fileHandle != invalidPlatformFileHandle)
closeFile(m_fileHandle);

ASSERT(!m_filePath.isNull());

m_plugin->NPP_StreamAsFile(&m_npStream, m_filePath.data());
} else {
// Just close the file.
if (m_fileHandle != invalidPlatformFileHandle)
closeFile(m_fileHandle);
}

// Delete the file after calling NPP_StreamAsFile(), instead of in the destructor. It should be OK
// to delete the file here -- NPP_StreamAsFile() is always called immediately before NPP_DestroyStream()
// (the stream destruction function), so there can be no expectation that a plugin will read the stream
// file asynchronously after NPP_StreamAsFile() is called.
deleteFile(String::fromUTF8(m_filePath.data()));
m_filePath = CString();

// NPP_StreamAsFile could call NPN_DestroyStream and destroy the stream.
if (!m_isStarted)
return;
}

// Set m_isStarted to false before calling NPP_DestroyStream in case NPP_DestroyStream calls NPN_DestroyStream.
m_isStarted = false;

@@ -27,6 +27,7 @@
#define NetscapePluginStream_h

#include "RunLoop.h"
#include <WebCore/FileSystem.h>
#include <WebCore/npapi.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -75,6 +76,7 @@ class NetscapePluginStream : public RefCounted<NetscapePluginStream> {

void deliverData(const char* bytes, int length);
void deliverDataToPlugin();
void deliverDataToFile(const char* bytes, int length);

RefPtr<NetscapePlugin> m_plugin;
uint64_t m_streamID;
@@ -86,6 +88,9 @@ class NetscapePluginStream : public RefCounted<NetscapePluginStream> {
uint16_t m_transferMode;
int32_t m_offset;

CString m_filePath;
WebCore::PlatformFileHandle m_fileHandle;

// Whether NPP_NewStream has successfully been called.
bool m_isStarted;

@@ -371,7 +371,7 @@ void PluginView::performURLRequest(URLRequest* request)
}

// This request is to load a URL and create a stream.
RefPtr<PluginView::Stream> stream = PluginView::Stream::create(this, request->requestID(), request->request());
RefPtr<Stream> stream = PluginView::Stream::create(this, request->requestID(), request->request());
addStream(stream.get());
stream->start();
}
@@ -536,12 +536,15 @@ void PluginView::loadURL(uint64_t requestID, const String& method, const String&

void PluginView::cancelStreamLoad(uint64_t streamID)
{
PluginView::Stream* stream = m_streams.get(streamID).get();
// Keep a reference to the stream. Stream::cancel might remove the stream from the map, and thus
// releasing its last reference.
RefPtr<Stream> stream = m_streams.get(streamID).get();
if (!stream)
return;

// Cancelling the stream here will remove it from the map.
stream->cancel();
removeStream(stream);
ASSERT(!m_streams.contains(streamID));
}

NPObject* PluginView::windowScriptNPObject()

0 comments on commit 9037abe

Please sign in to comment.