⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webbasenetscapepluginstream.mm

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 MM
📖 第 1 页 / 共 2 页
字号:
            [theHeaders appendData:[v dataUsingEncoding:NSUTF8StringEncoding]];            [theHeaders appendBytes:"\n" length:1];        }                // 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.        NSString *contentEncoding = (NSString *)[[(NSHTTPURLResponse *)r allHeaderFields] objectForKey:@"Content-Encoding"];        if (contentEncoding && ![contentEncoding isEqualToString:@"identity"])            expectedContentLength = -1;                // startStreamResponseURL:... will null-terminate.    }        startStream([r URL], expectedContentLength, WKGetNSURLResponseLastModifiedDate(r), [r MIMEType], theHeaders);    }void WebNetscapePluginStream::startStreamWithResponse(NSURLResponse *response){    didReceiveResponse(0, response);}bool WebNetscapePluginStream::wantsAllStreams() const{    if (!m_pluginFuncs->getvalue)        return false;        void *value = 0;    NPError error;    [m_pluginView.get() willCallPlugInFunction];    {        JSC::JSLock::DropAllLocks dropAllLocks(false);        error = m_pluginFuncs->getvalue(m_plugin, NPPVpluginWantsAllNetworkStreams, &value);    }    [m_pluginView.get() didCallPlugInFunction];    if (error != NPERR_NO_ERROR)        return false;        return value;}void WebNetscapePluginStream::destroyStream(){    if (m_isTerminated)        return;    RefPtr<WebNetscapePluginStream> protect(this);    ASSERT(m_reason != WEB_REASON_NONE);    ASSERT([m_deliveryData.get() length] == 0);        m_deliverDataTimer.stop();    if (m_stream.ndata) {        if (m_reason == NPRES_DONE && (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY)) {            ASSERT(m_fileDescriptor == -1);            ASSERT(m_path);            NSString *carbonPath = CarbonPathFromPOSIXPath(m_path.get());            ASSERT(carbonPath != NULL);            [m_pluginView.get() willCallPlugInFunction];            m_pluginFuncs->asfile(m_plugin, &m_stream, [carbonPath fileSystemRepresentation]);            [m_pluginView.get() didCallPlugInFunction];            LOG(Plugins, "NPP_StreamAsFile responseURL=%@ path=%s", m_responseURL.get(), carbonPath);        }        if (m_path) {            // Delete the file after calling NPP_StreamAsFile(), instead of in -dealloc/-finalize.  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.            unlink([m_path.get() fileSystemRepresentation]);            m_path = 0;            if (m_isTerminated)                return;        }        if (m_fileDescriptor != -1) {            // The file may still be open if we are destroying the stream before it completed loading.            close(m_fileDescriptor);            m_fileDescriptor = -1;        }        if (m_newStreamSuccessful) {            [m_pluginView.get() willCallPlugInFunction];#if !LOG_DISABLED            NPError npErr = #endif            m_pluginFuncs->destroystream(m_plugin, &m_stream, m_reason);            [m_pluginView.get() didCallPlugInFunction];            LOG(Plugins, "NPP_DestroyStream responseURL=%@ error=%d", m_responseURL.get(), npErr);        }        free(m_headers);        m_headers = NULL;        m_stream.headers = NULL;        m_stream.ndata = 0;        if (m_isTerminated)            return;    }    if (m_sendNotification) {        // NPP_URLNotify expects the request URL, not the response URL.        [m_pluginView.get() willCallPlugInFunction];        m_pluginFuncs->urlnotify(m_plugin, [m_requestURL.get() _web_URLCString], m_reason, m_notifyData);        [m_pluginView.get() didCallPlugInFunction];        LOG(Plugins, "NPP_URLNotify requestURL=%@ reason=%d", m_requestURL.get(), m_reason);    }    m_isTerminated = true;    setPlugin(0);}void WebNetscapePluginStream::destroyStreamWithReason(NPReason reason){    m_reason = reason;    if (m_reason != NPRES_DONE) {        // Stop any pending data from being streamed.        [m_deliveryData.get() setLength:0];    } else if ([m_deliveryData.get() length] > 0) {        // There is more data to be streamed, don't destroy the stream now.        return;    }    RefPtr<WebNetscapePluginStream> protect(this);    destroyStream();    ASSERT(!m_stream.ndata);}void WebNetscapePluginStream::cancelLoadWithError(NSError *error){    if (m_frameLoader) {        ASSERT(!m_loader);                DocumentLoader* documentLoader = m_frameLoader->activeDocumentLoader();        ASSERT(documentLoader);                if (documentLoader->isLoadingMainResource())            documentLoader->cancelMainResourceLoad(error);        return;    }        if (!m_loader->isDone())        m_loader->cancel(error);}void WebNetscapePluginStream::destroyStreamWithError(NSError *error){    destroyStreamWithReason(reasonForError(error));}void WebNetscapePluginStream::didFail(WebCore::NetscapePlugInStreamLoader*, const WebCore::ResourceError& error){    destroyStreamWithError(error);}void WebNetscapePluginStream::cancelLoadAndDestroyStreamWithError(NSError *error){    RefPtr<WebNetscapePluginStream> protect(this);    cancelLoadWithError(error);    destroyStreamWithError(error);    setPlugin(0);}    void WebNetscapePluginStream::deliverData(){    if (!m_stream.ndata || [m_deliveryData.get() length] == 0)        return;    RefPtr<WebNetscapePluginStream> protect(this);    int32 totalBytes = [m_deliveryData.get() length];    int32 totalBytesDelivered = 0;    while (totalBytesDelivered < totalBytes) {        [m_pluginView.get() willCallPlugInFunction];        int32 deliveryBytes = m_pluginFuncs->writeready(m_plugin, &m_stream);        [m_pluginView.get() didCallPlugInFunction];        LOG(Plugins, "NPP_WriteReady responseURL=%@ bytes=%d", m_responseURL.get(), deliveryBytes);        if (m_isTerminated)            return;        if (deliveryBytes <= 0) {            // Plug-in can't receive anymore data right now. Send it later.            if (!m_deliverDataTimer.isActive())                m_deliverDataTimer.startOneShot(0);            break;        } else {            deliveryBytes = MIN(deliveryBytes, totalBytes - totalBytesDelivered);            NSData *subdata = [m_deliveryData.get() subdataWithRange:NSMakeRange(totalBytesDelivered, deliveryBytes)];            [m_pluginView.get() willCallPlugInFunction];            deliveryBytes = m_pluginFuncs->write(m_plugin, &m_stream, m_offset, [subdata length], (void *)[subdata bytes]);            [m_pluginView.get() didCallPlugInFunction];            if (deliveryBytes < 0) {                // Netscape documentation says that a negative result from NPP_Write means cancel the load.                cancelLoadAndDestroyStreamWithError(pluginCancelledConnectionError());                return;            }            deliveryBytes = MIN((unsigned)deliveryBytes, [subdata length]);            m_offset += deliveryBytes;            totalBytesDelivered += deliveryBytes;            LOG(Plugins, "NPP_Write responseURL=%@ bytes=%d total-delivered=%d/%d", m_responseURL.get(), deliveryBytes, m_offset, m_stream.end);        }    }    if (totalBytesDelivered > 0) {        if (totalBytesDelivered < totalBytes) {            NSMutableData *newDeliveryData = [[NSMutableData alloc] initWithCapacity:totalBytes - totalBytesDelivered];            [newDeliveryData appendBytes:(char *)[m_deliveryData.get() bytes] + totalBytesDelivered length:totalBytes - totalBytesDelivered];            [m_deliveryData.get() release];            m_deliveryData = newDeliveryData;            [newDeliveryData release];        } else {            [m_deliveryData.get() setLength:0];            if (m_reason != WEB_REASON_NONE)                 destroyStream();        }    }}void WebNetscapePluginStream::deliverDataTimerFired(WebCore::Timer<WebNetscapePluginStream>* timer){    deliverData();}void WebNetscapePluginStream::deliverDataToFile(NSData *data){    if (m_fileDescriptor == -1 && !m_path) {        NSString *temporaryFileMask = [NSTemporaryDirectory() stringByAppendingPathComponent:@"WebKitPlugInStreamXXXXXX"];        char *temporaryFileName = strdup([temporaryFileMask fileSystemRepresentation]);        m_fileDescriptor = mkstemp(temporaryFileName);        if (m_fileDescriptor == -1) {            LOG_ERROR("Can't create a temporary file.");            // This is not a network error, but the only error codes are "network error" and "user break".            destroyStreamWithReason(NPRES_NETWORK_ERR);            free(temporaryFileName);            return;        }        m_path.adoptNS([[NSString stringWithUTF8String:temporaryFileName] retain]);        free(temporaryFileName);    }    int dataLength = [data length];    if (!dataLength)        return;    int byteCount = write(m_fileDescriptor, [data bytes], dataLength);    if (byteCount != dataLength) {        // This happens only rarely, when we are out of disk space or have a disk I/O error.        LOG_ERROR("error writing to temporary file, errno %d", errno);        close(m_fileDescriptor);        m_fileDescriptor = -1;        // This is not a network error, but the only error codes are "network error" and "user break".        destroyStreamWithReason(NPRES_NETWORK_ERR);        m_path = 0;    }}void WebNetscapePluginStream::didFinishLoading(NetscapePlugInStreamLoader*){    if (!m_stream.ndata)        return;        if (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY) {        // Fake the delivery of an empty data to ensure that the file has been created        deliverDataToFile([NSData data]);        if (m_fileDescriptor != -1)            close(m_fileDescriptor);        m_fileDescriptor = -1;    }        destroyStreamWithReason(NPRES_DONE);}void WebNetscapePluginStream::didReceiveData(NetscapePlugInStreamLoader*, const char* bytes, int length){    NSData *data = [[NSData alloc] initWithBytesNoCopy:(void*)bytes length:length freeWhenDone:NO];    ASSERT([data length] > 0);        if (m_transferMode != NP_ASFILEONLY) {        if (!m_deliveryData)            m_deliveryData.adoptNS([[NSMutableData alloc] initWithCapacity:[data length]]);        [m_deliveryData.get() appendData:data];        deliverData();    }    if (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY)        deliverDataToFile(data);        [data release];}static NSString *CarbonPathFromPOSIXPath(NSString *posixPath){    // Doesn't add a trailing colon for directories; this is a problem for paths to a volume,    // so this function would need to be revised if we ever wanted to call it with that.    CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:posixPath];    if (!url)        return nil;    return WebCFAutorelease(CFURLCopyFileSystemPath(url, kCFURLHFSPathStyle));}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -