diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/plugins/PluginStream.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/plugins/PluginStream.cpp')
-rw-r--r-- | Source/WebCore/plugins/PluginStream.cpp | 483 |
1 files changed, 0 insertions, 483 deletions
diff --git a/Source/WebCore/plugins/PluginStream.cpp b/Source/WebCore/plugins/PluginStream.cpp deleted file mode 100644 index 8b3bd9929..000000000 --- a/Source/WebCore/plugins/PluginStream.cpp +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora, Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "PluginStream.h" - -#include "DocumentLoader.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "PluginDebug.h" -#include "ResourceLoadScheduler.h" -#include "SharedBuffer.h" -#include "SubresourceLoader.h" -#include <wtf/StringExtras.h> -#include <wtf/text/CString.h> -#include <wtf/text/StringBuilder.h> -#include <wtf/text/WTFString.h> - -// We use -2 here because some plugins like to return -1 to indicate error -// and this way we won't clash with them. -static const int WebReasonNone = -2; - -using std::max; -using std::min; - -namespace WebCore { - -typedef HashMap<NPStream*, NPP> StreamMap; -static StreamMap& streams() -{ - static StreamMap staticStreams; - return staticStreams; -} - -PluginStream::PluginStream(PluginStreamClient* client, Frame* frame, const ResourceRequest& resourceRequest, bool sendNotification, void* notifyData, const NPPluginFuncs* pluginFuncs, NPP instance, const PluginQuirkSet& quirks) - : m_resourceRequest(resourceRequest) - , m_client(client) - , m_frame(frame) - , m_notifyData(notifyData) - , m_sendNotification(sendNotification) - , m_streamState(StreamBeforeStarted) - , m_loadManually(false) - , m_delayDeliveryTimer(this, &PluginStream::delayDeliveryTimerFired) - , m_tempFileHandle(invalidPlatformFileHandle) - , m_pluginFuncs(pluginFuncs) - , m_instance(instance) - , m_quirks(quirks) -{ - ASSERT(m_instance); - - m_stream.url = 0; - m_stream.ndata = 0; - m_stream.pdata = 0; - m_stream.end = 0; - m_stream.notifyData = 0; - m_stream.lastmodified = 0; - m_stream.headers = 0; - - streams().add(&m_stream, m_instance); -} - -PluginStream::~PluginStream() -{ - ASSERT(m_streamState != StreamStarted); - ASSERT(!m_loader); - - fastFree((char*)m_stream.url); - - streams().remove(&m_stream); -} - -void PluginStream::start() -{ - ASSERT(!m_loadManually); - m_loader = resourceLoadScheduler()->schedulePluginStreamLoad(m_frame, this, m_resourceRequest); -} - -void PluginStream::stop() -{ - m_streamState = StreamStopped; - - if (m_loadManually) { - ASSERT(!m_loader); - - DocumentLoader* documentLoader = m_frame->loader().activeDocumentLoader(); - ASSERT(documentLoader); - - if (documentLoader->isLoadingMainResource()) - documentLoader->cancelMainResourceLoad(m_frame->loader().cancelledError(m_resourceRequest)); - - return; - } - - if (m_loader) { - m_loader->cancel(); - m_loader = 0; - } - - m_client = 0; -} - -static uint32_t lastModifiedDate(const ResourceResponse& response) -{ - double lastModified = response.lastModified(); - if (!std::isfinite(lastModified)) - return 0; - - return lastModified * 1000; -} - -void PluginStream::startStream() -{ - ASSERT(m_streamState == StreamBeforeStarted); - - const URL& responseURL = m_resourceResponse.url(); - - // Some plugins (Flash) expect that javascript URLs are passed back decoded as this is the - // format used when requesting the URL. - if (protocolIsJavaScript(responseURL)) - m_stream.url = fastStrDup(decodeURLEscapeSequences(responseURL.string()).utf8().data()); - else - m_stream.url = fastStrDup(responseURL.string().utf8().data()); - - CString mimeTypeStr = m_resourceResponse.mimeType().utf8(); - - long long expectedContentLength = m_resourceResponse.expectedContentLength(); - - if (m_resourceResponse.isHTTP()) { - StringBuilder stringBuilder; - String separator = ASCIILiteral(": "); - - String statusLine = "HTTP " + String::number(m_resourceResponse.httpStatusCode()) + " OK\n"; - stringBuilder.append(statusLine); - - HTTPHeaderMap::const_iterator end = m_resourceResponse.httpHeaderFields().end(); - for (HTTPHeaderMap::const_iterator it = m_resourceResponse.httpHeaderFields().begin(); it != end; ++it) { - stringBuilder.append(it->key); - stringBuilder.append(separator); - stringBuilder.append(it->value); - stringBuilder.append('\n'); - } - - m_headers = stringBuilder.toString().utf8(); - - // If the content is encoded (most likely compressed), then don't send its length to the plugin, - // which is only interested in the decoded length, not yet known at the moment. - // <rdar://problem/4470599> tracks a request for -[NSURLResponse expectedContentLength] to incorporate this logic. - String contentEncoding = m_resourceResponse.httpHeaderField("Content-Encoding"); - if (!contentEncoding.isNull() && contentEncoding != "identity") - expectedContentLength = -1; - } - - m_stream.headers = m_headers.data(); - m_stream.pdata = 0; - m_stream.ndata = this; - m_stream.end = max(expectedContentLength, 0LL); - m_stream.lastmodified = lastModifiedDate(m_resourceResponse); - m_stream.notifyData = m_notifyData; - - m_transferMode = NP_NORMAL; - m_offset = 0; - m_reason = WebReasonNone; - - // Protect the stream if destroystream is called from within the newstream handler - RefPtr<PluginStream> protect(this); - - // calling into a plug-in could result in re-entrance if the plug-in yields - // control to the system (rdar://5744899). prevent this by deferring further - // loading while calling into the plug-in. - if (m_loader) - m_loader->setDefersLoading(true); - NPError npErr = m_pluginFuncs->newstream(m_instance, (NPMIMEType)mimeTypeStr.data(), &m_stream, false, &m_transferMode); - if (m_loader) - m_loader->setDefersLoading(false); - - // If the stream was destroyed in the call to newstream we return - if (m_reason != WebReasonNone) - return; - - if (npErr != NPERR_NO_ERROR) { - cancelAndDestroyStream(npErr); - return; - } - - m_streamState = StreamStarted; - - if (m_transferMode == NP_NORMAL) - return; - - m_path = openTemporaryFile("WKP", m_tempFileHandle); - - // Something went wrong, cancel loading the stream - if (!isHandleValid(m_tempFileHandle)) - cancelAndDestroyStream(NPRES_NETWORK_ERR); -} - -NPP PluginStream::ownerForStream(NPStream* stream) -{ - return streams().get(stream); -} - -void PluginStream::cancelAndDestroyStream(NPReason reason) -{ - RefPtr<PluginStream> protect(this); - - destroyStream(reason); - stop(); -} - -void PluginStream::destroyStream(NPReason reason) -{ - m_reason = reason; - if (m_reason != NPRES_DONE) { - // Stop any pending data from being streamed - if (m_deliveryData) - m_deliveryData->resize(0); - } else if (m_deliveryData && m_deliveryData->size() > 0) { - // There is more data to be streamed, don't destroy the stream now. - return; - } - destroyStream(); -} - -void PluginStream::destroyStream() -{ - if (m_streamState == StreamStopped) - return; - - ASSERT(m_reason != WebReasonNone); - ASSERT(!m_deliveryData || m_deliveryData->size() == 0); - - closeFile(m_tempFileHandle); - - bool newStreamCalled = m_stream.ndata; - - // Protect from destruction if: - // NPN_DestroyStream is called from NPP_NewStream or - // PluginStreamClient::streamDidFinishLoading() removes the last reference - RefPtr<PluginStream> protect(this); - - if (newStreamCalled) { - if (m_reason == NPRES_DONE && (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY)) { - ASSERT(!m_path.isNull()); - - if (m_loader) - m_loader->setDefersLoading(true); - m_pluginFuncs->asfile(m_instance, &m_stream, m_path.utf8().data()); - if (m_loader) - m_loader->setDefersLoading(false); - } - - if (m_streamState != StreamBeforeStarted) { - if (m_loader) - m_loader->setDefersLoading(true); - - NPError npErr = m_pluginFuncs->destroystream(m_instance, &m_stream, m_reason); - - if (m_loader) - m_loader->setDefersLoading(false); - - LOG_NPERROR(npErr); - } - - m_stream.ndata = 0; - } - - if (m_sendNotification) { - // Flash 9 can dereference null if we call NPP_URLNotify without first calling NPP_NewStream - // for requests made with NPN_PostURLNotify; see <rdar://5588807> - if (m_loader) - m_loader->setDefersLoading(true); - if (!newStreamCalled && m_quirks.contains(PluginQuirkFlashURLNotifyBug) && - equalIgnoringCase(m_resourceRequest.httpMethod(), "POST")) { - m_transferMode = NP_NORMAL; - m_stream.url = ""; - m_stream.notifyData = m_notifyData; - - static char emptyMimeType[] = ""; - m_pluginFuncs->newstream(m_instance, emptyMimeType, &m_stream, false, &m_transferMode); - m_pluginFuncs->destroystream(m_instance, &m_stream, m_reason); - - // in successful requests, the URL is dynamically allocated and freed in our - // destructor, so reset it to 0 - m_stream.url = 0; - } - m_pluginFuncs->urlnotify(m_instance, m_resourceRequest.url().string().utf8().data(), m_reason, m_notifyData); - if (m_loader) - m_loader->setDefersLoading(false); - } - - m_streamState = StreamStopped; - - if (!m_loadManually && m_client) - m_client->streamDidFinishLoading(this); - - if (!m_path.isNull()) - deleteFile(m_path); -} - -void PluginStream::delayDeliveryTimerFired(Timer<PluginStream>* timer) -{ - ASSERT_UNUSED(timer, timer == &m_delayDeliveryTimer); - - deliverData(); -} - -void PluginStream::deliverData() -{ - ASSERT(m_deliveryData); - - if (m_streamState == StreamStopped) - // FIXME: We should cancel our job in the SubresourceLoader on error so we don't reach this case - return; - - ASSERT(m_streamState != StreamBeforeStarted); - - if (!m_stream.ndata || m_deliveryData->size() == 0) - return; - - int32_t totalBytes = m_deliveryData->size(); - int32_t totalBytesDelivered = 0; - - if (m_loader) - m_loader->setDefersLoading(true); - while (totalBytesDelivered < totalBytes) { - int32_t deliveryBytes = m_pluginFuncs->writeready(m_instance, &m_stream); - - if (deliveryBytes <= 0) { - m_delayDeliveryTimer.startOneShot(0); - break; - } else { - deliveryBytes = min(deliveryBytes, totalBytes - totalBytesDelivered); - int32_t dataLength = deliveryBytes; - char* data = m_deliveryData->data() + totalBytesDelivered; - - // Write the data - deliveryBytes = m_pluginFuncs->write(m_instance, &m_stream, m_offset, dataLength, (void*)data); - if (deliveryBytes < 0) { - LOG_PLUGIN_NET_ERROR(); - if (m_loader) - m_loader->setDefersLoading(false); - cancelAndDestroyStream(NPRES_NETWORK_ERR); - return; - } - deliveryBytes = min(deliveryBytes, dataLength); - m_offset += deliveryBytes; - totalBytesDelivered += deliveryBytes; - } - } - if (m_loader) - m_loader->setDefersLoading(false); - - if (totalBytesDelivered > 0) { - if (totalBytesDelivered < totalBytes) { - int remainingBytes = totalBytes - totalBytesDelivered; - memmove(m_deliveryData->data(), m_deliveryData->data() + totalBytesDelivered, remainingBytes); - m_deliveryData->resize(remainingBytes); - } else { - m_deliveryData->resize(0); - if (m_reason != WebReasonNone) - destroyStream(); - } - } -} - -void PluginStream::sendJavaScriptStream(const URL& requestURL, const CString& resultString) -{ - didReceiveResponse(0, ResourceResponse(requestURL, "text/plain", resultString.length(), "", "")); - - if (m_streamState == StreamStopped) - return; - - if (!resultString.isNull()) { - didReceiveData(0, resultString.data(), resultString.length()); - if (m_streamState == StreamStopped) - return; - } - - m_loader = 0; - - destroyStream(resultString.isNull() ? NPRES_NETWORK_ERR : NPRES_DONE); -} - -void PluginStream::didReceiveResponse(NetscapePlugInStreamLoader* loader, const ResourceResponse& response) -{ - ASSERT_UNUSED(loader, loader == m_loader); - ASSERT(m_streamState == StreamBeforeStarted); - - m_resourceResponse = response; - - startStream(); -} - -void PluginStream::didReceiveData(NetscapePlugInStreamLoader* loader, const char* data, int length) -{ - ASSERT_UNUSED(loader, loader == m_loader); - ASSERT(m_streamState == StreamStarted); - - // If the plug-in cancels the stream in deliverData it could be deleted, - // so protect it here. - RefPtr<PluginStream> protect(this); - - if (m_transferMode != NP_ASFILEONLY) { - if (!m_deliveryData) - m_deliveryData = adoptPtr(new Vector<char>); - - int oldSize = m_deliveryData->size(); - m_deliveryData->resize(oldSize + length); - memcpy(m_deliveryData->data() + oldSize, data, length); - - deliverData(); - } - - if (m_streamState != StreamStopped && isHandleValid(m_tempFileHandle)) { - int bytesWritten = writeToFile(m_tempFileHandle, data, length); - if (bytesWritten != length) - cancelAndDestroyStream(NPRES_NETWORK_ERR); - } -} - -void PluginStream::didFail(NetscapePlugInStreamLoader* loader, const ResourceError&) -{ - ASSERT_UNUSED(loader, loader == m_loader); - - LOG_PLUGIN_NET_ERROR(); - - // destroyStream can result in our being deleted - RefPtr<PluginStream> protect(this); - - destroyStream(NPRES_NETWORK_ERR); - - m_loader = 0; -} - -void PluginStream::didFinishLoading(NetscapePlugInStreamLoader* loader) -{ - ASSERT_UNUSED(loader, loader == m_loader); - ASSERT(m_streamState == StreamStarted); - - // destroyStream can result in our being deleted - RefPtr<PluginStream> protect(this); - - destroyStream(NPRES_DONE); - - m_loader = 0; -} - -bool PluginStream::wantsAllStreams() const -{ - if (!m_pluginFuncs->getvalue) - return false; - - void* result = 0; - if (m_pluginFuncs->getvalue(m_instance, NPPVpluginWantsAllNetworkStreams, &result) != NPERR_NO_ERROR) - return false; - - return result != 0; -} - -} |