Changeset 64494 in webkit


Ignore:
Timestamp:
Aug 2, 2010 2:32:11 PM (14 years ago)
Author:
andersca@apple.com
Message:

Add support for loading manual streams
https://bugs.webkit.org/show_bug.cgi?id=43380

Reviewed by Sam Weinig.

  • WebProcess/Plugins/Netscape/NetscapePlugin.cpp:

(WebKit::NetscapePlugin::NetscapePlugin):
Initialize m_loadManually to false.

(WebKit::NetscapePlugin::removePluginStream):
Special case the manual stream.

(WebKit::NetscapePlugin::initialize):
Don't request the stream if we're already loading.

(WebKit::NetscapePlugin::manualStreamDidReceiveResponse):
Create the manual stream and pass the response to it.

(WebKit::NetscapePlugin::manualStreamDidReceiveData):
Pass the data to the manual stream.

(WebKit::NetscapePlugin::manualStreamDidFinishLoading):
Call the manual stream.

(WebKit::NetscapePlugin::manualStreamDidFail):
Ditto.

  • WebProcess/Plugins/Plugin.h:

Add pure virtual member functions for manual stream loading.

  • WebProcess/Plugins/PluginView.cpp:

(WebKit::buildHTTPHeaders):
Put code in a function so both PluginView::Stream::didReceiveResponse and
manualLoadDidReceiveResponse can call it.

(WebKit::PluginView::Stream::didReceiveResponse):
Call buildHTTPHeaders.

(WebKit::PluginView::Stream::didFinishLoading):
Protect the plug-in when calling destroyStream.

(WebKit::PluginView::manualLoadDidReceiveResponse):
Call Plugin::manualStreamDidReceiveResponse.

(WebKit::PluginView::manualLoadDidReceiveData):
Call Plugin::manualStreamDidReceiveData.

(WebKit::PluginView::manualLoadDidFinishLoading):
Call Plugin::manualStreamDidFinishLoading.

(WebKit::PluginView::manualLoadDidFail):
Call Plugin::manualStreamDidFail.

  • WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:

(WebKit::WebFrameLoaderClient::WebFrameLoaderClient):
Initialize m_hasSentResponseToPluginView to false.

(WebKit::WebFrameLoaderClient::setMainDocumentError):
Call PluginView::manualLoadDidFail.

(WebKit::WebFrameLoaderClient::committedLoad):
Call PluginView::manualLoadDidReceiveResponse.

(WebKit::WebFrameLoaderClient::finishedLoading):
Call PluginView::manualLoadDidFinishLoading.

(WebKit::WebFrameLoaderClient::redirectDataToPlugin):
Keep track of the plug-in view.

Location:
trunk/WebKit2
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKit2/ChangeLog

    r64492 r64494  
     12010-08-02  Anders Carlsson  <andersca@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        Add support for loading manual streams
     6        https://bugs.webkit.org/show_bug.cgi?id=43380
     7
     8        * WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
     9        (WebKit::NetscapePlugin::NetscapePlugin):
     10        Initialize m_loadManually to false.
     11
     12        (WebKit::NetscapePlugin::removePluginStream):
     13        Special case the manual stream.
     14
     15        (WebKit::NetscapePlugin::initialize):
     16        Don't request the stream if we're already loading.
     17
     18        (WebKit::NetscapePlugin::manualStreamDidReceiveResponse):
     19        Create the manual stream and pass the response to it.
     20
     21        (WebKit::NetscapePlugin::manualStreamDidReceiveData):
     22        Pass the data to the manual stream.
     23
     24        (WebKit::NetscapePlugin::manualStreamDidFinishLoading):
     25        Call the manual stream.
     26
     27        (WebKit::NetscapePlugin::manualStreamDidFail):
     28        Ditto.
     29
     30        * WebProcess/Plugins/Plugin.h:
     31        Add pure virtual member functions for manual stream loading.
     32
     33        * WebProcess/Plugins/PluginView.cpp:
     34        (WebKit::buildHTTPHeaders):
     35        Put code in a function so both PluginView::Stream::didReceiveResponse and
     36        manualLoadDidReceiveResponse can call it.
     37
     38        (WebKit::PluginView::Stream::didReceiveResponse):
     39        Call buildHTTPHeaders.
     40
     41        (WebKit::PluginView::Stream::didFinishLoading):
     42        Protect the plug-in when calling destroyStream.
     43
     44        (WebKit::PluginView::manualLoadDidReceiveResponse):
     45        Call Plugin::manualStreamDidReceiveResponse.
     46
     47        (WebKit::PluginView::manualLoadDidReceiveData):
     48        Call Plugin::manualStreamDidReceiveData.
     49
     50        (WebKit::PluginView::manualLoadDidFinishLoading):
     51        Call Plugin::manualStreamDidFinishLoading.
     52
     53        (WebKit::PluginView::manualLoadDidFail):
     54        Call Plugin::manualStreamDidFail.
     55
     56        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     57        (WebKit::WebFrameLoaderClient::WebFrameLoaderClient):
     58        Initialize m_hasSentResponseToPluginView to false.
     59
     60        (WebKit::WebFrameLoaderClient::setMainDocumentError):
     61        Call PluginView::manualLoadDidFail.
     62
     63        (WebKit::WebFrameLoaderClient::committedLoad):
     64        Call PluginView::manualLoadDidReceiveResponse.
     65
     66        (WebKit::WebFrameLoaderClient::finishedLoading):
     67        Call PluginView::manualLoadDidFinishLoading.
     68
     69        (WebKit::WebFrameLoaderClient::redirectDataToPlugin):
     70        Keep track of the plug-in view.
     71
    1722010-08-02  Brady Eidson  <beidson@apple.com>
    273
  • trunk/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp

    r64449 r64494  
    4848    , m_isStarted(false)
    4949    , m_inNPPNew(false)
     50    , m_loadManually(false)
    5051#if PLATFORM(MAC)
    5152    , m_drawingModel(static_cast<NPDrawingModel>(-1))
     
    180181void NetscapePlugin::removePluginStream(NetscapePluginStream* pluginStream)
    181182{
     183    if (pluginStream == m_manualStream) {
     184        m_manualStream = 0;
     185        return;
     186    }
     187
    182188    ASSERT(m_streams.get(pluginStream->streamID()) == pluginStream);
    183189    m_streams.remove(pluginStream->streamID());
     
    293299    uint16_t mode = parameters.loadManually ? NP_FULL : NP_EMBED;
    294300   
     301    m_loadManually = parameters.loadManually;
    295302    m_inNPPNew = true;
    296303
     
    332339
    333340    // Load the src URL if needed.
    334     if (!parameters.url.isEmpty() && shouldLoadSrcURL())
     341    if (!parameters.loadManually && !parameters.url.isEmpty() && shouldLoadSrcURL())
    335342        loadURL("GET", parameters.url.string(), String(), HTTPHeaderMap(), Vector<char>(), false, 0);
    336343   
     
    432439}
    433440
     441void NetscapePlugin::manualStreamDidReceiveResponse(const KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime,
     442                                                    const String& mimeType, const String& headers)
     443{
     444    ASSERT(m_loadManually);
     445    ASSERT(!m_manualStream);
     446   
     447    m_manualStream = NetscapePluginStream::create(this, 0, false, 0);
     448    m_manualStream->didReceiveResponse(responseURL, streamLength, lastModifiedTime, mimeType, headers);
     449}
     450
     451void NetscapePlugin::manualStreamDidReceiveData(const char* bytes, int length)
     452{
     453    ASSERT(m_loadManually);
     454    ASSERT(m_manualStream);
     455
     456    m_manualStream->didReceiveData(bytes, length);
     457}
     458
     459void NetscapePlugin::manualStreamDidFinishLoading()
     460{
     461    ASSERT(m_loadManually);
     462    ASSERT(m_manualStream);
     463
     464    m_manualStream->didFinishLoading();
     465}
     466
     467void NetscapePlugin::manualStreamDidFail(bool wasCancelled)
     468{
     469    ASSERT(m_loadManually);
     470    ASSERT(m_manualStream);
     471
     472    m_manualStream->didFail(wasCancelled);
     473}
     474
    434475bool NetscapePlugin::handleMouseEvent(const WebMouseEvent& mouseEvent)
    435476{
  • trunk/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h

    r64449 r64494  
    115115    virtual void streamDidFinishLoading(uint64_t streamID);
    116116    virtual void streamDidFail(uint64_t streamID, bool wasCancelled);
     117    virtual void manualStreamDidReceiveResponse(const WebCore::KURL& responseURL, uint32_t streamLength,
     118                                                uint32_t lastModifiedTime, const WebCore::String& mimeType, const WebCore::String& headers);
     119    virtual void manualStreamDidReceiveData(const char* bytes, int length);
     120    virtual void manualStreamDidFinishLoading();
     121    virtual void manualStreamDidFail(bool wasCancelled);
     122   
    117123    virtual bool handleMouseEvent(const WebMouseEvent&);
    118124    virtual bool handleWheelEvent(const WebWheelEvent&);
     
    144150    bool m_isStarted;
    145151    bool m_inNPPNew;
     152    bool m_loadManually;
     153    RefPtr<NetscapePluginStream> m_manualStream;
    146154
    147155#if PLATFORM(MAC)
  • trunk/WebKit2/WebProcess/Plugins/Plugin.h

    r64154 r64494  
    9292    virtual void streamDidFail(uint64_t streamID, bool wasCancelled) = 0;
    9393
     94    // Tells the plug-in that the manual stream has received its HTTP response.
     95    virtual void manualStreamDidReceiveResponse(const WebCore::KURL& responseURL, uint32_t streamLength,
     96                                                uint32_t lastModifiedTime, const WebCore::String& mimeType, const WebCore::String& headers) = 0;
     97
     98    // Tells the plug-in that the manual stream did receive data.
     99    virtual void manualStreamDidReceiveData(const char* bytes, int length) = 0;
     100
     101    // Tells the plug-in that a stream has finished loading.
     102    virtual void manualStreamDidFinishLoading() = 0;
     103   
     104    // Tells the plug-in that a stream has failed to load, either because of network errors or because the load was cancelled.
     105    virtual void manualStreamDidFail(bool wasCancelled) = 0;
     106   
    94107    // Tells the plug-in to handle the passed in mouse event. The plug-in should return true if it processed the event.
    95108    virtual bool handleMouseEvent(const WebMouseEvent&) = 0;
  • trunk/WebKit2/WebProcess/Plugins/PluginView.cpp

    r64487 r64494  
    141141}
    142142
     143static String buildHTTPHeaders(const ResourceResponse& response, long long& expectedContentLength)
     144{
     145    if (!response.isHTTP())
     146        return String();
     147
     148    Vector<UChar> stringBuilder;
     149    String separator(": ");
     150   
     151    String statusLine = String::format("HTTP %d ", response.httpStatusCode());
     152    stringBuilder.append(statusLine.characters(), statusLine.length());
     153    stringBuilder.append(response.httpStatusText().characters(), response.httpStatusText().length());
     154    stringBuilder.append('\n');
     155   
     156    HTTPHeaderMap::const_iterator end = response.httpHeaderFields().end();
     157    for (HTTPHeaderMap::const_iterator it = response.httpHeaderFields().begin(); it != end; ++it) {
     158        stringBuilder.append(it->first.characters(), it->first.length());
     159        stringBuilder.append(separator.characters(), separator.length());
     160        stringBuilder.append(it->second.characters(), it->second.length());
     161        stringBuilder.append('\n');
     162    }
     163   
     164    String headers = String::adopt(stringBuilder);
     165   
     166    // If the content is encoded (most likely compressed), then don't send its length to the plugin,
     167    // which is only interested in the decoded length, not yet known at the moment.
     168    // <rdar://problem/4470599> tracks a request for -[NSURLResponse expectedContentLength] to incorporate this logic.
     169    String contentEncoding = response.httpHeaderField("Content-Encoding");
     170    if (!contentEncoding.isNull() && contentEncoding != "identity")
     171        expectedContentLength = -1;
     172
     173    return headers;
     174}
     175
    143176void PluginView::Stream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse& response)
    144177{
     
    148181    long long expectedContentLength = response.expectedContentLength();
    149182   
    150     String headers;
    151     if (response.isHTTP()) {
    152         Vector<UChar> stringBuilder;
    153         String separator(": ");
    154 
    155         String statusLine = String::format("HTTP %d ", response.httpStatusCode());
    156         stringBuilder.append(statusLine.characters(), statusLine.length());
    157         stringBuilder.append(response.httpStatusText().characters(), response.httpStatusText().length());
    158         stringBuilder.append('\n');
    159 
    160         HTTPHeaderMap::const_iterator end = response.httpHeaderFields().end();
    161         for (HTTPHeaderMap::const_iterator it = response.httpHeaderFields().begin(); it != end; ++it) {
    162             stringBuilder.append(it->first.characters(), it->first.length());
    163             stringBuilder.append(separator.characters(), separator.length());
    164             stringBuilder.append(it->second.characters(), it->second.length());
    165             stringBuilder.append('\n');
    166         }
    167 
    168         headers = String::adopt(stringBuilder);
    169 
    170         // If the content is encoded (most likely compressed), then don't send its length to the plugin,
    171         // which is only interested in the decoded length, not yet known at the moment.
    172         // <rdar://problem/4470599> tracks a request for -[NSURLResponse expectedContentLength] to incorporate this logic.
    173         String contentEncoding = response.httpHeaderField("Content-Encoding");
    174         if (!contentEncoding.isNull() && contentEncoding != "identity")
    175             expectedContentLength = -1;
    176     }
     183    String headers = buildHTTPHeaders(response, expectedContentLength);
    177184
    178185    uint32_t streamLength = 0;
     
    204211{
    205212    // Calling streamDidFinishLoading could cause us to be deleted, so we hold on to a reference here.
    206     RefPtr<Stream> protect(this);
    207 
     213    RefPtr<Stream> protectStream(this);
     214
     215    // Protect the plug-in while we're calling into it.
     216    NPRuntimeObjectMap::PluginProtector pluginProtector(&m_pluginView->m_npRuntimeObjectMap);
    208217    m_pluginView->m_plugin->streamDidFinishLoading(m_streamID);
     218
    209219    m_pluginView->removeStream(this);
    210220    m_pluginView = 0;
     
    254264}
    255265
     266void PluginView::manualLoadDidReceiveResponse(const ResourceResponse& response)
     267{
     268    // Compute the stream related data from the resource response.
     269    const KURL& responseURL = response.url();
     270    const String& mimeType = response.mimeType();
     271    long long expectedContentLength = response.expectedContentLength();
     272   
     273    String headers = buildHTTPHeaders(response, expectedContentLength);
     274   
     275    uint32_t streamLength = 0;
     276    if (expectedContentLength > 0)
     277        streamLength = expectedContentLength;
     278
     279    m_plugin->manualStreamDidReceiveResponse(responseURL, streamLength, response.lastModifiedDate(), mimeType, headers);
     280}
     281
     282void PluginView::manualLoadDidReceiveData(const char* bytes, int length)
     283{
     284    m_plugin->manualStreamDidReceiveData(bytes, length);
     285}
     286
     287void PluginView::manualLoadDidFinishLoading()
     288{
     289    m_plugin->manualStreamDidFinishLoading();
     290}
     291
     292void PluginView::manualLoadDidFail(const ResourceError& error)
     293{
     294    m_plugin->manualStreamDidFail(error.isCancellation());
     295}
     296   
    256297void PluginView::initializePlugin()
    257298{
  • trunk/WebKit2/WebProcess/Plugins/PluginView.h

    r64487 r64494  
    5757    bool isBeingDestroyed() const { return m_isBeingDestroyed; }
    5858
     59    void manualLoadDidReceiveResponse(const WebCore::ResourceResponse&);
     60    void manualLoadDidReceiveData(const char* bytes, int length);
     61    void manualLoadDidFinishLoading();
     62    void manualLoadDidFail(const WebCore::ResourceError&);
     63   
    5964private:
    6065    PluginView(WebCore::HTMLPlugInElement*, PassRefPtr<Plugin>, const Plugin::Parameters& parameters);
  • trunk/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r64247 r64494  
    6464namespace WebKit {
    6565
     66WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* frame)
     67    : m_frame(frame)
     68    , m_hasSentResponseToPluginView(false)
     69{
     70}
     71
     72WebFrameLoaderClient::~WebFrameLoaderClient()
     73{
     74}
     75   
    6676void WebFrameLoaderClient::frameLoaderDestroyed()
    6777{
     
    452462}
    453463
    454 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError&)
    455 {
    456     notImplemented();
     464void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
     465{
     466    if (!m_pluginView)
     467        return;
     468   
     469    m_pluginView->manualLoadDidFail(error);
     470    m_pluginView = 0;
     471    m_hasSentResponseToPluginView = false;
    457472}
    458473
     
    511526    const String& textEncoding = loader->response().textEncodingName();
    512527   
    513     receivedData(data, length, textEncoding);
     528    if (!m_pluginView)
     529        receivedData(data, length, textEncoding);
     530
     531    // Calling receivedData did not create the plug-in view.
     532    if (!m_pluginView)
     533        return;
     534
     535    if (!m_hasSentResponseToPluginView) {
     536        m_pluginView->manualLoadDidReceiveResponse(m_frame->coreFrame()->loader()->documentLoader()->response());
     537        // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
     538        // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
     539        // to null
     540        if (!m_pluginView)
     541            return;
     542        m_hasSentResponseToPluginView = true;
     543    }
     544    m_pluginView->manualLoadDidReceiveData(data, length);
    514545}
    515546
     
    532563void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
    533564{
    534     committedLoad(loader, 0, 0);
     565    if (!m_pluginView) {
     566        committedLoad(loader, 0, 0);
     567        return;
     568    }
     569
     570    m_pluginView->manualLoadDidFinishLoading();
     571    m_pluginView = 0;
     572    m_hasSentResponseToPluginView = false;
    535573}
    536574
     
    821859void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
    822860{
    823     notImplemented();
     861    ASSERT(!m_pluginView);
     862    ASSERT(pluginWidget);
     863   
     864    m_pluginView = static_cast<PluginView*>(pluginWidget);
    824865}
    825866
  • trunk/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h

    r58686 r64494  
    3131namespace WebKit {
    3232
     33class PluginView;
    3334class WebFrame;
    34 
     35   
    3536class WebFrameLoaderClient : public WebCore::FrameLoaderClient {
    3637public:
    37     WebFrameLoaderClient(WebFrame* frame)
    38         : m_frame(frame)
    39     {
    40     }
     38    WebFrameLoaderClient(WebFrame*);
     39    ~WebFrameLoaderClient();
    4140
    4241    WebFrame* webFrame() const { return m_frame; }
     
    206205   
    207206    void receivedData(const char* data, int length, const WebCore::String& textEncoding);
    208 
     207   
    209208    WebFrame* m_frame;
     209   
     210    RefPtr<PluginView> m_pluginView;
     211    bool m_hasSentResponseToPluginView;
    210212};
    211213
Note: See TracChangeset for help on using the changeset viewer.