<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[187886] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/187886">187886</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-08-04 13:48:47 -0700 (Tue, 04 Aug 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Implement NPAPI redirect handling
https://bugs.webkit.org/show_bug.cgi?id=138675
rdar://problem/15779101

Patch by Jeffrey Pfau, updated and tweaked by me.

Patch by Alexey Proskuryakov &lt;ap@apple.com&gt; on 2015-08-04
Reviewed by Anders Carlsson.

Source/WebCore:

Test: http/tests/plugins/get-url-redirect-notify.html

* loader/NetscapePlugInStreamLoader.cpp:
(WebCore::NetscapePlugInStreamLoader::init):
(WebCore::NetscapePlugInStreamLoader::willSendRequest):
(WebCore::NetscapePlugInStreamLoader::didReceiveResponse):
* loader/NetscapePlugInStreamLoader.h:
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::init):
(WebCore::ResourceLoader::isSubresourceLoader):
(WebCore::ResourceLoader::willSendRequestInternal):
(WebCore::ResourceLoader::willSendRequest):
(WebCore::ResourceLoader::didSendData):
* loader/ResourceLoader.h:
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::isSubresourceLoader):
(WebCore::SubresourceLoader::willSendRequestInternal):
(WebCore::SubresourceLoader::willSendRequest): Deleted.
* loader/SubresourceLoader.h:
* plugins/npapi.h:
* plugins/npfunctions.h:

Source/WebKit/mac:

* Plugins/Hosted/HostedNetscapePluginStream.h:
(WebKit::HostedNetscapePluginStream::streamID):
* Plugins/Hosted/HostedNetscapePluginStream.mm:
(WebKit::HostedNetscapePluginStream::didFinishLoading):
(WebKit::HostedNetscapePluginStream::willSendRequest):
(WebKit::HostedNetscapePluginStream::didReceiveResponse):
* Plugins/WebNetscapePluginStream.h:
* Plugins/WebNetscapePluginStream.mm:
(WebNetscapePluginStream::stop):
(WebNetscapePluginStream::willSendRequest):
(WebNetscapePluginStream::didReceiveResponse):

Source/WebKit/win:

* Plugins/PluginStream.cpp:
(WebCore::PluginStream::sendJavaScriptStream):
(WebCore::PluginStream::willSendRequest):
(WebCore::PluginStream::didReceiveResponse):
* Plugins/PluginStream.h:

Source/WebKit2:

* PluginProcess/PluginControllerProxy.cpp:
(WebKit::PluginControllerProxy::loadURL):
(WebKit::PluginControllerProxy::continueStreamLoad):
(WebKit::PluginControllerProxy::cancelStreamLoad):
(WebKit::PluginControllerProxy::didEvaluateJavaScript):
(WebKit::PluginControllerProxy::streamWillSendRequest):
(WebKit::PluginControllerProxy::streamDidReceiveResponse):
* PluginProcess/PluginControllerProxy.h:
* PluginProcess/PluginControllerProxy.messages.in:
* WebProcess/Network/WebResourceLoader.cpp:
(WebKit::WebResourceLoader::willSendRequest):
* WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp:
(WebKit::NPN_ConvertPoint):
(WebKit::NPN_URLRedirectResponse):
(WebKit::initializeBrowserFuncs):
(WebKit::netscapeBrowserFuncs):
* WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
(WebKit::NetscapePlugin::getAuthenticationInfo):
(WebKit::NetscapePlugin::registerRedirect):
(WebKit::NetscapePlugin::urlRedirectResponse):
(WebKit::NetscapePlugin::setIsPlayingAudio):
(WebKit::NetscapePlugin::NPP_URLNotify):
(WebKit::NetscapePlugin::NPP_URLRedirectNotify):
(WebKit::NetscapePlugin::NPP_GetValue):
(WebKit::NetscapePlugin::didEvaluateJavaScript):
(WebKit::NetscapePlugin::streamWillSendRequest):
(WebKit::NetscapePlugin::streamDidReceiveResponse):
* WebProcess/Plugins/Netscape/NetscapePlugin.h:
* WebProcess/Plugins/Netscape/NetscapePluginStream.cpp:
(WebKit::NetscapePluginStream::~NetscapePluginStream):
(WebKit::NetscapePluginStream::willSendRequest):
(WebKit::NetscapePluginStream::didReceiveResponse):
(WebKit::NetscapePluginStream::stop):
(WebKit::NetscapePluginStream::setURL):
(WebKit::NetscapePluginStream::cancel):
* WebProcess/Plugins/Netscape/NetscapePluginStream.h:
(WebKit::NetscapePluginStream::streamID):
(WebKit::NetscapePluginStream::npStream):
* WebProcess/Plugins/PDF/PDFPlugin.h:
* WebProcess/Plugins/Plugin.h:
* WebProcess/Plugins/PluginController.h:
* WebProcess/Plugins/PluginProxy.cpp:
(WebKit::PluginProxy::didEvaluateJavaScript):
(WebKit::PluginProxy::streamWillSendRequest):
(WebKit::PluginProxy::streamDidReceiveResponse):
(WebKit::PluginProxy::setPluginIsPlayingAudio):
(WebKit::PluginProxy::continueStreamLoad):
(WebKit::PluginProxy::cancelStreamLoad):
* WebProcess/Plugins/PluginProxy.h:
* WebProcess/Plugins/PluginProxy.messages.in:
* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::Stream::streamID):
(WebKit::PluginView::Stream::Stream):
(WebKit::PluginView::Stream::cancel):
(WebKit::PluginView::Stream::continueLoad):
(WebKit::buildHTTPHeaders):
(WebKit::lastModifiedDateMS):
(WebKit::PluginView::Stream::willSendRequest):
(WebKit::PluginView::Stream::didReceiveResponse):
(WebKit::PluginView::cancelStreamLoad):
(WebKit::PluginView::continueStreamLoad):
(WebKit::PluginView::cancelManualStreamLoad):
* WebProcess/Plugins/PluginView.h:

Tools:

* DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj:
* DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj.filters:
* DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
* DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt:
* DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp:
(PluginTest::NPP_URLNotify):
(PluginTest::NPP_URLRedirectNotify):
(PluginTest::NPP_GetValue):
(PluginTest::NPN_GetURLNotify):
(PluginTest::NPN_PostURLNotify):
(PluginTest::NPN_GetValue):
(PluginTest::NPN_ReleaseVariantValue):
(PluginTest::NPN_URLRedirectResponse):
(PluginTest::NPN_ConvertPoint):
* DumpRenderTree/TestNetscapePlugIn/PluginTest.h:
* DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp: Added.
(URLRedirect::URLRedirect):
(URLRedirect::ScriptableObject::hasMethod):
(URLRedirect::ScriptableObject::get):
(URLRedirect::ScriptableObject::serviceAsync):
(URLRedirect::ScriptableObject::invoke):
(URLRedirect::NPP_GetValue):
(URLRedirect::NPP_URLNotify):
(URLRedirect::NPP_URLRedirectNotify):
* DumpRenderTree/TestNetscapePlugIn/main.cpp:
(NP_GetEntryPoints):
(NPP_URLNotify):
(NPP_URLRedirectNotify):
(NPP_GetValue):

LayoutTests:

* http/tests/plugins/get-url-redirect-notify-expected.txt: Added.
* http/tests/plugins/get-url-redirect-notify.html: Added.
* platform/wk2/http/tests/plugins: Added.
* platform/wk2/http/tests/plugins/get-url-redirect-notify-expected.txt: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreloaderNetscapePlugInStreamLoadercpp">trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderNetscapePlugInStreamLoaderh">trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.h</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadercpp">trunk/Source/WebCore/loader/ResourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoaderh">trunk/Source/WebCore/loader/ResourceLoader.h</a></li>
<li><a href="#trunkSourceWebCoreloaderSubresourceLoadercpp">trunk/Source/WebCore/loader/SubresourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderSubresourceLoaderh">trunk/Source/WebCore/loader/SubresourceLoader.h</a></li>
<li><a href="#trunkSourceWebCorepluginsnpapih">trunk/Source/WebCore/plugins/npapi.h</a></li>
<li><a href="#trunkSourceWebCorepluginsnpfunctionsh">trunk/Source/WebCore/plugins/npfunctions.h</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacPluginsHostedHostedNetscapePluginStreamh">trunk/Source/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.h</a></li>
<li><a href="#trunkSourceWebKitmacPluginsHostedHostedNetscapePluginStreammm">trunk/Source/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm</a></li>
<li><a href="#trunkSourceWebKitmacPluginsWebNetscapePluginStreamh">trunk/Source/WebKit/mac/Plugins/WebNetscapePluginStream.h</a></li>
<li><a href="#trunkSourceWebKitmacPluginsWebNetscapePluginStreammm">trunk/Source/WebKit/mac/Plugins/WebNetscapePluginStream.mm</a></li>
<li><a href="#trunkSourceWebKitwinChangeLog">trunk/Source/WebKit/win/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitwinPluginsPluginStreamcpp">trunk/Source/WebKit/win/Plugins/PluginStream.cpp</a></li>
<li><a href="#trunkSourceWebKitwinPluginsPluginStreamh">trunk/Source/WebKit/win/Plugins/PluginStream.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2PluginProcessPluginControllerProxycpp">trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2PluginProcessPluginControllerProxyh">trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.h</a></li>
<li><a href="#trunkSourceWebKit2PluginProcessPluginControllerProxymessagesin">trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessNetworkWebResourceLoadercpp">trunk/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsNetscapeNetscapeBrowserFuncscpp">trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsNetscapeNetscapePlugincpp">trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsNetscapeNetscapePluginh">trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsNetscapeNetscapePluginStreamcpp">trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsNetscapeNetscapePluginStreamh">trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsPDFPDFPluginh">trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsPluginh">trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsPluginControllerh">trunk/Source/WebKit2/WebProcess/Plugins/PluginController.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsPluginProxycpp">trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsPluginProxyh">trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsPluginProxymessagesin">trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsPluginViewcpp">trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessPluginsPluginViewh">trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreeDumpRenderTreevcxprojTestNetscapePluginTestNetscapePluginvcxproj">trunk/Tools/DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj</a></li>
<li><a href="#trunkToolsDumpRenderTreeDumpRenderTreevcxprojTestNetscapePluginTestNetscapePluginvcxprojfilters">trunk/Tools/DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj.filters</a></li>
<li><a href="#trunkToolsDumpRenderTreeDumpRenderTreexcodeprojprojectpbxproj">trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsDumpRenderTreeTestNetscapePlugInCMakeListstxt">trunk/Tools/DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt</a></li>
<li><a href="#trunkToolsDumpRenderTreeTestNetscapePlugInPluginTestcpp">trunk/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp</a></li>
<li><a href="#trunkToolsDumpRenderTreeTestNetscapePlugInPluginTesth">trunk/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h</a></li>
<li><a href="#trunkToolsDumpRenderTreeTestNetscapePlugInmaincpp">trunk/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestspluginsgeturlredirectnotifyexpectedtxt">trunk/LayoutTests/http/tests/plugins/get-url-redirect-notify-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestspluginsgeturlredirectnotifyhtml">trunk/LayoutTests/http/tests/plugins/get-url-redirect-notify.html</a></li>
<li>trunk/LayoutTests/platform/wk2/http/tests/plugins/</li>
<li><a href="#trunkLayoutTestsplatformwk2httptestspluginsgeturlredirectnotifyexpectedtxt">trunk/LayoutTests/platform/wk2/http/tests/plugins/get-url-redirect-notify-expected.txt</a></li>
<li><a href="#trunkToolsDumpRenderTreeTestNetscapePlugInTestsURLRedirectcpp">trunk/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/LayoutTests/ChangeLog        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2015-08-04  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        Implement NPAPI redirect handling
+        https://bugs.webkit.org/show_bug.cgi?id=138675
+        rdar://problem/15779101
+
+        Patch by Jeffrey Pfau, updated and tweaked by me.
+
+        Reviewed by Anders Carlsson.
+
+        * http/tests/plugins/get-url-redirect-notify-expected.txt: Added.
+        * http/tests/plugins/get-url-redirect-notify.html: Added.
+        * platform/wk2/http/tests/plugins: Added.
+        * platform/wk2/http/tests/plugins/get-url-redirect-notify-expected.txt: Added.
+
</ins><span class="cx"> 2015-08-04  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Layout Test http/tests/security/contentSecurityPolicy/source-list-parsing-10.html is failing
</span></span></pre></div>
<a id="trunkLayoutTestshttptestspluginsgeturlredirectnotifyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/plugins/get-url-redirect-notify-expected.txt (0 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/plugins/get-url-redirect-notify-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/plugins/get-url-redirect-notify-expected.txt        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+
+Sync allow, reason shouldn't be NPRES_USER_BREAK...true
+Sync allow, URL should be the final URL...false
+Sync deny, reason should be NPRES_USER_BREAK...false
+Sync deny, URL should be the previous URL...true
+Async allow, reason shouldn't be NPRES_USER_BREAK...true
+Async allow, URL should be the final URL...false
+Async deny, reason should be NPRES_USER_BREAK...false
+Async deny, URL should be the previous URL...true
+Async multiple allow, reason shouldn't be NPRES_USER_BREAK...true
+Async multiple allow, URL should be the final URL...false
+Async multiple deny, reason should be NPRES_USER_BREAK...false
+Async multiple deny, URL should be the previous URL...false
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestspluginsgeturlredirectnotifyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/plugins/get-url-redirect-notify.html (0 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/plugins/get-url-redirect-notify.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/plugins/get-url-redirect-notify.html        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -0,0 +1,89 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+&lt;embed name=&quot;plg&quot; type=&quot;application/x-webkit-test-netscape&quot; test=&quot;url-redirect&quot;&gt;&lt;/embed&gt;
+&lt;div id=&quot;log&quot;&gt;
+    &lt;div id=&quot;syncallowreason&quot;&gt;Sync allow, reason shouldn't be NPRES_USER_BREAK...&lt;/div&gt;
+    &lt;div id=&quot;syncallowurl&quot;&gt;Sync allow, URL should be the final URL...&lt;/div&gt;
+    &lt;div id=&quot;syncdenyreason&quot;&gt;Sync deny, reason should be NPRES_USER_BREAK...&lt;/div&gt;
+    &lt;div id=&quot;syncdenyurl&quot;&gt;Sync deny, URL should be the previous URL...&lt;/div&gt;
+    &lt;div id=&quot;asyncallowreason&quot;&gt;Async allow, reason shouldn't be NPRES_USER_BREAK...&lt;/div&gt;
+    &lt;div id=&quot;asyncallowurl&quot;&gt;Async allow, URL should be the final URL...&lt;/div&gt;
+    &lt;div id=&quot;asyncdenyreason&quot;&gt;Async deny, reason should be NPRES_USER_BREAK...&lt;/div&gt;
+    &lt;div id=&quot;asyncdenyurl&quot;&gt;Async deny, URL should be the previous URL...&lt;/div&gt;
+    &lt;div id=&quot;asyncmultiallowreason&quot;&gt;Async multiple allow, reason shouldn't be NPRES_USER_BREAK...&lt;/div&gt;
+    &lt;div id=&quot;asyncmultiallowurl&quot;&gt;Async multiple allow, URL should be the final URL...&lt;/div&gt;
+    &lt;div id=&quot;asyncmultidenyreason&quot;&gt;Async multiple deny, reason should be NPRES_USER_BREAK...&lt;/div&gt;
+    &lt;div id=&quot;asyncmultidenyurl&quot;&gt;Async multiple deny, URL should be the previous URL...&lt;/div&gt;
+&lt;/div&gt;
+&lt;script&gt;
+    function log(node, message)
+    {
+        text = document.getElementById(node);
+        text.innerText += message;
+    }
+    function cleanup()
+    {
+        --testsRemaining;
+        if (!testsRemaining) {
+            clearInterval(timer);
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+    }
+    function notifyTrue(reason, url)
+    {
+        log(&quot;syncallowreason&quot;, reason != 2);
+        log(&quot;syncallowurl&quot;, url == redirectURL);
+        cleanup();
+    }
+    function notifyFalse(reason, url)
+    {
+        log(&quot;syncdenyreason&quot;, reason == 2);
+        log(&quot;syncdenyurl&quot;, url == singleRedirect);
+        cleanup();
+    }
+    function notifyTrueAsync(reason, url)
+    {
+        log(&quot;asyncallowreason&quot;, reason != 2);
+        log(&quot;asyncallowurl&quot;, url == redirectURL);
+        cleanup();
+    }
+    function notifyFalseAsync(reason, url)
+    {
+        log(&quot;asyncdenyreason&quot;, reason == 2);
+        log(&quot;asyncdenyurl&quot;, url == singleRedirect);
+        cleanup();
+    }
+    function notifyMultiTrueAsync(reason, url)
+    {
+        log(&quot;asyncmultiallowreason&quot;, reason != 2);
+        log(&quot;asyncmultiallowurl&quot;, url == redirectURL);
+        cleanup();
+    }
+    function notifyMultiFalseAsync(reason, url)
+    {
+        log(&quot;asyncmultidenyreason&quot;, reason == 2);
+        log(&quot;asyncmultidenyurl&quot;, url == singleRedirect);
+        cleanup();
+    }
+
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+    }
+
+    var baseURL = &quot;http://127.0.0.1:8000/resources/redirect.php&quot;;
+    var redirectURL = &quot;http://127.0.0.1:8000/dummy&quot;;
+    var singleRedirect = baseURL + &quot;?code=307&amp;url=&quot; + encodeURIComponent(redirectURL);
+    var doubleRedirect = baseURL + &quot;?code=307&amp;url=&quot; + encodeURIComponent(singleRedirect);
+    var testsRemaining = 6;
+    plg.get(singleRedirect, 1, &quot;notifyTrue&quot;);
+    plg.get(singleRedirect, 0, &quot;notifyFalse&quot;);
+    plg.getAsync(singleRedirect, 1, &quot;notifyTrueAsync&quot;);
+    plg.getAsync(singleRedirect, 0, &quot;notifyFalseAsync&quot;);
+    plg.getAsync(doubleRedirect, 2, &quot;notifyMultiTrueAsync&quot;);
+    plg.getAsync(doubleRedirect, 1, &quot;notifyMultiFalseAsync&quot;);
+    var timer = setInterval(function() { plg.serviceAsync() }, 10);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformwk2httptestspluginsgeturlredirectnotifyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/wk2/http/tests/plugins/get-url-redirect-notify-expected.txt (0 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/wk2/http/tests/plugins/get-url-redirect-notify-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/wk2/http/tests/plugins/get-url-redirect-notify-expected.txt        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+
+Sync allow, reason shouldn't be NPRES_USER_BREAK...true
+Sync allow, URL should be the final URL...true
+Sync deny, reason should be NPRES_USER_BREAK...true
+Sync deny, URL should be the previous URL...true
+Async allow, reason shouldn't be NPRES_USER_BREAK...true
+Async allow, URL should be the final URL...true
+Async deny, reason should be NPRES_USER_BREAK...true
+Async deny, URL should be the previous URL...true
+Async multiple allow, reason shouldn't be NPRES_USER_BREAK...true
+Async multiple allow, URL should be the final URL...true
+Async multiple deny, reason should be NPRES_USER_BREAK...true
+Async multiple deny, URL should be the previous URL...true
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/ChangeLog        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2015-08-04  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        Implement NPAPI redirect handling
+        https://bugs.webkit.org/show_bug.cgi?id=138675
+        rdar://problem/15779101
+
+        Patch by Jeffrey Pfau, updated and tweaked by me.
+
+        Reviewed by Anders Carlsson.
+
+        Test: http/tests/plugins/get-url-redirect-notify.html
+
+        * loader/NetscapePlugInStreamLoader.cpp:
+        (WebCore::NetscapePlugInStreamLoader::init):
+        (WebCore::NetscapePlugInStreamLoader::willSendRequest):
+        (WebCore::NetscapePlugInStreamLoader::didReceiveResponse):
+        * loader/NetscapePlugInStreamLoader.h:
+        * loader/ResourceLoader.cpp:
+        (WebCore::ResourceLoader::init):
+        (WebCore::ResourceLoader::isSubresourceLoader):
+        (WebCore::ResourceLoader::willSendRequestInternal):
+        (WebCore::ResourceLoader::willSendRequest):
+        (WebCore::ResourceLoader::didSendData):
+        * loader/ResourceLoader.h:
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::isSubresourceLoader):
+        (WebCore::SubresourceLoader::willSendRequestInternal):
+        (WebCore::SubresourceLoader::willSendRequest): Deleted.
+        * loader/SubresourceLoader.h:
+        * plugins/npapi.h:
+        * plugins/npfunctions.h:
+
</ins><span class="cx"> 2015-08-04  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         RenderTheme::paint() should take RenderBox instead of RenderObject.
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderNetscapePlugInStreamLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -88,6 +88,18 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void NetscapePlugInStreamLoader::willSendRequest(ResourceRequest&amp;&amp; request, const ResourceResponse&amp; redirectResponse, std::function&lt;void(ResourceRequest&amp;&amp;)&gt;&amp;&amp; callback)
+{
+    RefPtr&lt;NetscapePlugInStreamLoader&gt; protect(this);
+
+    m_client-&gt;willSendRequest(this, WTF::move(request), redirectResponse, [protect, redirectResponse, callback](ResourceRequest request) {
+        if (!request.isNull())
+            protect-&gt;willSendRequestInternal(request, redirectResponse);
+
+        callback(WTF::move(request));
+    });
+}
+
</ins><span class="cx"> void NetscapePlugInStreamLoader::didReceiveResponse(const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><span class="cx">     Ref&lt;NetscapePlugInStreamLoader&gt; protect(*this);
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderNetscapePlugInStreamLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> 
</span><span class="cx"> class NetscapePlugInStreamLoaderClient {
</span><span class="cx"> public:
</span><ins>+    virtual void willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&amp;&amp;, const ResourceResponse&amp; redirectResponse, std::function&lt;void (ResourceRequest&amp;&amp;)&gt;&amp;&amp;) = 0;
</ins><span class="cx">     virtual void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&amp;) = 0;
</span><span class="cx">     virtual void didReceiveData(NetscapePlugInStreamLoader*, const char*, int) = 0;
</span><span class="cx">     virtual void didFail(NetscapePlugInStreamLoader*, const ResourceError&amp;) = 0;
</span><span class="lines">@@ -58,6 +59,7 @@
</span><span class="cx"> private:
</span><span class="cx">     virtual bool init(const ResourceRequest&amp;) override;
</span><span class="cx"> 
</span><ins>+    virtual void willSendRequest(ResourceRequest&amp;&amp;, const ResourceResponse&amp; redirectResponse, std::function&lt;void(ResourceRequest&amp;&amp;)&gt;&amp;&amp; callback) override;
</ins><span class="cx">     virtual void didReceiveResponse(const ResourceResponse&amp;) override;
</span><span class="cx">     virtual void didReceiveData(const char*, unsigned, long long encodedDataLength, DataPayloadType) override;
</span><span class="cx">     virtual void didReceiveBuffer(PassRefPtr&lt;SharedBuffer&gt;, long long encodedDataLength, DataPayloadType) override;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoader.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoader.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/loader/ResourceLoader.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -147,7 +147,7 @@
</span><span class="cx">             clientRequest.setFirstPartyForCookies(document-&gt;firstPartyForCookies());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    willSendRequest(clientRequest, ResourceResponse());
</del><ins>+    willSendRequestInternal(clientRequest, ResourceResponse());
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     // If this ResourceLoader was stopped as a result of willSendRequest, bail out.
</span><span class="lines">@@ -286,7 +286,7 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoader::willSendRequest(ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</del><ins>+void ResourceLoader::willSendRequestInternal(ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</ins><span class="cx"> {
</span><span class="cx">     // Protect this in this delegate method since the additional processing can do
</span><span class="cx">     // anything including possibly derefing this; one example of this is Radar 3266216.
</span><span class="lines">@@ -344,10 +344,10 @@
</span><span class="cx">         frameLoader()-&gt;client().dispatchDidReceiveServerRedirectForProvisionalLoad();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoader::willSendRequest(ResourceRequest&amp;&amp; request, const ResourceResponse&amp; redirectResponse, std::function&lt;void(ResourceRequest&amp;)&gt; callback)
</del><ins>+void ResourceLoader::willSendRequest(ResourceRequest&amp;&amp; request, const ResourceResponse&amp; redirectResponse, std::function&lt;void(ResourceRequest&amp;&amp;)&gt;&amp;&amp; callback)
</ins><span class="cx"> {
</span><del>-    willSendRequest(request, redirectResponse);
-    callback(request);
</del><ins>+    willSendRequestInternal(request, redirectResponse);
+    callback(WTF::move(request));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoader::didSendData(unsigned long long, unsigned long long)
</span><span class="lines">@@ -557,7 +557,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (documentLoader()-&gt;applicationCacheHost()-&gt;maybeLoadFallbackForRedirect(this, request, redirectResponse))
</span><span class="cx">         return;
</span><del>-    willSendRequest(request, redirectResponse);
</del><ins>+    willSendRequestInternal(request, redirectResponse);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoader::didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoader.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoader.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/loader/ResourceLoader.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -99,8 +99,7 @@
</span><span class="cx">     
</span><span class="cx">     virtual bool isSubresourceLoader();
</span><span class="cx"> 
</span><del>-    virtual void willSendRequest(ResourceRequest&amp;, const ResourceResponse&amp; redirectResponse);
-    virtual void willSendRequest(ResourceRequest&amp;&amp;, const ResourceResponse&amp; redirectResponse, std::function&lt;void(ResourceRequest&amp;)&gt; callback);
</del><ins>+    virtual void willSendRequest(ResourceRequest&amp;&amp;, const ResourceResponse&amp; redirectResponse, std::function&lt;void(ResourceRequest&amp;&amp;)&gt;&amp;&amp; callback);
</ins><span class="cx">     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
</span><span class="cx">     virtual void didReceiveResponse(const ResourceResponse&amp;);
</span><span class="cx">     virtual void didReceiveData(const char*, unsigned, long long encodedDataLength, DataPayloadType);
</span><span class="lines">@@ -170,6 +169,8 @@
</span><span class="cx">     virtual CFCachedURLResponseRef willCacheResponse(ResourceHandle*, CFCachedURLResponseRef) override;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    virtual void willSendRequestInternal(ResourceRequest&amp;, const ResourceResponse&amp; redirectResponse);
+
</ins><span class="cx">     RefPtr&lt;ResourceHandle&gt; m_handle;
</span><span class="cx">     RefPtr&lt;Frame&gt; m_frame;
</span><span class="cx">     RefPtr&lt;DocumentLoader&gt; m_documentLoader;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderSubresourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/SubresourceLoader.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -152,7 +152,7 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SubresourceLoader::willSendRequest(ResourceRequest&amp; newRequest, const ResourceResponse&amp; redirectResponse)
</del><ins>+void SubresourceLoader::willSendRequestInternal(ResourceRequest&amp; newRequest, const ResourceResponse&amp; redirectResponse)
</ins><span class="cx"> {
</span><span class="cx">     // Store the previous URL because the call to ResourceLoader::willSendRequest will modify it.
</span><span class="cx">     URL previousURL = request().url();
</span><span class="lines">@@ -185,7 +185,7 @@
</span><span class="cx">     if (newRequest.isNull() || reachedTerminalState())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ResourceLoader::willSendRequest(newRequest, redirectResponse);
</del><ins>+    ResourceLoader::willSendRequestInternal(newRequest, redirectResponse);
</ins><span class="cx">     if (newRequest.isNull())
</span><span class="cx">         cancel();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderSubresourceLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/SubresourceLoader.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/SubresourceLoader.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/loader/SubresourceLoader.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -63,7 +63,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool init(const ResourceRequest&amp;) override;
</span><span class="cx"> 
</span><del>-    virtual void willSendRequest(ResourceRequest&amp;, const ResourceResponse&amp; redirectResponse) override;
</del><ins>+    virtual void willSendRequestInternal(ResourceRequest&amp;, const ResourceResponse&amp; redirectResponse) override;
</ins><span class="cx">     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
</span><span class="cx">     virtual void didReceiveResponse(const ResourceResponse&amp;) override;
</span><span class="cx">     virtual void didReceiveData(const char*, unsigned, long long encodedDataLength, DataPayloadType) override;
</span></span></pre></div>
<a id="trunkSourceWebCorepluginsnpapih"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/plugins/npapi.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/plugins/npapi.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/plugins/npapi.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx"> /*----------------------------------------------------------------------*/
</span><span class="cx"> 
</span><span class="cx"> #define NP_VERSION_MAJOR 0
</span><del>-#define NP_VERSION_MINOR 24
</del><ins>+#define NP_VERSION_MINOR 26
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> /* The OS/2 version of Netscape uses RC_DATA to define the
</span><span class="lines">@@ -868,6 +868,9 @@
</span><span class="cx"> void        NP_LOADDS NPN_UnscheduleTimer(NPP instance, uint32_t timerID);
</span><span class="cx"> NPError     NP_LOADDS NPN_PopUpContextMenu(NPP instance, NPMenu* menu);
</span><span class="cx"> NPBool      NP_LOADDS NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
</span><ins>+NPBool      NP_LOADDS NPN_HandleEvent(NPP instance, void *event, NPBool handled);
+NPBool      NP_LOADDS NPN_UnfocusInstance(NPP instance, NPFocusDirection direction);
+void        NP_LOADDS NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow);
</ins><span class="cx"> 
</span><span class="cx"> #ifdef __cplusplus
</span><span class="cx"> }  /* end extern &quot;C&quot; */
</span></span></pre></div>
<a id="trunkSourceWebCorepluginsnpfunctionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/plugins/npfunctions.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/plugins/npfunctions.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebCore/plugins/npfunctions.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -71,6 +71,9 @@
</span><span class="cx"> typedef void (*NPN_UnscheduleTimerProcPtr)(NPP npp, uint32_t timerID);
</span><span class="cx"> typedef NPError (*NPN_PopUpContextMenuProcPtr)(NPP instance, NPMenu* menu);
</span><span class="cx"> typedef NPBool (*NPN_ConvertPointProcPtr)(NPP npp, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
</span><ins>+typedef NPBool (*NPN_HandleEventPtr)(NPP instance, void *event, NPBool handled);
+typedef NPBool (*NPN_UnfocusInstancePtr)(NPP instance, NPFocusDirection direction);
+typedef void (*NPN_URLRedirectResponsePtr)(NPP instance, void* notifyData, NPBool allow);
</ins><span class="cx"> 
</span><span class="cx"> typedef void (*NPN_ReleaseVariantValueProcPtr) (NPVariant *variant);
</span><span class="cx"> 
</span><span class="lines">@@ -175,6 +178,9 @@
</span><span class="cx">     NPN_UnscheduleTimerProcPtr unscheduletimer;
</span><span class="cx">     NPN_PopUpContextMenuProcPtr popupcontextmenu;
</span><span class="cx">     NPN_ConvertPointProcPtr convertpoint;
</span><ins>+    NPN_HandleEventPtr handleevent;
+    NPN_UnfocusInstancePtr unfocusinstance;
+    NPN_URLRedirectResponsePtr urlredirectresponse;
</ins><span class="cx"> } NPNetscapeFuncs;
</span><span class="cx"> 
</span><span class="cx"> typedef struct _NPPluginFuncs {
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit/mac/ChangeLog        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2015-08-04  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        Implement NPAPI redirect handling
+        https://bugs.webkit.org/show_bug.cgi?id=138675
+        rdar://problem/15779101
+
+        Patch by Jeffrey Pfau, updated and tweaked by me.
+
+        Reviewed by Anders Carlsson.
+
+        * Plugins/Hosted/HostedNetscapePluginStream.h:
+        (WebKit::HostedNetscapePluginStream::streamID):
+        * Plugins/Hosted/HostedNetscapePluginStream.mm:
+        (WebKit::HostedNetscapePluginStream::didFinishLoading):
+        (WebKit::HostedNetscapePluginStream::willSendRequest):
+        (WebKit::HostedNetscapePluginStream::didReceiveResponse):
+        * Plugins/WebNetscapePluginStream.h:
+        * Plugins/WebNetscapePluginStream.mm:
+        (WebNetscapePluginStream::stop):
+        (WebNetscapePluginStream::willSendRequest):
+        (WebNetscapePluginStream::didReceiveResponse):
+
</ins><span class="cx"> 2015-08-03  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed post-review feedback on r187797
</span></span></pre></div>
<a id="trunkSourceWebKitmacPluginsHostedHostedNetscapePluginStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -61,10 +61,12 @@
</span><span class="cx">     uint32_t streamID() const { return m_streamID; }
</span><span class="cx"> 
</span><span class="cx">     void startStreamWithResponse(NSURLResponse *response);
</span><del>-    void didReceiveData(WebCore::NetscapePlugInStreamLoader*, const char* bytes, int length);
-    void didFinishLoading(WebCore::NetscapePlugInStreamLoader*);
-    void didFail(WebCore::NetscapePlugInStreamLoader*, const WebCore::ResourceError&amp;);
</del><span class="cx"> 
</span><ins>+    // FIXME: Can these be made private?
+    void didReceiveData(WebCore::NetscapePlugInStreamLoader*, const char* bytes, int length) override;
+    void didFinishLoading(WebCore::NetscapePlugInStreamLoader*) override;
+    void didFail(WebCore::NetscapePlugInStreamLoader*, const WebCore::ResourceError&amp;) override;
+
</ins><span class="cx">     void start();
</span><span class="cx">     void stop();
</span><span class="cx"> 
</span><span class="lines">@@ -84,8 +86,9 @@
</span><span class="cx">     NSError *pluginCancelledConnectionError() const;
</span><span class="cx"> 
</span><span class="cx">     // NetscapePlugInStreamLoaderClient methods.
</span><del>-    void didReceiveResponse(WebCore::NetscapePlugInStreamLoader*, const WebCore::ResourceResponse&amp;);
-    bool wantsAllStreams() const;
</del><ins>+    void willSendRequest(WebCore::NetscapePlugInStreamLoader*, WebCore::ResourceRequest&amp;&amp;, const WebCore::ResourceResponse&amp; redirectResponse, std::function&lt;void (WebCore::ResourceRequest&amp;&amp;)&gt;&amp;&amp;) override;
+    void didReceiveResponse(WebCore::NetscapePlugInStreamLoader*, const WebCore::ResourceResponse&amp;) override;
+    bool wantsAllStreams() const override;
</ins><span class="cx">     
</span><span class="cx">     RefPtr&lt;NetscapePluginInstanceProxy&gt; m_instance;
</span><span class="cx">     uint32_t m_streamID;
</span></span></pre></div>
<a id="trunkSourceWebKitmacPluginsHostedHostedNetscapePluginStreammm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit/mac/Plugins/Hosted/HostedNetscapePluginStream.mm        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -128,7 +128,13 @@
</span><span class="cx">                                 m_streamID);
</span><span class="cx">     m_instance-&gt;disconnectStream(this);
</span><span class="cx"> }
</span><del>-    
</del><ins>+
+void HostedNetscapePluginStream::willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&amp;&amp; request, const ResourceResponse&amp;, std::function&lt;void (WebCore::ResourceRequest&amp;&amp;)&gt;&amp;&amp; callback)
+{
+    // FIXME: We should notify the plug-in with NPP_URLRedirectNotify here.
+    callback(WTF::move(request));
+}
+
</ins><span class="cx"> void HostedNetscapePluginStream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><span class="cx">     NSURLResponse *r = response.nsURLResponse();
</span></span></pre></div>
<a id="trunkSourceWebKitmacPluginsWebNetscapePluginStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/Plugins/WebNetscapePluginStream.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/Plugins/WebNetscapePluginStream.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit/mac/Plugins/WebNetscapePluginStream.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -79,10 +79,12 @@
</span><span class="cx">     
</span><span class="cx">     void startStreamWithResponse(NSURLResponse *response);
</span><span class="cx">     
</span><del>-    void didReceiveData(WebCore::NetscapePlugInStreamLoader*, const char* bytes, int length);
</del><span class="cx">     void destroyStreamWithError(NSError *);
</span><del>-    void didFinishLoading(WebCore::NetscapePlugInStreamLoader*);
</del><span class="cx"> 
</span><ins>+    // FIXME: Can these be made private?
+    void didReceiveData(WebCore::NetscapePlugInStreamLoader*, const char* bytes, int length) override;
+    void didFinishLoading(WebCore::NetscapePlugInStreamLoader*) override;
+
</ins><span class="cx"> private:
</span><span class="cx">     void destroyStream();
</span><span class="cx">     void cancelLoadWithError(NSError *);
</span><span class="lines">@@ -95,6 +97,7 @@
</span><span class="cx">     NSError *pluginCancelledConnectionError() const;
</span><span class="cx"> 
</span><span class="cx">     // NetscapePlugInStreamLoaderClient methods.
</span><ins>+    void willSendRequest(WebCore::NetscapePlugInStreamLoader*, WebCore::ResourceRequest&amp;&amp;, const WebCore::ResourceResponse&amp; redirectResponse, std::function&lt;void (WebCore::ResourceRequest&amp;&amp;)&gt;&amp;&amp;) override;
</ins><span class="cx">     void didReceiveResponse(WebCore::NetscapePlugInStreamLoader*, const WebCore::ResourceResponse&amp;);
</span><span class="cx">     void didFail(WebCore::NetscapePlugInStreamLoader*, const WebCore::ResourceError&amp;);
</span><span class="cx">     bool wantsAllStreams() const;
</span></span></pre></div>
<a id="trunkSourceWebKitmacPluginsWebNetscapePluginStreammm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/Plugins/WebNetscapePluginStream.mm (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/Plugins/WebNetscapePluginStream.mm        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit/mac/Plugins/WebNetscapePluginStream.mm        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -297,6 +297,12 @@
</span><span class="cx">         cancelLoadAndDestroyStreamWithError(m_loader-&gt;cancelledError());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebNetscapePluginStream::willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&amp;&amp; request, const ResourceResponse&amp;, std::function&lt;void (WebCore::ResourceRequest&amp;&amp;)&gt;&amp;&amp; callback)
+{
+    // FIXME: We should notify the plug-in with NPP_URLRedirectNotify here.
+    callback(WTF::move(request));
+}
+
</ins><span class="cx"> void WebNetscapePluginStream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><span class="cx">     NSURLResponse *r = response.nsURLResponse();
</span></span></pre></div>
<a id="trunkSourceWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/ChangeLog (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/ChangeLog        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit/win/ChangeLog        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2015-08-04  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        Implement NPAPI redirect handling
+        https://bugs.webkit.org/show_bug.cgi?id=138675
+        rdar://problem/15779101
+
+        Patch by Jeffrey Pfau, updated and tweaked by me.
+
+        Reviewed by Anders Carlsson.
+
+        * Plugins/PluginStream.cpp:
+        (WebCore::PluginStream::sendJavaScriptStream):
+        (WebCore::PluginStream::willSendRequest):
+        (WebCore::PluginStream::didReceiveResponse):
+        * Plugins/PluginStream.h:
+
</ins><span class="cx"> 2015-08-01  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix compile errors with VS2015
</span></span></pre></div>
<a id="trunkSourceWebKitwinPluginsPluginStreamcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/Plugins/PluginStream.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/Plugins/PluginStream.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit/win/Plugins/PluginStream.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -403,6 +403,12 @@
</span><span class="cx">     destroyStream(resultString.isNull() ? NPRES_NETWORK_ERR : NPRES_DONE);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginStream::willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&amp;&amp; request, const ResourceResponse&amp;, std::function&lt;void (WebCore::ResourceRequest&amp;&amp;)&gt;&amp;&amp; callback)
+{
+    // FIXME: We should notify the plug-in with NPP_URLRedirectNotify here.
+    callback(WTF::move(request));
+}
+
</ins><span class="cx"> void PluginStream::didReceiveResponse(NetscapePlugInStreamLoader* loader, const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><span class="cx">     ASSERT_UNUSED(loader, loader == m_loader);
</span></span></pre></div>
<a id="trunkSourceWebKitwinPluginsPluginStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/Plugins/PluginStream.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/win/Plugins/PluginStream.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit/win/Plugins/PluginStream.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -74,13 +74,6 @@
</span><span class="cx"> 
</span><span class="cx">         static NPP ownerForStream(NPStream*);
</span><span class="cx"> 
</span><del>-        // NetscapePlugInStreamLoaderClient
-        virtual void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&amp;);
-        virtual void didReceiveData(NetscapePlugInStreamLoader*, const char*, int);
-        virtual void didFail(NetscapePlugInStreamLoader*, const ResourceError&amp;);
-        virtual void didFinishLoading(NetscapePlugInStreamLoader*);
-        virtual bool wantsAllStreams() const;
-
</del><span class="cx">     private:
</span><span class="cx">         PluginStream(PluginStreamClient*, Frame*, const ResourceRequest&amp;, bool sendNotification, void* notifyData, const NPPluginFuncs*, NPP instance, const PluginQuirkSet&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -88,6 +81,14 @@
</span><span class="cx">         void destroyStream(NPReason);
</span><span class="cx">         void destroyStream();
</span><span class="cx"> 
</span><ins>+        // NetscapePlugInStreamLoaderClient
+        void willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&amp;&amp;, const ResourceResponse&amp; redirectResponse, std::function&lt;void (ResourceRequest&amp;&amp;)&gt;&amp;&amp;) override;
+        void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&amp;) override;
+        void didReceiveData(NetscapePlugInStreamLoader*, const char*, int) override;
+        void didFail(NetscapePlugInStreamLoader*, const ResourceError&amp;) override;
+        void didFinishLoading(NetscapePlugInStreamLoader*) override;
+        bool wantsAllStreams() const override;
+
</ins><span class="cx">         ResourceRequest m_resourceRequest;
</span><span class="cx">         ResourceResponse m_resourceResponse;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/ChangeLog        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -1,3 +1,77 @@
</span><ins>+2015-08-04  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        Implement NPAPI redirect handling
+        https://bugs.webkit.org/show_bug.cgi?id=138675
+        rdar://problem/15779101
+
+        Patch by Jeffrey Pfau, updated and tweaked by me.
+
+        Reviewed by Anders Carlsson.
+
+        * PluginProcess/PluginControllerProxy.cpp:
+        (WebKit::PluginControllerProxy::loadURL):
+        (WebKit::PluginControllerProxy::continueStreamLoad):
+        (WebKit::PluginControllerProxy::cancelStreamLoad):
+        (WebKit::PluginControllerProxy::didEvaluateJavaScript):
+        (WebKit::PluginControllerProxy::streamWillSendRequest):
+        (WebKit::PluginControllerProxy::streamDidReceiveResponse):
+        * PluginProcess/PluginControllerProxy.h:
+        * PluginProcess/PluginControllerProxy.messages.in:
+        * WebProcess/Network/WebResourceLoader.cpp:
+        (WebKit::WebResourceLoader::willSendRequest):
+        * WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp:
+        (WebKit::NPN_ConvertPoint):
+        (WebKit::NPN_URLRedirectResponse):
+        (WebKit::initializeBrowserFuncs):
+        (WebKit::netscapeBrowserFuncs):
+        * WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
+        (WebKit::NetscapePlugin::getAuthenticationInfo):
+        (WebKit::NetscapePlugin::registerRedirect):
+        (WebKit::NetscapePlugin::urlRedirectResponse):
+        (WebKit::NetscapePlugin::setIsPlayingAudio):
+        (WebKit::NetscapePlugin::NPP_URLNotify):
+        (WebKit::NetscapePlugin::NPP_URLRedirectNotify):
+        (WebKit::NetscapePlugin::NPP_GetValue):
+        (WebKit::NetscapePlugin::didEvaluateJavaScript):
+        (WebKit::NetscapePlugin::streamWillSendRequest):
+        (WebKit::NetscapePlugin::streamDidReceiveResponse):
+        * WebProcess/Plugins/Netscape/NetscapePlugin.h:
+        * WebProcess/Plugins/Netscape/NetscapePluginStream.cpp:
+        (WebKit::NetscapePluginStream::~NetscapePluginStream):
+        (WebKit::NetscapePluginStream::willSendRequest):
+        (WebKit::NetscapePluginStream::didReceiveResponse):
+        (WebKit::NetscapePluginStream::stop):
+        (WebKit::NetscapePluginStream::setURL):
+        (WebKit::NetscapePluginStream::cancel):
+        * WebProcess/Plugins/Netscape/NetscapePluginStream.h:
+        (WebKit::NetscapePluginStream::streamID):
+        (WebKit::NetscapePluginStream::npStream):
+        * WebProcess/Plugins/PDF/PDFPlugin.h:
+        * WebProcess/Plugins/Plugin.h:
+        * WebProcess/Plugins/PluginController.h:
+        * WebProcess/Plugins/PluginProxy.cpp:
+        (WebKit::PluginProxy::didEvaluateJavaScript):
+        (WebKit::PluginProxy::streamWillSendRequest):
+        (WebKit::PluginProxy::streamDidReceiveResponse):
+        (WebKit::PluginProxy::setPluginIsPlayingAudio):
+        (WebKit::PluginProxy::continueStreamLoad):
+        (WebKit::PluginProxy::cancelStreamLoad):
+        * WebProcess/Plugins/PluginProxy.h:
+        * WebProcess/Plugins/PluginProxy.messages.in:
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::Stream::streamID):
+        (WebKit::PluginView::Stream::Stream):
+        (WebKit::PluginView::Stream::cancel):
+        (WebKit::PluginView::Stream::continueLoad):
+        (WebKit::buildHTTPHeaders):
+        (WebKit::lastModifiedDateMS):
+        (WebKit::PluginView::Stream::willSendRequest):
+        (WebKit::PluginView::Stream::didReceiveResponse):
+        (WebKit::PluginView::cancelStreamLoad):
+        (WebKit::PluginView::continueStreamLoad):
+        (WebKit::PluginView::cancelManualStreamLoad):
+        * WebProcess/Plugins/PluginView.h:
+
</ins><span class="cx"> 2015-08-04  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r187812.
</span></span></pre></div>
<a id="trunkSourceWebKit2PluginProcessPluginControllerProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -241,6 +241,11 @@
</span><span class="cx">     m_connection-&gt;connection()-&gt;send(Messages::PluginProxy::LoadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups), m_pluginInstanceID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginControllerProxy::continueStreamLoad(uint64_t streamID)
+{
+    m_connection-&gt;connection()-&gt;send(Messages::PluginProxy::ContinueStreamLoad(streamID), m_pluginInstanceID);
+}
+
</ins><span class="cx"> void PluginControllerProxy::cancelStreamLoad(uint64_t streamID)
</span><span class="cx"> {
</span><span class="cx">     m_connection-&gt;connection()-&gt;send(Messages::PluginProxy::CancelStreamLoad(streamID), m_pluginInstanceID);
</span><span class="lines">@@ -463,6 +468,11 @@
</span><span class="cx">     m_plugin-&gt;didEvaluateJavaScript(requestID, result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginControllerProxy::streamWillSendRequest(uint64_t streamID, const String&amp; requestURLString, const String&amp; redirectResponseURLString, uint32_t redirectResponseStatusCode)
+{
+    m_plugin-&gt;streamWillSendRequest(streamID, URL(ParsedURLString, requestURLString), URL(ParsedURLString, redirectResponseURLString), redirectResponseStatusCode);
+}
+
</ins><span class="cx"> void PluginControllerProxy::streamDidReceiveResponse(uint64_t streamID, const String&amp; responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers)
</span><span class="cx"> {
</span><span class="cx">     m_plugin-&gt;streamDidReceiveResponse(streamID, URL(ParsedURLString, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String());
</span></span></pre></div>
<a id="trunkSourceWebKit2PluginProcessPluginControllerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx">     virtual void invalidate(const WebCore::IntRect&amp;) override;
</span><span class="cx">     virtual String userAgent() override;
</span><span class="cx">     virtual void loadURL(uint64_t requestID, const String&amp; method, const String&amp; urlString, const String&amp; target, const WebCore::HTTPHeaderMap&amp; headerFields, const Vector&lt;uint8_t&gt;&amp; httpBody, bool allowPopups) override;
</span><ins>+    virtual void continueStreamLoad(uint64_t streamID) override;
</ins><span class="cx">     virtual void cancelStreamLoad(uint64_t streamID) override;
</span><span class="cx">     virtual void cancelManualStreamLoad() override;
</span><span class="cx">     virtual NPObject* windowScriptNPObject() override;
</span><span class="lines">@@ -126,6 +127,7 @@
</span><span class="cx">     void geometryDidChange(const WebCore::IntSize&amp; pluginSize, const WebCore::IntRect&amp; clipRect, const WebCore::AffineTransform&amp; pluginToRootViewTransform, float contentsScaleFactor, const ShareableBitmap::Handle&amp; backingStoreHandle);
</span><span class="cx">     void visibilityDidChange(bool isVisible);
</span><span class="cx">     void didEvaluateJavaScript(uint64_t requestID, const String&amp; result);
</span><ins>+    void streamWillSendRequest(uint64_t streamID, const String&amp; requestURLString, const String&amp; redirectResponseURLString, uint32_t redirectResponseStatusCode);
</ins><span class="cx">     void streamDidReceiveResponse(uint64_t streamID, const String&amp; responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers);
</span><span class="cx">     void streamDidReceiveData(uint64_t streamID, const IPC::DataReference&amp; data);
</span><span class="cx">     void streamDidFinishLoading(uint64_t streamID);
</span></span></pre></div>
<a id="trunkSourceWebKit2PluginProcessPluginControllerProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.messages.in (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.messages.in        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/PluginProcess/PluginControllerProxy.messages.in        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -38,6 +38,9 @@
</span><span class="cx">     # Sent when JavaScript that the plug-in asked to be evaluated has been evaluated.
</span><span class="cx">     DidEvaluateJavaScript(uint64_t requestID, String result)
</span><span class="cx"> 
</span><ins>+    # Sent when the plug-in receives will send a request for a stream.
+    StreamWillSendRequest(uint64_t streamID, String requestURLString, String redirectResponseURLString, uint32_t redirectResponseStatusCode)
+
</ins><span class="cx">     # Sent when the plug-in receives a response for a stream.
</span><span class="cx">     StreamDidReceiveResponse(uint64_t streamID, String responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, String mimeType, String headers)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessNetworkWebResourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -89,14 +89,11 @@
</span><span class="cx">     if (m_coreLoader-&gt;documentLoader()-&gt;applicationCacheHost()-&gt;maybeLoadFallbackForRedirect(m_coreLoader.get(), newRequest, redirectResponse))
</span><span class="cx">         return;
</span><span class="cx">     // FIXME: Do we need to update NetworkResourceLoader clientCredentialPolicy in case loader policy is DoNotAskClientForCrossOriginCredentials?
</span><del>-    m_coreLoader-&gt;willSendRequest(WTF::move(newRequest), redirectResponse, [protect](ResourceRequest&amp; request) {
</del><ins>+    m_coreLoader-&gt;willSendRequest(WTF::move(newRequest), redirectResponse, [protect](ResourceRequest&amp;&amp; request) {
</ins><span class="cx">         if (!protect-&gt;m_coreLoader)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        if (!request.isNull())
-            protect-&gt;send(Messages::NetworkResourceLoader::ContinueWillSendRequest(request));
-        else
-            protect-&gt;m_coreLoader-&gt;cancel();
</del><ins>+        protect-&gt;send(Messages::NetworkResourceLoader::ContinueWillSendRequest(request));
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsNetscapeNetscapeBrowserFuncscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -983,6 +983,13 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+static void NPN_URLRedirectResponse(NPP npp, void* notifyData, NPBool allow)
+{
+    RefPtr&lt;NetscapePlugin&gt; plugin = NetscapePlugin::fromNPP(npp);
+
+    plugin-&gt;urlRedirectResponse(notifyData, allow);
+}
+
</ins><span class="cx"> static void initializeBrowserFuncs(NPNetscapeFuncs &amp;netscapeFuncs)
</span><span class="cx"> {
</span><span class="cx">     netscapeFuncs.size = sizeof(NPNetscapeFuncs);
</span><span class="lines">@@ -1046,6 +1053,11 @@
</span><span class="cx">     netscapeFuncs.popupcontextmenu = 0;
</span><span class="cx">     netscapeFuncs.convertpoint = 0;
</span><span class="cx"> #endif
</span><ins>+#if ENABLE(NETWORK_PROCESS)
+    netscapeFuncs.urlredirectresponse = NPN_URLRedirectResponse;
+#else
+    netscapeFuncs.urlredirectresponse = 0;
+#endif
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> NPNetscapeFuncs* netscapeBrowserFuncs()
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsNetscapeNetscapePlugincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -396,8 +396,41 @@
</span><span class="cx"> bool NetscapePlugin::getAuthenticationInfo(const ProtectionSpace&amp; protectionSpace, String&amp; username, String&amp; password)
</span><span class="cx"> {
</span><span class="cx">     return controller()-&gt;getAuthenticationInfo(protectionSpace, username, password);
</span><del>-}    
</del><ins>+}
</ins><span class="cx"> 
</span><ins>+void NetscapePlugin::registerRedirect(NetscapePluginStream* stream, const URL&amp; requestURL, int redirectResponseStatus, void* notificationData)
+{
+#if ENABLE(NETWORK_PROCESS)
+    // NPP_URLRedirectNotify may synchronously request this stream back out, so set it first
+    m_redirects.set(notificationData, std::make_pair(stream, requestURL.string()));
+    if (!NPP_URLRedirectNotify(requestURL.string().utf8().data(), redirectResponseStatus, notificationData)) {
+        m_redirects.take(notificationData);
+        controller()-&gt;continueStreamLoad(stream-&gt;streamID());
+    }
+#else
+    controller()-&gt;continueStreamLoad(stream-&gt;streamID());
+#endif
+}
+
+void NetscapePlugin::urlRedirectResponse(void* notifyData, bool allow)
+{
+    if (!m_redirects.contains(notifyData))
+        return;
+
+    auto redirect = m_redirects.take(notifyData);
+    if (!redirect.first)
+        return;
+
+    RefPtr&lt;NetscapePluginStream&gt; stream = redirect.first;
+    if (!allow) {
+        controller()-&gt;cancelStreamLoad(stream-&gt;streamID());
+        stream-&gt;stop(NPRES_USER_BREAK);
+    } else {
+        stream-&gt;setURL(redirect.second);
+        controller()-&gt;continueStreamLoad(stream-&gt;streamID());
+    }
+}
+
</ins><span class="cx"> void NetscapePlugin::setIsPlayingAudio(bool isPlayingAudio)
</span><span class="cx"> {
</span><span class="cx">     controller()-&gt;setPluginIsPlayingAudio(isPlayingAudio);
</span><span class="lines">@@ -453,6 +486,15 @@
</span><span class="cx">     m_pluginModule-&gt;pluginFuncs().urlnotify(&amp;m_npp, url, reason, notifyData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool NetscapePlugin::NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData)
+{
+    if (!m_pluginModule-&gt;pluginFuncs().urlredirectnotify)
+        return false;
+
+    m_pluginModule-&gt;pluginFuncs().urlredirectnotify(&amp;m_npp, url, status, notifyData);
+    return true;
+}
+
</ins><span class="cx"> NPError NetscapePlugin::NPP_GetValue(NPPVariable variable, void *value)
</span><span class="cx"> {
</span><span class="cx">     if (!m_pluginModule-&gt;pluginFuncs().getvalue)
</span><span class="lines">@@ -814,6 +856,14 @@
</span><span class="cx">         pluginStream-&gt;sendJavaScriptStream(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void NetscapePlugin::streamWillSendRequest(uint64_t streamID, const URL&amp; requestURL, const URL&amp; redirectResponseURL, int redirectResponseStatus)
+{
+    ASSERT(m_isStarted);
+
+    if (NetscapePluginStream* pluginStream = streamFromID(streamID))
+        pluginStream-&gt;willSendRequest(requestURL, redirectResponseURL, redirectResponseStatus);
+}
+
</ins><span class="cx"> void NetscapePlugin::streamDidReceiveResponse(uint64_t streamID, const URL&amp; responseURL, uint32_t streamLength, 
</span><span class="cx">                                               uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers, const String&amp; /* suggestedFileName */)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsNetscapeNetscapePluginh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -141,6 +141,9 @@
</span><span class="cx"> 
</span><span class="cx">     void setIsPlayingAudio(bool);
</span><span class="cx"> 
</span><ins>+    void registerRedirect(NetscapePluginStream*, const WebCore::URL&amp; requestURL, int redirectResponseStatus, void* notificationData);
+    void urlRedirectResponse(void* notifyData, bool allow);
+
</ins><span class="cx">     // Member functions for calling into the plug-in.
</span><span class="cx">     NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData*);
</span><span class="cx">     NPError NPP_Destroy(NPSavedData**);
</span><span class="lines">@@ -152,6 +155,7 @@
</span><span class="cx">     int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer);
</span><span class="cx">     int16_t NPP_HandleEvent(void* event);
</span><span class="cx">     void NPP_URLNotify(const char* url, NPReason, void* notifyData);
</span><ins>+    bool NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData);
</ins><span class="cx">     NPError NPP_GetValue(NPPVariable, void *value);
</span><span class="cx">     NPError NPP_SetValue(NPNVariable, void *value);
</span><span class="cx"> 
</span><span class="lines">@@ -199,7 +203,8 @@
</span><span class="cx">     virtual void frameDidFinishLoading(uint64_t requestID) override;
</span><span class="cx">     virtual void frameDidFail(uint64_t requestID, bool wasCancelled) override;
</span><span class="cx">     virtual void didEvaluateJavaScript(uint64_t requestID, const String&amp; result) override;
</span><del>-    virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL&amp; responseURL, uint32_t streamLength, 
</del><ins>+    virtual void streamWillSendRequest(uint64_t streamID, const WebCore::URL&amp; requestURL, const WebCore::URL&amp; responseURL, int responseStatus) override;
+    virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL&amp; responseURL, uint32_t streamLength,
</ins><span class="cx">                                           uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers, const String&amp; suggestedFileName) override;
</span><span class="cx">     virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override;
</span><span class="cx">     virtual void streamDidFinishLoading(uint64_t streamID) override;
</span><span class="lines">@@ -288,6 +293,7 @@
</span><span class="cx"> 
</span><span class="cx">     typedef HashMap&lt;uint64_t, RefPtr&lt;NetscapePluginStream&gt;&gt; StreamsMap;
</span><span class="cx">     StreamsMap m_streams;
</span><ins>+    HashMap&lt;void*, std::pair&lt;RefPtr&lt;NetscapePluginStream&gt;, String&gt;&gt; m_redirects;
</ins><span class="cx"> 
</span><span class="cx">     RefPtr&lt;NetscapePluginModule&gt; m_pluginModule;
</span><span class="cx">     NPP_t m_npp;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsNetscapeNetscapePluginStreamcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -62,6 +62,14 @@
</span><span class="cx">     ASSERT(m_fileHandle == invalidPlatformFileHandle);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void NetscapePluginStream::willSendRequest(const URL&amp; requestURL, const URL&amp; redirectResponseURL, int redirectResponseStatus)
+{
+    Ref&lt;NetscapePluginStream&gt; protect(*this);
+
+    if (redirectResponseStatus &gt;= 300 &amp;&amp; redirectResponseStatus &lt; 400)
+        m_plugin-&gt;registerRedirect(this, requestURL, redirectResponseStatus, m_notificationData);
+}
+
</ins><span class="cx"> void NetscapePluginStream::didReceiveResponse(const URL&amp; responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers)
</span><span class="cx"> {
</span><span class="cx">     // Starting the stream could cause the plug-in stream to go away so we keep a reference to it here.
</span><span class="lines">@@ -338,6 +346,11 @@
</span><span class="cx">     notifyAndDestroyStream(reason);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void NetscapePluginStream::setURL(const String&amp; newURLString)
+{
+    m_requestURLString = newURLString;
+}
+
</ins><span class="cx"> void NetscapePluginStream::cancel()
</span><span class="cx"> {
</span><span class="cx">     m_plugin-&gt;cancelStreamLoad(this);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsNetscapeNetscapePluginStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx">     uint64_t streamID() const { return m_streamID; }
</span><span class="cx">     const NPStream* npStream() const { return &amp;m_npStream; }
</span><span class="cx"> 
</span><ins>+    void willSendRequest(const WebCore::URL&amp; requestURL, const WebCore::URL&amp; redirectResponseURL, int redirectResponseStatus);
</ins><span class="cx">     void didReceiveResponse(const WebCore::URL&amp; responseURL, uint32_t streamLength,
</span><span class="cx">                             uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers);
</span><span class="cx">     void didReceiveData(const char* bytes, int length);
</span><span class="lines">@@ -67,6 +68,7 @@
</span><span class="cx"> 
</span><span class="cx">     void stop(NPReason);
</span><span class="cx">     NPError destroy(NPReason);
</span><ins>+    void setURL(const String&amp; newURLString);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     NetscapePluginStream(PassRefPtr&lt;NetscapePlugin&gt;, uint64_t streamID, const String&amp; requestURLString, bool sendNotification, void* notificationData);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsPDFPDFPluginh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -128,6 +128,7 @@
</span><span class="cx">     virtual void frameDidFinishLoading(uint64_t requestID) override;
</span><span class="cx">     virtual void frameDidFail(uint64_t requestID, bool wasCancelled) override;
</span><span class="cx">     virtual void didEvaluateJavaScript(uint64_t requestID, const String&amp; result) override;
</span><ins>+    virtual void streamWillSendRequest(uint64_t streamID, const WebCore::URL&amp; requestURL, const WebCore::URL&amp; responseURL, int responseStatus) override { }
</ins><span class="cx">     virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL&amp; responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers, const String&amp; suggestedFileName) override;
</span><span class="cx">     virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override;
</span><span class="cx">     virtual void streamDidFinishLoading(uint64_t streamID) override;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsPluginh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -165,6 +165,9 @@
</span><span class="cx">     // back the result. If evaluating the script failed, result will be null.
</span><span class="cx">     virtual void didEvaluateJavaScript(uint64_t requestID, const String&amp; result) = 0;
</span><span class="cx"> 
</span><ins>+    // Tells the plug-in that a stream may send an HTTP request.
+    virtual void streamWillSendRequest(uint64_t streamID, const WebCore::URL&amp; requestURL, const WebCore::URL&amp; responseURL, int responseStatusCode) = 0;
+
</ins><span class="cx">     // Tells the plug-in that a stream has received its HTTP response.
</span><span class="cx">     virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL&amp; responseURL, uint32_t streamLength, 
</span><span class="cx">                                           uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers, const String&amp; suggestedFileName) = 0;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsPluginControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginController.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/PluginController.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginController.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -64,7 +64,10 @@
</span><span class="cx">     virtual void loadURL(uint64_t requestID, const String&amp; method, const String&amp; urlString, const String&amp; target, 
</span><span class="cx">                          const WebCore::HTTPHeaderMap&amp; headerFields, const Vector&lt;uint8_t&gt;&amp; httpBody, bool allowPopups) = 0;
</span><span class="cx"> 
</span><del>-    /// Cancels the load of a stream that was requested by loadURL.
</del><ins>+    // Continues the load of a stream that was requested by loadURL.
+    virtual void continueStreamLoad(uint64_t streamID) = 0;
+
+    // Cancels the load of a stream that was requested by loadURL.
</ins><span class="cx">     virtual void cancelStreamLoad(uint64_t streamID) = 0;
</span><span class="cx"> 
</span><span class="cx">     // Cancels the load of the manual stream.
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsPluginProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -321,6 +321,11 @@
</span><span class="cx">     m_connection-&gt;connection()-&gt;send(Messages::PluginControllerProxy::DidEvaluateJavaScript(requestID, result), m_pluginInstanceID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginProxy::streamWillSendRequest(uint64_t streamID, const URL&amp; requestURL, const URL&amp; responseURL, int responseStatus)
+{
+    m_connection-&gt;connection()-&gt;send(Messages::PluginControllerProxy::StreamWillSendRequest(streamID, requestURL.string(), responseURL.string(), responseStatus), m_pluginInstanceID);
+}
+
</ins><span class="cx"> void PluginProxy::streamDidReceiveResponse(uint64_t streamID, const URL&amp; responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String&amp; mimeType, const WTF::String&amp; headers, const String&amp; /* suggestedFileName */)
</span><span class="cx"> {
</span><span class="cx">     m_connection-&gt;connection()-&gt;send(Messages::PluginControllerProxy::StreamDidReceiveResponse(streamID, responseURL.string(), streamLength, lastModifiedTime, mimeType, headers), m_pluginInstanceID);
</span><span class="lines">@@ -658,6 +663,11 @@
</span><span class="cx">     controller()-&gt;setPluginIsPlayingAudio(pluginIsPlayingAudio);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginProxy::continueStreamLoad(uint64_t streamID)
+{
+    controller()-&gt;continueStreamLoad(streamID);
+}
+
</ins><span class="cx"> void PluginProxy::cancelStreamLoad(uint64_t streamID)
</span><span class="cx"> {
</span><span class="cx">     controller()-&gt;cancelStreamLoad(streamID);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsPluginProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -90,6 +90,7 @@
</span><span class="cx">     virtual void frameDidFinishLoading(uint64_t requestID) override;
</span><span class="cx">     virtual void frameDidFail(uint64_t requestID, bool wasCancelled) override;
</span><span class="cx">     virtual void didEvaluateJavaScript(uint64_t requestID, const String&amp; result) override;
</span><ins>+    virtual void streamWillSendRequest(uint64_t streamID, const WebCore::URL&amp; requestURL, const WebCore::URL&amp; responseURL, int responseStatus) override;
</ins><span class="cx">     virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL&amp; responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String&amp; mimeType, const String&amp; headers, const String&amp; suggestedFileName) override;
</span><span class="cx">     virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override;
</span><span class="cx">     virtual void streamDidFinishLoading(uint64_t streamID) override;
</span><span class="lines">@@ -168,6 +169,7 @@
</span><span class="cx">     void getPluginElementNPObject(uint64_t&amp; pluginElementNPObjectID);
</span><span class="cx">     void evaluate(const NPVariantData&amp; npObjectAsVariantData, const String&amp; scriptString, bool allowPopups, bool&amp; returnValue, NPVariantData&amp; resultData);
</span><span class="cx">     void setPluginIsPlayingAudio(bool);
</span><ins>+    void continueStreamLoad(uint64_t streamID);
</ins><span class="cx">     void cancelStreamLoad(uint64_t streamID);
</span><span class="cx">     void cancelManualStreamLoad();
</span><span class="cx">     void setStatusbarText(const String&amp; statusbarText);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsPluginProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -50,6 +50,9 @@
</span><span class="cx">     # Cancels the given stream load.
</span><span class="cx">     CancelStreamLoad(uint64_t streamID)
</span><span class="cx"> 
</span><ins>+    # Continues the given stream load.
+    ContinueStreamLoad(uint64_t streamID)
+
</ins><span class="cx">     # Cancel the manual stream load.
</span><span class="cx">     CancelManualStreamLoad()
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsPluginViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -115,6 +115,7 @@
</span><span class="cx"> 
</span><span class="cx">     void start();
</span><span class="cx">     void cancel();
</span><ins>+    void continueLoad();
</ins><span class="cx"> 
</span><span class="cx">     uint64_t streamID() const { return m_streamID; }
</span><span class="cx"> 
</span><span class="lines">@@ -128,15 +129,17 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // NetscapePluginStreamLoaderClient
</span><del>-    virtual void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&amp;);
-    virtual void didReceiveData(NetscapePlugInStreamLoader*, const char*, int);
-    virtual void didFail(NetscapePlugInStreamLoader*, const ResourceError&amp;);
-    virtual void didFinishLoading(NetscapePlugInStreamLoader*);
</del><ins>+    void willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&amp;&amp;, const ResourceResponse&amp; redirectResponse, std::function&lt;void (ResourceRequest&amp;&amp;)&gt;&amp;&amp;) override;
+    void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&amp;) override;
+    void didReceiveData(NetscapePlugInStreamLoader*, const char*, int) override;
+    void didFail(NetscapePlugInStreamLoader*, const ResourceError&amp;) override;
+    void didFinishLoading(NetscapePlugInStreamLoader*) override;
</ins><span class="cx"> 
</span><span class="cx">     PluginView* m_pluginView;
</span><span class="cx">     uint64_t m_streamID;
</span><del>-    const ResourceRequest m_request;
-    
</del><ins>+    ResourceRequest m_request;
+    std::function&lt;void (ResourceRequest)&gt; m_loadCallback;
+
</ins><span class="cx">     // True if the stream was explicitly cancelled by calling cancel().
</span><span class="cx">     // (As opposed to being cancelled by the user hitting the stop button for example.
</span><span class="cx">     bool m_streamWasCancelled;
</span><span class="lines">@@ -169,6 +172,14 @@
</span><span class="cx">     m_loader = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginView::Stream::continueLoad()
+{
+    ASSERT(m_pluginView-&gt;m_plugin);
+    ASSERT(m_loadCallback);
+
+    m_loadCallback(m_request);
+}
+
</ins><span class="cx"> static String buildHTTPHeaders(const ResourceResponse&amp; response, long long&amp; expectedContentLength)
</span><span class="cx"> {
</span><span class="cx">     if (!response.isHTTP())
</span><span class="lines">@@ -210,6 +221,16 @@
</span><span class="cx">     return std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(lastModified.value().time_since_epoch()).count();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginView::Stream::willSendRequest(NetscapePlugInStreamLoader*, ResourceRequest&amp;&amp; request, const ResourceResponse&amp; redirectResponse, std::function&lt;void (ResourceRequest&amp;&amp;)&gt;&amp;&amp; decisionHandler)
+{
+    const URL&amp; requestURL = request.url();
+    const URL&amp; redirectResponseURL = redirectResponse.url();
+
+    m_loadCallback = decisionHandler;
+    m_request = request;
+    m_pluginView-&gt;m_plugin-&gt;streamWillSendRequest(m_streamID, requestURL, redirectResponseURL, redirectResponse.httpStatusCode());
+}
+
</ins><span class="cx"> void PluginView::Stream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><span class="cx">     // Compute the stream related data from the resource response.
</span><span class="lines">@@ -1404,6 +1425,15 @@
</span><span class="cx">     ASSERT(!m_streams.contains(streamID));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginView::continueStreamLoad(uint64_t streamID)
+{
+    RefPtr&lt;Stream&gt; stream = m_streams.get(streamID);
+    if (!stream)
+        return;
+
+    stream-&gt;continueLoad();
+}
+
</ins><span class="cx"> void PluginView::cancelManualStreamLoad()
</span><span class="cx"> {
</span><span class="cx">     if (!frame())
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessPluginsPluginViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -196,6 +196,7 @@
</span><span class="cx">     virtual String userAgent() override;
</span><span class="cx">     virtual void loadURL(uint64_t requestID, const String&amp; method, const String&amp; urlString, const String&amp; target, const WebCore::HTTPHeaderMap&amp; headerFields, const Vector&lt;uint8_t&gt;&amp; httpBody, bool allowPopups) override;
</span><span class="cx">     virtual void cancelStreamLoad(uint64_t streamID) override;
</span><ins>+    virtual void continueStreamLoad(uint64_t streamID) override;
</ins><span class="cx">     virtual void cancelManualStreamLoad() override;
</span><span class="cx"> #if ENABLE(NETSCAPE_PLUGIN_API)
</span><span class="cx">     virtual NPObject* windowScriptNPObject() override;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Tools/ChangeLog        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2015-08-04  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        Implement NPAPI redirect handling
+        https://bugs.webkit.org/show_bug.cgi?id=138675
+        rdar://problem/15779101
+
+        Patch by Jeffrey Pfau, updated and tweaked by me.
+
+        Reviewed by Anders Carlsson.
+
+        * DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj:
+        * DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj.filters:
+        * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+        * DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt:
+        * DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp:
+        (PluginTest::NPP_URLNotify):
+        (PluginTest::NPP_URLRedirectNotify):
+        (PluginTest::NPP_GetValue):
+        (PluginTest::NPN_GetURLNotify):
+        (PluginTest::NPN_PostURLNotify):
+        (PluginTest::NPN_GetValue):
+        (PluginTest::NPN_ReleaseVariantValue):
+        (PluginTest::NPN_URLRedirectResponse):
+        (PluginTest::NPN_ConvertPoint):
+        * DumpRenderTree/TestNetscapePlugIn/PluginTest.h:
+        * DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp: Added.
+        (URLRedirect::URLRedirect):
+        (URLRedirect::ScriptableObject::hasMethod):
+        (URLRedirect::ScriptableObject::get):
+        (URLRedirect::ScriptableObject::serviceAsync):
+        (URLRedirect::ScriptableObject::invoke):
+        (URLRedirect::NPP_GetValue):
+        (URLRedirect::NPP_URLNotify):
+        (URLRedirect::NPP_URLRedirectNotify):
+        * DumpRenderTree/TestNetscapePlugIn/main.cpp:
+        (NP_GetEntryPoints):
+        (NPP_URLNotify):
+        (NPP_URLRedirectNotify):
+        (NPP_GetValue):
+
</ins><span class="cx"> 2015-08-04  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Move Matt Daiter to committers.
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeDumpRenderTreevcxprojTestNetscapePluginTestNetscapePluginvcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Tools/DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -75,6 +75,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\PluginScriptableObjectOverridesAllProperties.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\PrivateBrowsing.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\ToStringAndValueOfObject.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\URLRedirect.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\win\CallJSThatDestroysPlugin.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\win\DrawsGradient.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\win\DumpWindowRect.cpp&quot; /&gt;
</span><span class="lines">@@ -234,4 +235,4 @@
</span><span class="cx">   &lt;Import Project=&quot;$(VCTargetsPath)\Microsoft.Cpp.targets&quot; /&gt;
</span><span class="cx">   &lt;ImportGroup Label=&quot;ExtensionTargets&quot;&gt;
</span><span class="cx">   &lt;/ImportGroup&gt;
</span><del>-&lt;/Project&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+&lt;/Project&gt;
</ins></span></pre></div>
<a id="trunkToolsDumpRenderTreeDumpRenderTreevcxprojTestNetscapePluginTestNetscapePluginvcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj.filters (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj.filters        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Tools/DumpRenderTree/DumpRenderTree.vcxproj/TestNetscapePlugin/TestNetscapePlugin.vcxproj.filters        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -71,6 +71,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\ToStringAndValueOfObject.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Tests&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\URLRedirect.cpp&quot;&gt;
+      &lt;Filter&gt;Tests&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\..\TestNetscapePlugIn\Tests\win\CallJSThatDestroysPlugin.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Tests\win&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -136,4 +139,4 @@
</span><span class="cx">       &lt;Filter&gt;Resources&lt;/Filter&gt;
</span><span class="cx">     &lt;/ResourceCompile&gt;
</span><span class="cx">   &lt;/ItemGroup&gt;
</span><del>-&lt;/Project&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+&lt;/Project&gt;
</ins></span></pre></div>
<a id="trunkToolsDumpRenderTreeDumpRenderTreexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -24,6 +24,7 @@
</span><span class="cx"> /* End PBXAggregateTarget section */
</span><span class="cx"> 
</span><span class="cx"> /* Begin PBXBuildFile section */
</span><ins>+                00F048541A0C3C9A000244DB /* URLRedirect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00F048531A0C3C9A000244DB /* URLRedirect.cpp */; };
</ins><span class="cx">                 0F37A4A711E6628700275F54 /* PluginObjectMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F37A4A611E6628700275F54 /* PluginObjectMac.mm */; };
</span><span class="cx">                 0F37A4AA11E6629100275F54 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5A752A108AF5D1F00138E45 /* QuartzCore.framework */; };
</span><span class="cx">                 141BF435096A455900E0753C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9335435F03D75502008635CE /* WebKit.framework */; };
</span><span class="lines">@@ -200,6 +201,7 @@
</span><span class="cx"> /* End PBXCopyFilesBuildPhase section */
</span><span class="cx"> 
</span><span class="cx"> /* Begin PBXFileReference section */
</span><ins>+                00F048531A0C3C9A000244DB /* URLRedirect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLRedirect.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F37A4A611E6628700275F54 /* PluginObjectMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PluginObjectMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 141BF233096A44CF00E0753C /* TestNetscapePlugIn.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestNetscapePlugIn.plugin; sourceTree = BUILT_PRODUCTS_DIR; };
</span><span class="cx">                 141BF447096A45C800E0753C /* PluginObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PluginObject.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -561,6 +563,7 @@
</span><span class="cx">                                 1A1E4296141141C400388758 /* PrivateBrowsing.cpp */,
</span><span class="cx">                                 5106803D15CC7B10001A8A23 /* SlowNPPNew.cpp */,
</span><span class="cx">                                 1A4CCD4E171375A300981040 /* ToStringAndValueOfObject.cpp */,
</span><ins>+                                00F048531A0C3C9A000244DB /* URLRedirect.cpp */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = Tests;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -924,6 +927,7 @@
</span><span class="cx">                                 5106803E15CC7B10001A8A23 /* SlowNPPNew.cpp in Sources */,
</span><span class="cx">                                 1A14C8A51406DE0400B254F7 /* SupportsCarbonEventModel.cpp in Sources */,
</span><span class="cx">                                 1AC6C84B0D07638600CD3161 /* TestObject.cpp in Sources */,
</span><ins>+                                00F048541A0C3C9A000244DB /* URLRedirect.cpp in Sources */,
</ins><span class="cx">                         );
</span><span class="cx">                         runOnlyForDeploymentPostprocessing = 0;
</span><span class="cx">                 };
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeTestNetscapePlugInCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Tools/DumpRenderTree/TestNetscapePlugIn/CMakeLists.txt        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx">     ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/PluginScriptableObjectOverridesAllProperties.cpp
</span><span class="cx">     ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/PrivateBrowsing.cpp
</span><span class="cx">     ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/ToStringAndValueOfObject.cpp
</span><ins>+    ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/URLRedirect.cpp
</ins><span class="cx">     ${WEBKIT_TESTNETSCAPEPLUGIN_DIR}/Tests/x11/CallInvalidateRectWithNullNPPArgument.cpp
</span><span class="cx"> )
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeTestNetscapePlugInPluginTestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -136,6 +136,11 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginTest::NPP_URLRedirectNotify(const char*, int32_t, void* notifyData)
+{
+    NPN_URLRedirectResponse(notifyData, true);
+}
+
</ins><span class="cx"> NPError PluginTest::NPP_GetValue(NPPVariable variable, void *value)
</span><span class="cx"> {
</span><span class="cx">     // We don't know anything about plug-in values so just return NPERR_GENERIC_ERROR.
</span><span class="lines">@@ -159,6 +164,11 @@
</span><span class="cx">     return browser-&gt;geturlnotify(m_npp, url, target, notifyData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+NPError PluginTest::NPN_PostURLNotify(const char *url, const char *target, uint32_t len, const char* buf, NPBool file, void *notifyData)
+{
+    return browser-&gt;posturlnotify(m_npp, url, target, len, buf, file, notifyData);
+}
+
</ins><span class="cx"> NPError PluginTest::NPN_GetValue(NPNVariable variable, void* value)
</span><span class="cx"> {
</span><span class="cx">     return browser-&gt;getvalue(m_npp, variable, value);
</span><span class="lines">@@ -231,6 +241,11 @@
</span><span class="cx">     browser-&gt;releasevariantvalue(variant);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginTest::NPN_URLRedirectResponse(void* notifyData, NPBool allow)
+{
+    browser-&gt;urlredirectresponse(m_npp, notifyData, allow);
+}
+
</ins><span class="cx"> #ifdef XP_MACOSX
</span><span class="cx"> bool PluginTest::NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeTestNetscapePlugInPluginTesth"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -68,12 +68,14 @@
</span><span class="cx">     
</span><span class="cx">     virtual int16_t NPP_HandleEvent(void* event);
</span><span class="cx">     virtual bool NPP_URLNotify(const char* url, NPReason, void* notifyData);
</span><ins>+    virtual void NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData);
</ins><span class="cx">     virtual NPError NPP_GetValue(NPPVariable, void* value);
</span><span class="cx">     virtual NPError NPP_SetValue(NPNVariable, void *value);
</span><span class="cx"> 
</span><span class="cx">     // NPN functions.
</span><span class="cx">     NPError NPN_GetURL(const char* url, const char* target);
</span><span class="cx">     NPError NPN_GetURLNotify(const char* url, const char* target, void* notifyData);
</span><ins>+    NPError NPN_PostURLNotify(const char *url, const char *target, uint32_t len, const char* buf, NPBool file, void *notifyData);
</ins><span class="cx">     NPError NPN_GetValue(NPNVariable, void* value);
</span><span class="cx">     void NPN_InvalidateRect(NPRect* invalidRect);
</span><span class="cx">     bool NPN_Invoke(NPObject *, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);
</span><span class="lines">@@ -91,6 +93,7 @@
</span><span class="cx">     void NPN_ReleaseObject(NPObject*);
</span><span class="cx">     bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName);
</span><span class="cx">     void NPN_ReleaseVariantValue(NPVariant*);
</span><ins>+    void NPN_URLRedirectResponse(void* notifyData, NPBool allow);
</ins><span class="cx"> 
</span><span class="cx"> #ifdef XP_MACOSX
</span><span class="cx">     bool NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeTestNetscapePlugInTestsURLRedirectcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp (0 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp                                (rev 0)
+++ trunk/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/URLRedirect.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -0,0 +1,167 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#include &quot;PluginTest.h&quot;
+
+#include &lt;string.h&gt;
+
+using namespace std;
+
+class URLRedirect : public PluginTest {
+public:
+    URLRedirect(NPP npp, const string&amp; identifier)
+        : PluginTest(npp, identifier)
+    {
+    }
+
+    struct Redirect {
+        int redirectsRemaining;
+        bool async;
+        bool hasFired;
+    };
+
+    std::map&lt;void*, Redirect&gt; redirects;
+
+private:
+    // This is the test object.
+    class TestObject : public Object&lt;TestObject&gt; { };
+
+    // This is the scriptable object. It has a single &quot;testObject&quot; property and an &quot;evaluate&quot; function.
+    class ScriptableObject : public Object&lt;ScriptableObject&gt; {
+    public:
+        bool hasMethod(NPIdentifier methodName)
+        {
+            return identifierIs(methodName, &quot;get&quot;) || identifierIs(methodName, &quot;getAsync&quot;) || identifierIs(methodName, &quot;serviceAsync&quot;);
+        }
+
+        bool get(const NPVariant* args, uint32_t argCount, NPVariant* result, bool async)
+        {
+            if (argCount != 3 || !NPVARIANT_IS_STRING(args[0]) || !(NPVARIANT_IS_BOOLEAN(args[1]) || NPVARIANT_IS_DOUBLE(args[1]) || NPVARIANT_IS_INT32(args[1])) || !NPVARIANT_IS_STRING(args[2]))
+                return false;
+
+            const NPString* notifyString = &amp;NPVARIANT_TO_STRING(args[2]);
+            basic_string&lt;NPUTF8&gt; notify(notifyString-&gt;UTF8Characters, notifyString-&gt;UTF8Length);
+            NPIdentifier notifyMethod = pluginTest()-&gt;NPN_GetStringIdentifier(notify.c_str());
+
+            Redirect&amp; redirect = static_cast&lt;URLRedirect*&gt;(pluginTest())-&gt;redirects[reinterpret_cast&lt;void*&gt;(notifyMethod)];
+            if (NPVARIANT_IS_DOUBLE(args[1]))
+                redirect.redirectsRemaining = NPVARIANT_TO_DOUBLE(args[1]);
+            else if (NPVARIANT_IS_INT32(args[1]))
+                redirect.redirectsRemaining = NPVARIANT_TO_INT32(args[1]);
+            else if (NPVARIANT_IS_BOOLEAN(args[1]))
+                redirect.redirectsRemaining = NPVARIANT_TO_BOOLEAN(args[1]);
+            redirect.async = async;
+            redirect.hasFired = true;
+
+            const NPString* urlString = &amp;NPVARIANT_TO_STRING(args[0]);
+            basic_string&lt;NPUTF8&gt; url(urlString-&gt;UTF8Characters, urlString-&gt;UTF8Length);
+
+            pluginTest()-&gt;NPN_GetURLNotify(url.c_str(), 0, reinterpret_cast&lt;void*&gt;(notifyMethod));
+
+            VOID_TO_NPVARIANT(*result);
+            return true;
+        }
+
+        bool serviceAsync(const NPVariant* args, uint32_t argCount, NPVariant* result)
+        {
+            if (argCount)
+                return false;
+
+            NPBool seen = 0;
+            URLRedirect* plugin = static_cast&lt;URLRedirect*&gt;(pluginTest());
+            for (auto&amp; redirect : plugin-&gt;redirects) {
+                if (redirect.second.hasFired)
+                    continue;
+                redirect.second.hasFired = true;
+                plugin-&gt;NPN_URLRedirectResponse(redirect.first, redirect.second.redirectsRemaining);
+                if (redirect.second.redirectsRemaining)
+                    --redirect.second.redirectsRemaining;
+                seen = 1;
+            }
+
+            BOOLEAN_TO_NPVARIANT(seen, *result);
+            return true;
+        }
+
+        bool invoke(NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result)
+        {
+            if (identifierIs(methodName, &quot;get&quot;))
+                return get(args, argCount, result, false);
+
+            if (identifierIs(methodName, &quot;getAsync&quot;))
+                return get(args, argCount, result, true);
+
+            if (identifierIs(methodName, &quot;serviceAsync&quot;))
+                return serviceAsync(args, argCount, result);
+
+            return false;
+        }
+    };
+
+    virtual NPError NPP_GetValue(NPPVariable variable, void *value)
+    {
+        if (variable != NPPVpluginScriptableNPObject)
+            return NPERR_GENERIC_ERROR;
+
+        *(NPObject**)value = ScriptableObject::create(this);
+
+        return NPERR_NO_ERROR;
+    }
+
+    virtual bool NPP_URLNotify(const char* url, NPReason reason, void* notifyData)
+    {
+        NPVariant args[2];
+
+        NPObject* windowScriptObject;
+        NPN_GetValue(NPNVWindowNPObject, &amp;windowScriptObject);
+
+        NPIdentifier callbackIdentifier = notifyData;
+
+        INT32_TO_NPVARIANT(reason, args[0]);
+        STRINGZ_TO_NPVARIANT(url, args[1]);
+
+        NPVariant browserResult;
+        if (NPN_Invoke(windowScriptObject, callbackIdentifier, args, 2, &amp;browserResult))
+            NPN_ReleaseVariantValue(&amp;browserResult);
+
+        return true;
+    }
+
+    virtual void NPP_URLRedirectNotify(const char*, int32_t, void* notifyData)
+    {
+        Redirect&amp; redirect = redirects[notifyData];
+        if (redirect.async) {
+            redirect.hasFired = false;
+            return;
+        }
+
+        NPN_URLRedirectResponse(notifyData, redirect.redirectsRemaining);
+        if (redirect.redirectsRemaining)
+            --redirect.redirectsRemaining;
+    }
+};
+
+static PluginTest::Register&lt;URLRedirect&gt; urlRedirect(&quot;url-redirect&quot;);
+
</ins></span></pre></div>
<a id="trunkToolsDumpRenderTreeTestNetscapePlugInmaincpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp (187885 => 187886)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp        2015-08-04 20:46:06 UTC (rev 187885)
+++ trunk/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp        2015-08-04 20:48:47 UTC (rev 187886)
</span><span class="lines">@@ -116,6 +116,7 @@
</span><span class="cx">     pluginFuncs-&gt;print = NPP_Print;
</span><span class="cx">     pluginFuncs-&gt;event = NPP_HandleEvent;
</span><span class="cx">     pluginFuncs-&gt;urlnotify = NPP_URLNotify;
</span><ins>+    pluginFuncs-&gt;urlredirectnotify = NPP_URLRedirectNotify;
</ins><span class="cx">     pluginFuncs-&gt;getvalue = NPP_GetValue;
</span><span class="cx">     pluginFuncs-&gt;setvalue = NPP_SetValue;
</span><span class="cx">     
</span><span class="lines">@@ -799,6 +800,12 @@
</span><span class="cx">     handleCallback(obj, url, reason, notifyData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void NPP_URLRedirectNotify(NPP instance, const char *url, int32_t status, void *notifyData)
+{
+    PluginObject* obj = static_cast&lt;PluginObject*&gt;(instance-&gt;pdata);
+    obj-&gt;pluginTest-&gt;NPP_URLRedirectNotify(url, status, notifyData);
+}
+
</ins><span class="cx"> NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
</span><span class="cx"> {
</span><span class="cx"> #ifdef XP_UNIX
</span></span></pre>
</div>
</div>

</body>
</html>