<!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>[204128] 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/204128">204128</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-08-04 11:48:16 -0700 (Thu, 04 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Temporary redirected m3u8 streaming stopped working.
https://bugs.webkit.org/show_bug.cgi?id=160472
rdar://problem/27592694

Patch by Jeremy Jones &lt;jeremyj@apple.com&gt; on 2016-08-04
Reviewed by Alex Christensen.

Source/WebCore:

Test: http/tests/media/hls/hls-redirect.html

The change for https://trac.webkit.org/changeset/202466 hides knowledge of the temporary redirected URL from
WebCoreNSURLSession clients. MPEG playlists (e.g. .m3u8) can contain paths relative to the redirected URL.

This change exposes the redirected URL for MPEG playlists.

* platform/MIMETypeRegistry.cpp:
(WebCore::initializeMPEGPlaylistMIMETypes): Added.
(WebCore::initializeMIMETypeRegistry):
(WebCore::MIMETypeRegistry::isMPEGPlaylistMIMEType): Added.
* platform/MIMETypeRegistry.h:
* platform/network/cocoa/WebCoreNSURLSession.mm:
(-[WebCoreNSURLSessionDataTask resource:receivedResponse:]): Add MPEG playlist condition.
(-[WebCoreNSURLSessionDataTask resource:receivedRedirect:request:]): Add MPEG playlist condition.

LayoutTests:

This tests that m3u8 files can be loaded when going through a temporary redirect.

* http/tests/media/hls/hls-redirect-expected.txt: Added.
* http/tests/media/hls/hls-redirect.html: 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="#trunkSourceWebCoreplatformMIMETypeRegistrycpp">trunk/Source/WebCore/platform/MIMETypeRegistry.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformMIMETypeRegistryh">trunk/Source/WebCore/platform/MIMETypeRegistry.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcocoaWebCoreNSURLSessionmm">trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestsmediahlshlsredirectexpectedtxt">trunk/LayoutTests/http/tests/media/hls/hls-redirect-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsmediahlshlsredirecthtml">trunk/LayoutTests/http/tests/media/hls/hls-redirect.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (204127 => 204128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-08-04 18:07:45 UTC (rev 204127)
+++ trunk/LayoutTests/ChangeLog        2016-08-04 18:48:16 UTC (rev 204128)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-08-04  Jeremy Jones  &lt;jeremyj@apple.com&gt;
+
+        Temporary redirected m3u8 streaming stopped working.
+        https://bugs.webkit.org/show_bug.cgi?id=160472
+        rdar://problem/27592694
+
+        Reviewed by Alex Christensen.
+
+        This tests that m3u8 files can be loaded when going through a temporary redirect.
+
+        * http/tests/media/hls/hls-redirect-expected.txt: Added.
+        * http/tests/media/hls/hls-redirect.html: Added.
+
</ins><span class="cx"> 2016-08-04  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Content Blocker cannot block WebSocket connections
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsmediahlshlsredirectexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/media/hls/hls-redirect-expected.txt (0 => 204128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/media/hls/hls-redirect-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/media/hls/hls-redirect-expected.txt        2016-08-04 18:48:16 UTC (rev 204128)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+
+load metadata OK
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsmediahlshlsredirecthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/media/hls/hls-redirect.html (0 => 204128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/media/hls/hls-redirect.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/media/hls/hls-redirect.html        2016-08-04 18:48:16 UTC (rev 204128)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=../../media-resources/video-test.js&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;video src=&quot;http://127.0.0.1:8000/resources/redirect.php?code=307&amp;url=http%3A%2F%2Flocalhost%3A8000/media/resources/hls/test-vod.m3u8&quot; onloadedmetadata=&quot;logResult(true, 'load metadata'); endTest()&quot; onerror=&quot;failTest('load error')&quot;&gt;&lt;/video&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (204127 => 204128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-08-04 18:07:45 UTC (rev 204127)
+++ trunk/Source/WebCore/ChangeLog        2016-08-04 18:48:16 UTC (rev 204128)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2016-08-04  Jeremy Jones  &lt;jeremyj@apple.com&gt;
+
+        Temporary redirected m3u8 streaming stopped working.
+        https://bugs.webkit.org/show_bug.cgi?id=160472
+        rdar://problem/27592694
+
+        Reviewed by Alex Christensen.
+
+        Test: http/tests/media/hls/hls-redirect.html
+
+        The change for https://trac.webkit.org/changeset/202466 hides knowledge of the temporary redirected URL from 
+        WebCoreNSURLSession clients. MPEG playlists (e.g. .m3u8) can contain paths relative to the redirected URL.
+
+        This change exposes the redirected URL for MPEG playlists.
+
+        * platform/MIMETypeRegistry.cpp:
+        (WebCore::initializeMPEGPlaylistMIMETypes): Added.
+        (WebCore::initializeMIMETypeRegistry):
+        (WebCore::MIMETypeRegistry::isMPEGPlaylistMIMEType): Added.
+        * platform/MIMETypeRegistry.h:
+        * platform/network/cocoa/WebCoreNSURLSession.mm:
+        (-[WebCoreNSURLSessionDataTask resource:receivedResponse:]): Add MPEG playlist condition.
+        (-[WebCoreNSURLSessionDataTask resource:receivedRedirect:request:]): Add MPEG playlist condition.
+
</ins><span class="cx"> 2016-08-04  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Content Blocker cannot block WebSocket connections
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformMIMETypeRegistrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/MIMETypeRegistry.cpp (204127 => 204128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/MIMETypeRegistry.cpp        2016-08-04 18:07:45 UTC (rev 204127)
+++ trunk/Source/WebCore/platform/MIMETypeRegistry.cpp        2016-08-04 18:48:16 UTC (rev 204128)
</span><span class="lines">@@ -146,6 +146,7 @@
</span><span class="cx"> static HashSet&lt;String, ASCIICaseInsensitiveHash&gt;* supportedJavaScriptMIMETypes;
</span><span class="cx"> static HashSet&lt;String, ASCIICaseInsensitiveHash&gt;* supportedNonImageMIMETypes;
</span><span class="cx"> static HashSet&lt;String, ASCIICaseInsensitiveHash&gt;* supportedMediaMIMETypes;
</span><ins>+static HashSet&lt;String, ASCIICaseInsensitiveHash&gt;* mpegPlaylistMIMETypes;
</ins><span class="cx"> static HashSet&lt;String, ASCIICaseInsensitiveHash&gt;* pdfMIMETypes;
</span><span class="cx"> static HashSet&lt;String, ASCIICaseInsensitiveHash&gt;* pdfAndPostScriptMIMETypes;
</span><span class="cx"> static HashSet&lt;String, ASCIICaseInsensitiveHash&gt;* unsupportedTextMIMETypes;
</span><span class="lines">@@ -301,6 +302,22 @@
</span><span class="cx">         supportedJavaScriptMIMETypes-&gt;add(type);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void initializeMPEGPlaylistMIMETypes()
+{
+    const char* const types[] = {
+        &quot;application/vnd.apple.mpegurl&quot;,
+        &quot;application/mpegurl&quot;,
+        &quot;application/x-mpegurl&quot;,
+        &quot;audio/mpegurl&quot;,
+        &quot;audio/x-mpegurl&quot;,
+        &quot;audio/mpegurl&quot;,
+        &quot;audio/x-mpegurl&quot;
+    };
+
+    for (auto&amp; type : types)
+        mpegPlaylistMIMETypes-&gt;add(type);
+}
+
</ins><span class="cx"> static void initializePDFMIMETypes()
</span><span class="cx"> {
</span><span class="cx">     const char* const types[] = {
</span><span class="lines">@@ -455,6 +472,9 @@
</span><span class="cx">     supportedImageMIMETypes = new HashSet&lt;String, ASCIICaseInsensitiveHash&gt;;
</span><span class="cx">     initializeSupportedImageMIMETypes();
</span><span class="cx"> 
</span><ins>+    mpegPlaylistMIMETypes = new HashSet&lt;String, ASCIICaseInsensitiveHash&gt;;
+    initializeMPEGPlaylistMIMETypes();
+
</ins><span class="cx">     pdfMIMETypes = new HashSet&lt;String, ASCIICaseInsensitiveHash&gt;;
</span><span class="cx">     initializePDFMIMETypes();
</span><span class="cx"> 
</span><span class="lines">@@ -553,6 +573,15 @@
</span><span class="cx">         || mimeType.startsWith(&quot;application/x-java-vm&quot;, false);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool MIMETypeRegistry::isMPEGPlaylistMIMEType(const String&amp; mimeType)
+{
+    if (mimeType.isEmpty())
+        return false;
+    if (!mpegPlaylistMIMETypes)
+        initializeMIMETypeRegistry();
+    return mpegPlaylistMIMETypes-&gt;contains(mimeType);
+}
+
</ins><span class="cx"> bool MIMETypeRegistry::isPDFOrPostScriptMIMEType(const String&amp; mimeType)
</span><span class="cx"> {
</span><span class="cx">     if (mimeType.isEmpty())
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformMIMETypeRegistryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/MIMETypeRegistry.h (204127 => 204128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/MIMETypeRegistry.h        2016-08-04 18:07:45 UTC (rev 204127)
+++ trunk/Source/WebCore/platform/MIMETypeRegistry.h        2016-08-04 18:48:16 UTC (rev 204128)
</span><span class="lines">@@ -76,6 +76,9 @@
</span><span class="cx">     // Check to see if a MIME type is a plugin implemented by the browser.
</span><span class="cx">     static bool isApplicationPluginMIMEType(const String&amp; mimeType);
</span><span class="cx"> 
</span><ins>+    // Check to see if a MIME type is one of the MPEG playlists types.
+    static bool isMPEGPlaylistMIMEType(const String&amp; mimeType);
+
</ins><span class="cx">     // Check to see if a MIME type is one of the common PDF/PS types.
</span><span class="cx">     WEBCORE_EXPORT static bool isPDFOrPostScriptMIMEType(const String&amp; mimeType);
</span><span class="cx">     static bool isPDFMIMEType(const String&amp; mimeType);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcocoaWebCoreNSURLSessionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm (204127 => 204128)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm        2016-08-04 18:07:45 UTC (rev 204127)
+++ trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm        2016-08-04 18:48:16 UTC (rev 204128)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101100
</span><span class="cx"> 
</span><span class="cx"> #import &quot;CachedResourceRequest.h&quot;
</span><ins>+#import &quot;MIMETypeRegistry.h&quot;
</ins><span class="cx"> #import &quot;PlatformMediaResourceLoader.h&quot;
</span><span class="cx"> #import &quot;SecurityOrigin.h&quot;
</span><span class="cx"> #import &quot;SubresourceLoader.h&quot;
</span><span class="lines">@@ -586,9 +587,20 @@
</span><span class="cx">         // and use that URL for all future requests for the same piece of media. This breaks
</span><span class="cx">         // certain features of CORS, as well as being against the HTTP spec in the case of
</span><span class="cx">         // non-permanent redirects.
</span><del>-        auto responseData = response.crossThreadData();
-        responseData.url = URL(self.currentRequest.URL);
-        strongResponse = ResourceResponseBase::fromCrossThreadData(WTFMove(responseData)).nsURLResponse();
</del><ins>+
+        // Exclude MPEG Playlists since these require the redirected URL as the base URL
+        // for relative paths.
+        String mimeType = response.nsURLResponse().MIMEType;
+        if (mimeType.isEmpty() || mimeType == &quot;application/octet-stream&quot; || mimeType == &quot;text/plain&quot;) {
+            String extension = response.nsURLResponse().URL.pathExtension;
+            mimeType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
+
+        }
+        if (!MIMETypeRegistry::isMPEGPlaylistMIMEType(mimeType)) {
+            auto responseData = response.crossThreadData();
+            responseData.url = URL(self.currentRequest.URL);
+            strongResponse = ResourceResponseBase::fromCrossThreadData(WTFMove(responseData)).nsURLResponse();
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     RetainPtr&lt;WebCoreNSURLSessionDataTask&gt; strongSelf { self };
</span><span class="lines">@@ -658,9 +670,19 @@
</span><span class="cx">     // FIXME(&lt;rdar://problem/27000361&gt;):
</span><span class="cx">     // Do not update the current request if the redirect is temporary; use this
</span><span class="cx">     // current request during responseReceieved: to work around a CoreMedia bug.
</span><del>-    if (response.httpStatusCode() != 302 &amp;&amp; response.httpStatusCode() != 307)
-        self.currentRequest = [NSURLRequest requestWithURL:request.url()];
</del><span class="cx"> 
</span><ins>+    // Exclude MPEG Playlists since these require the redirected URL as the base URL
+    // for relative paths.
+    if (response.httpStatusCode() != 302 &amp;&amp; response.httpStatusCode() != 307) {
+        String mimeType = response.nsURLResponse().MIMEType;
+        if (mimeType.isEmpty() || mimeType == &quot;application/octet-stream&quot; || mimeType == &quot;text/plain&quot;) {
+            String extension = response.nsURLResponse().URL.pathExtension;
+            mimeType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
+        }
+        if (!MIMETypeRegistry::isMPEGPlaylistMIMEType(mimeType))
+            self.currentRequest = [NSURLRequest requestWithURL:request.url()];
+    }
+
</ins><span class="cx">     [self.session updateHasSingleSecurityOrigin:SecurityOrigin::create(request.url())];
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>