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

📄 webbasenetscapepluginstream.mm

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 MM
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2005, 2006, 2007 Apple Inc. 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.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of *     its contributors may be used to endorse or promote products derived *     from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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. */#if ENABLE(NETSCAPE_PLUGIN_API)#import "WebBaseNetscapePluginStream.h"#import "WebNetscapePluginView.h"#import "WebFrameInternal.h"#import "WebKitErrorsPrivate.h"#import "WebKitLogging.h"#import "WebNSObjectExtras.h"#import "WebNSURLExtras.h"#import "WebNSURLRequestExtras.h"#import "WebNetscapePluginPackage.h"#import <Foundation/NSURLResponse.h>#import <runtime/JSLock.h>#import <WebCore/DocumentLoader.h>#import <WebCore/Frame.h>#import <WebCore/FrameLoader.h>#import <WebCore/WebCoreObjCExtras.h>#import <WebKitSystemInterface.h>#import <wtf/HashMap.h>#import <wtf/StdLibExtras.h>using namespace WebCore;#define WEB_REASON_NONE -1static NSString *CarbonPathFromPOSIXPath(NSString *posixPath);typedef HashMap<NPStream*, NPP> StreamMap;static StreamMap& streams(){    DEFINE_STATIC_LOCAL(StreamMap, staticStreams, ());    return staticStreams;}NPP WebNetscapePluginStream::ownerForStream(NPStream *stream){    return streams().get(stream);}NPReason WebNetscapePluginStream::reasonForError(NSError *error){    if (!error)        return NPRES_DONE;    if ([[error domain] isEqualToString:NSURLErrorDomain] && [error code] == NSURLErrorCancelled)        return NPRES_USER_BREAK;    return NPRES_NETWORK_ERR;}NSError *WebNetscapePluginStream::pluginCancelledConnectionError() const{    return [[[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInCancelledConnection                                           contentURL:m_responseURL ? m_responseURL.get() : m_requestURL.get()                                        pluginPageURL:nil                                           pluginName:[[m_pluginView.get() pluginPackage] name]                                             MIMEType:m_mimeType.get()] autorelease];}NSError *WebNetscapePluginStream::errorForReason(NPReason reason) const{    if (reason == NPRES_DONE)        return nil;    if (reason == NPRES_USER_BREAK)        return [NSError _webKitErrorWithDomain:NSURLErrorDomain                                          code:NSURLErrorCancelled                                            URL:m_responseURL ? m_responseURL.get() : m_requestURL.get()];    return pluginCancelledConnectionError();}WebNetscapePluginStream::WebNetscapePluginStream(FrameLoader* frameLoader)    : m_plugin(0)    , m_transferMode(0)    , m_offset(0)    , m_fileDescriptor(-1)    , m_sendNotification(false)    , m_notifyData(0)    , m_headers(0)    , m_reason(NPRES_BASE)    , m_isTerminated(false)    , m_newStreamSuccessful(false)    , m_frameLoader(frameLoader)    , m_pluginFuncs(0)    , m_deliverDataTimer(this, &WebNetscapePluginStream::deliverDataTimerFired){    memset(&m_stream, 0, sizeof(NPStream));}WebNetscapePluginStream::WebNetscapePluginStream(NSURLRequest *request, NPP plugin, bool sendNotification, void* notifyData)    : m_requestURL([request URL])    , m_plugin(0)    , m_transferMode(0)    , m_offset(0)    , m_fileDescriptor(-1)    , m_sendNotification(sendNotification)    , m_notifyData(notifyData)    , m_headers(0)    , m_reason(NPRES_BASE)    , m_isTerminated(false)    , m_newStreamSuccessful(false)    , m_frameLoader(0)    , m_request(AdoptNS, [request mutableCopy])    , m_pluginFuncs(0)    , m_deliverDataTimer(this, &WebNetscapePluginStream::deliverDataTimerFired){    memset(&m_stream, 0, sizeof(NPStream));    WebNetscapePluginView *view = (WebNetscapePluginView *)plugin->ndata;        // This check has already been done by the plug-in view.    ASSERT(FrameLoader::canLoad([request URL], String(), core([view webFrame])->document()));        ASSERT([request URL]);    ASSERT(plugin);        setPlugin(plugin);        streams().add(&m_stream, plugin);            if (core([view webFrame])->loader()->shouldHideReferrer([request URL], core([view webFrame])->loader()->outgoingReferrer()))        [m_request.get() _web_setHTTPReferrer:nil];}WebNetscapePluginStream::~WebNetscapePluginStream(){    ASSERT(!m_plugin);    ASSERT(m_isTerminated);    ASSERT(!m_stream.ndata);        // The stream file should have been deleted, and the path freed, in -_destroyStream    ASSERT(!m_path);    ASSERT(m_fileDescriptor == -1);        free((void *)m_stream.url);    free(m_headers);        streams().remove(&m_stream);}void WebNetscapePluginStream::setPlugin(NPP plugin){    if (plugin) {        m_plugin = plugin;        m_pluginView = static_cast<WebNetscapePluginView *>(m_plugin->ndata);        WebNetscapePluginPackage *pluginPackage = [m_pluginView.get() pluginPackage];                m_pluginFuncs = [pluginPackage pluginFuncs];    } else {        WebNetscapePluginView *view = m_pluginView.get();        m_plugin = 0;        m_pluginFuncs = 0;                [view disconnectStream:this];        m_pluginView = 0;    }        }void WebNetscapePluginStream::startStream(NSURL *url, long long expectedContentLength, NSDate *lastModifiedDate, NSString *mimeType, NSData *headers){    ASSERT(!m_isTerminated);        m_responseURL = url;    m_mimeType = mimeType;        free((void *)m_stream.url);    m_stream.url = strdup([m_responseURL.get() _web_URLCString]);    m_stream.ndata = this;    m_stream.end = expectedContentLength > 0 ? (uint32)expectedContentLength : 0;    m_stream.lastmodified = (uint32)[lastModifiedDate timeIntervalSince1970];    m_stream.notifyData = m_notifyData;    if (headers) {        unsigned len = [headers length];        m_headers = (char*) malloc(len + 1);        [headers getBytes:m_headers];        m_headers[len] = 0;        m_stream.headers = m_headers;    }        m_transferMode = NP_NORMAL;    m_offset = 0;    m_reason = WEB_REASON_NONE;    // FIXME: If WebNetscapePluginStream called our initializer we wouldn't have to do this here.    m_fileDescriptor = -1;    // FIXME: Need a way to check if stream is seekable    [m_pluginView.get() willCallPlugInFunction];    NPError npErr = m_pluginFuncs->newstream(m_plugin, (char *)[m_mimeType.get() UTF8String], &m_stream, NO, &m_transferMode);    [m_pluginView.get() didCallPlugInFunction];    LOG(Plugins, "NPP_NewStream URL=%@ MIME=%@ error=%d", m_responseURL.get(), m_mimeType.get(), npErr);    if (npErr != NPERR_NO_ERROR) {        LOG_ERROR("NPP_NewStream failed with error: %d responseURL: %@", npErr, m_responseURL.get());        // Calling cancelLoadWithError: cancels the load, but doesn't call NPP_DestroyStream.        cancelLoadWithError(pluginCancelledConnectionError());        return;    }    m_newStreamSuccessful = true;    switch (m_transferMode) {        case NP_NORMAL:            LOG(Plugins, "Stream type: NP_NORMAL");            break;        case NP_ASFILEONLY:            LOG(Plugins, "Stream type: NP_ASFILEONLY");            break;        case NP_ASFILE:            LOG(Plugins, "Stream type: NP_ASFILE");            break;        case NP_SEEK:            LOG_ERROR("Stream type: NP_SEEK not yet supported");            cancelLoadAndDestroyStreamWithError(pluginCancelledConnectionError());            break;        default:            LOG_ERROR("unknown stream type");    }}void WebNetscapePluginStream::start(){    ASSERT(m_request);    ASSERT(!m_frameLoader);    ASSERT(!m_loader);        m_loader = NetscapePlugInStreamLoader::create(core([m_pluginView.get() webFrame]), this);    m_loader->setShouldBufferData(false);        m_loader->documentLoader()->addPlugInStreamLoader(m_loader.get());    m_loader->load(m_request.get());}void WebNetscapePluginStream::stop(){    ASSERT(!m_frameLoader);        if (!m_loader->isDone())        cancelLoadAndDestroyStreamWithError(m_loader->cancelledError());}void WebNetscapePluginStream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse& response){    NSURLResponse *r = response.nsURLResponse();        NSMutableData *theHeaders = nil;    long long expectedContentLength = [r expectedContentLength];        if ([r isKindOfClass:[NSHTTPURLResponse class]]) {        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)r;        theHeaders = [NSMutableData dataWithCapacity:1024];                // FIXME: it would be nice to be able to get the raw HTTP header block.        // This includes the HTTP version, the real status text,        // all headers in their original order and including duplicates,        // and all original bytes verbatim, rather than sent through Unicode translation.        // Unfortunately NSHTTPURLResponse doesn't provide access at that low a level.                [theHeaders appendBytes:"HTTP " length:5];        char statusStr[10];        long statusCode = [httpResponse statusCode];        snprintf(statusStr, sizeof(statusStr), "%ld", statusCode);        [theHeaders appendBytes:statusStr length:strlen(statusStr)];        [theHeaders appendBytes:" OK\n" length:4];                // HACK: pass the headers through as UTF-8.        // This is not the intended behavior; we're supposed to pass original bytes verbatim.        // But we don't have the original bytes, we have NSStrings built by the URL loading system.        // It hopefully shouldn't matter, since RFC2616/RFC822 require ASCII-only headers,        // but surely someone out there is using non-ASCII characters, and hopefully UTF-8 is adequate here.        // It seems better than NSASCIIStringEncoding, which will lose information if non-ASCII is used.                NSDictionary *headerDict = [httpResponse allHeaderFields];        NSArray *keys = [[headerDict allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];        NSEnumerator *i = [keys objectEnumerator];        NSString *k;        while ((k = [i nextObject]) != nil) {            NSString *v = [headerDict objectForKey:k];            [theHeaders appendData:[k dataUsingEncoding:NSUTF8StringEncoding]];            [theHeaders appendBytes:": " length:2];

⌨️ 快捷键说明

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