<!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>[195764] 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/195764">195764</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2016-01-28 11:17:17 -0800 (Thu, 28 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Custom protocol loading through AVFoundation does not support byte-range requests.
https://bugs.webkit.org/show_bug.cgi?id=152919
&lt;rdar://problem/23664657&gt;

Reviewed by Alex Christensen.

Source/WebCore:

Tests: http/tests/xmlhttprequest/blob-request-byte-range.html
       TestWebkitAPI/Tests/WebCore/ParsedContentRange.cpp

When loading data through the AVAssetResourceLoaderDelegateProtocol, AVFoundation will issue
requests for specific byte-ranges by adding a &quot;Range:&quot; HTTP header to the NSURLRequest it
passes to the delegate.  WebCore ignores this header, loads the entire resource, and replies
to the callback with the requested subset of the entire resource.

For byte-range requests near the end of a resource, this is inefficient, as the entire
resource up to, and including, the requested range must be loaded before any data can be
returned. Explicitly handle byte-range requests by creating a CachedResourceRequest with the
underlying NSURLRequest (which includes the &quot;Range:&quot; header) rather than just the request's
URL. BlobResourceHandle must be modified to add the &quot;Content-Range:&quot; response header to the
ResourceResponse.

To facilitate both generating and parsing the &quot;Content-Range:&quot; header, add a new
ParsedContentRange class for use by ResourceResponse and its clients. This class provides
methods both for parsing a &quot;Content-Range&quot; header value string, and for generating the
header value from elemental values.

* platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:
(WebCore::WebCoreAVFResourceLoader::startLoading):
(WebCore::WebCoreAVFResourceLoader::responseReceived):
(WebCore::WebCoreAVFResourceLoader::fulfillRequestWithResource):
* platform/network/BlobResourceHandle.cpp:
(WebCore::BlobResourceHandle::BlobResourceHandle):
(WebCore::BlobResourceHandle::didGetSize):
(WebCore::BlobResourceHandle::seek):
(WebCore::BlobResourceHandle::notifyResponseOnSuccess):
* platform/network/BlobResourceHandle.h:
* platform/network/HTTPHeaderNames.in:
* platform/network/ParsedContentRange.cpp: Added.
(WebCore::areContentRangeValuesValid):
(WebCore::parseContentRange):
(WebCore::ParsedContentRange::ParsedContentRange):
(WebCore::ParsedContentRange::headerValue):
* platform/network/ParsedContentRange.h: Added.
(WebCore::ParsedContentRange::ParsedContentRange):
(WebCore::ParsedContentRange::isValid):
(WebCore::ParsedContentRange::firstBytePosition):
(WebCore::ParsedContentRange::lastBytePosition):
(WebCore::ParsedContentRange::instanceLength):
* platform/network/ResourceResponseBase.cpp:
(WebCore::ResourceResponseBase::updateHeaderParsedState):
(WebCore::parseContentRangeInHeader):
(WebCore::ResourceResponseBase::contentRange):
* platform/network/ResourceResponseBase.h:
* CMakeLists.txt:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:

Tools:

Add tests for new ParsedContntRange class.

* TestWebKitAPI/PlatformWin.cmake:
* TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj:
* TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp: Added.
(TestWebKitAPI::TEST):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcWebCoreAVFResourceLoadermm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkBlobResourceHandlecpp">trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkBlobResourceHandleh">trunk/Source/WebCore/platform/network/BlobResourceHandle.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPHeaderNamesin">trunk/Source/WebCore/platform/network/HTTPHeaderNames.in</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceResponseBasecpp">trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceResponseBaseh">trunk/Source/WebCore/platform/network/ResourceResponseBase.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPIPlatformWincmake">trunk/Tools/TestWebKitAPI/PlatformWin.cmake</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIvcxprojTestWebKitAPIvcxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIvcxprojTestWebKitAPIvcxprojfilters">trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestsxmlhttprequestblobrequestbyterangeexpectedtxt">trunk/LayoutTests/http/tests/xmlhttprequest/blob-request-byte-range-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsxmlhttprequestblobrequestbyterangehtml">trunk/LayoutTests/http/tests/xmlhttprequest/blob-request-byte-range.html</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkParsedContentRangecpp">trunk/Source/WebCore/platform/network/ParsedContentRange.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkParsedContentRangeh">trunk/Source/WebCore/platform/network/ParsedContentRange.h</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebCoreParsedContentRangecpp">trunk/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestshttptestsxmlhttprequestblobrequestbyterangeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/xmlhttprequest/blob-request-byte-range-expected.txt (0 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/xmlhttprequest/blob-request-byte-range-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/blob-request-byte-range-expected.txt        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+Test an XMLHttpRequest of a Blob URL requesting a byte-range responds appropriately.
+
+PASS: &quot;req.status&quot; == &quot;206&quot;
+PASS: &quot;req.getResponseHeader(&quot;Content-Range&quot;)&quot; == &quot;bytes 1-2/4&quot;
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsxmlhttprequestblobrequestbyterangehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/xmlhttprequest/blob-request-byte-range.html (0 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/xmlhttprequest/blob-request-byte-range.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/blob-request-byte-range.html        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+&lt;p&gt;Test an XMLHttpRequest of a Blob URL requesting a byte-range responds appropriately.&lt;/p&gt;
+&lt;pre id=&quot;console&quot;&gt;&lt;/pre&gt;
+&lt;script&gt;
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function log(text)
+{
+    var console = document.getElementById('console');
+    console.appendChild(document.createTextNode(text + '\n'));
+}
+
+function test(expect, actual)
+{
+    var result = eval(actual);
+    if (expect == result)
+        log(`PASS: &quot;${ actual }&quot; == &quot;${ expect }&quot;`);
+    else
+        log(`FAIL: &quot;${ actual }&quot; EXPECT &quot;${ expect }&quot; GOT &quot;${ result }&quot;`);
+}
+
+var array = new Int8Array([0, 1, 2, 3]);
+var blob = new Blob(array);
+var url = URL.createObjectURL(blob);
+
+var req = new XMLHttpRequest;
+req.responseType = 'blob';
+req.open('GET', url);
+req.setRequestHeader('Range', 'bytes=1-2');
+req.onreadystatechange = function() {
+    if (req.readyState == 4) {
+        test(206, 'req.status');
+        test('bytes 1-2/4', 'req.getResponseHeader(&quot;Content-Range&quot;)');
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }
+};
+req.send();
+
+&lt;/script&gt;
+&lt;/body&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -2331,6 +2331,7 @@
</span><span class="cx">     platform/network/HTTPParsers.cpp
</span><span class="cx">     platform/network/MIMEHeader.cpp
</span><span class="cx">     platform/network/NetworkStateNotifier.cpp
</span><ins>+    platform/network/ParsedContentRange.cpp
</ins><span class="cx">     platform/network/ParsedContentType.cpp
</span><span class="cx">     platform/network/ProtectionSpaceBase.cpp
</span><span class="cx">     platform/network/ProxyServer.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/ChangeLog        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -1,3 +1,63 @@
</span><ins>+2016-01-08  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        Custom protocol loading through AVFoundation does not support byte-range requests.
+        https://bugs.webkit.org/show_bug.cgi?id=152919
+        &lt;rdar://problem/23664657&gt;
+
+        Reviewed by Alex Christensen.
+
+        Tests: http/tests/xmlhttprequest/blob-request-byte-range.html
+               TestWebkitAPI/Tests/WebCore/ParsedContentRange.cpp
+
+        When loading data through the AVAssetResourceLoaderDelegateProtocol, AVFoundation will issue
+        requests for specific byte-ranges by adding a &quot;Range:&quot; HTTP header to the NSURLRequest it
+        passes to the delegate.  WebCore ignores this header, loads the entire resource, and replies
+        to the callback with the requested subset of the entire resource.
+
+        For byte-range requests near the end of a resource, this is inefficient, as the entire
+        resource up to, and including, the requested range must be loaded before any data can be
+        returned. Explicitly handle byte-range requests by creating a CachedResourceRequest with the
+        underlying NSURLRequest (which includes the &quot;Range:&quot; header) rather than just the request's
+        URL. BlobResourceHandle must be modified to add the &quot;Content-Range:&quot; response header to the
+        ResourceResponse. 
+
+        To facilitate both generating and parsing the &quot;Content-Range:&quot; header, add a new
+        ParsedContentRange class for use by ResourceResponse and its clients. This class provides
+        methods both for parsing a &quot;Content-Range&quot; header value string, and for generating the
+        header value from elemental values.
+
+        * platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:
+        (WebCore::WebCoreAVFResourceLoader::startLoading):
+        (WebCore::WebCoreAVFResourceLoader::responseReceived):
+        (WebCore::WebCoreAVFResourceLoader::fulfillRequestWithResource):
+        * platform/network/BlobResourceHandle.cpp:
+        (WebCore::BlobResourceHandle::BlobResourceHandle):
+        (WebCore::BlobResourceHandle::didGetSize):
+        (WebCore::BlobResourceHandle::seek):
+        (WebCore::BlobResourceHandle::notifyResponseOnSuccess):
+        * platform/network/BlobResourceHandle.h:
+        * platform/network/HTTPHeaderNames.in:
+        * platform/network/ParsedContentRange.cpp: Added.
+        (WebCore::areContentRangeValuesValid):
+        (WebCore::parseContentRange):
+        (WebCore::ParsedContentRange::ParsedContentRange):
+        (WebCore::ParsedContentRange::headerValue):
+        * platform/network/ParsedContentRange.h: Added.
+        (WebCore::ParsedContentRange::ParsedContentRange):
+        (WebCore::ParsedContentRange::isValid):
+        (WebCore::ParsedContentRange::firstBytePosition):
+        (WebCore::ParsedContentRange::lastBytePosition):
+        (WebCore::ParsedContentRange::instanceLength):
+        * platform/network/ResourceResponseBase.cpp:
+        (WebCore::ResourceResponseBase::updateHeaderParsedState):
+        (WebCore::parseContentRangeInHeader):
+        (WebCore::ResourceResponseBase::contentRange):
+        * platform/network/ResourceResponseBase.h:
+        * CMakeLists.txt:
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj:
+
</ins><span class="cx"> 2016-01-28  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Storage interface's attributes / operations should be enumerable
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -8886,6 +8886,7 @@
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\platform\network\ParsedContentRange.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\platform\network\ParsedContentType.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\platform\network\ProtectionSpaceBase.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\platform\network\ProxyServer.cpp&quot; /&gt;
</span><span class="lines">@@ -21352,6 +21353,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\network\NetworkingContext.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\network\NetworkStateNotifier.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\network\NetworkStorageSession.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\platform\network\ParsedContentRange.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\platform\network\ParsedContentType.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\network\PlatformCookieJar.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\network\ProtectionSpace.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -1772,6 +1772,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\platform\network\NetworkStorageSessionStub.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;platform\network&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\platform\network\ParsedContentRange.cpp&quot;&gt;
+      &lt;Filter&gt;platform\network&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\platform\network\ParsedContentType.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;platform\network&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -8779,6 +8782,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\platform\network\NetworkStorageSession.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;platform\network&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\platform\network\ParsedContenRange.h&quot;&gt;
+      &lt;Filter&gt;platform\network&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\platform\network\ParsedContentType.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;platform\network&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -6097,6 +6097,8 @@
</span><span class="cx">                 CDC979F51C498C0900DB50D4 /* WebCoreNSErrorExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC979F31C498C0900DB50D4 /* WebCoreNSErrorExtras.h */; };
</span><span class="cx">                 CDCA82961679100F00875714 /* TextTrackRepresentationIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDCA82941679100F00875714 /* TextTrackRepresentationIOS.mm */; };
</span><span class="cx">                 CDCA98EB18B2C8EB00C12FF9 /* CDMPrivateMediaPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCA98EA18B2C8EB00C12FF9 /* CDMPrivateMediaPlayer.cpp */; };
</span><ins>+                CDCD41E71C3DDB0900965D99 /* ParsedContentRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCD41E51C3DDB0900965D99 /* ParsedContentRange.cpp */; };
+                CDCD41E81C3DDB0A00965D99 /* ParsedContentRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCD41E61C3DDB0900965D99 /* ParsedContentRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 CDCFABBD18C0AF78006F8450 /* SelectionSubtreeRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCFABBB18C0AE31006F8450 /* SelectionSubtreeRoot.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 CDCFABBE18C0AF84006F8450 /* SelectionSubtreeRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCFABBC18C0AF19006F8450 /* SelectionSubtreeRoot.cpp */; };
</span><span class="cx">                 CDD525D7145B6DD0008D204D /* JSHTMLMediaElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDF65CCC145B6AFE00C4C7AA /* JSHTMLMediaElementCustom.cpp */; };
</span><span class="lines">@@ -14009,6 +14011,8 @@
</span><span class="cx">                 CDCA82941679100F00875714 /* TextTrackRepresentationIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextTrackRepresentationIOS.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDCA98E918B2C8D000C12FF9 /* CDMPrivateMediaPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDMPrivateMediaPlayer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDCA98EA18B2C8EB00C12FF9 /* CDMPrivateMediaPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDMPrivateMediaPlayer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                CDCD41E51C3DDB0900965D99 /* ParsedContentRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParsedContentRange.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                CDCD41E61C3DDB0900965D99 /* ParsedContentRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParsedContentRange.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 CDCE5CD014633BC900D47CCA /* EventTargetFactory.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventTargetFactory.in; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDCFABBB18C0AE31006F8450 /* SelectionSubtreeRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionSubtreeRoot.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CDCFABBC18C0AF19006F8450 /* SelectionSubtreeRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionSubtreeRoot.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -17583,6 +17587,8 @@
</span><span class="cx">                                 1A7FA61A0DDA3BBE0028F8A5 /* NetworkStateNotifier.cpp */,
</span><span class="cx">                                 1A7FA6180DDA3B3A0028F8A5 /* NetworkStateNotifier.h */,
</span><span class="cx">                                 E13EF3421684ECF40034C83F /* NetworkStorageSession.h */,
</span><ins>+                                CDCD41E51C3DDB0900965D99 /* ParsedContentRange.cpp */,
+                                CDCD41E61C3DDB0900965D99 /* ParsedContentRange.h */,
</ins><span class="cx">                                 447958021643B47B001E0A7F /* ParsedContentType.cpp */,
</span><span class="cx">                                 447958031643B47B001E0A7F /* ParsedContentType.h */,
</span><span class="cx">                                 51B454E91B4DAE7D0085EAA6 /* PingHandle.h */,
</span><span class="lines">@@ -25671,6 +25677,7 @@
</span><span class="cx">                                 939885C408B7E3D100E707C4 /* EventNames.h in Headers */,
</span><span class="cx">                                 8F67561B1288B17B0047ACA3 /* EventQueue.h in Headers */,
</span><span class="cx">                                 E0FEF372B17C53EAC1C1FBEE /* EventSource.h in Headers */,
</span><ins>+                                CDCD41E81C3DDB0A00965D99 /* ParsedContentRange.h in Headers */,
</ins><span class="cx">                                 E12EDB7B0B308A78002704B6 /* EventTarget.h in Headers */,
</span><span class="cx">                                 97AA3CA5145237CC003E1DA6 /* EventTargetHeaders.h in Headers */,
</span><span class="cx">                                 97AA3CA6145237CC003E1DA6 /* EventTargetInterfaces.h in Headers */,
</span><span class="lines">@@ -29584,6 +29591,7 @@
</span><span class="cx">                                 A454424A119B3661009BE912 /* HTMLMeterElement.cpp in Sources */,
</span><span class="cx">                                 A8CFF7A90A156978000A4234 /* HTMLModElement.cpp in Sources */,
</span><span class="cx">                                 A8DF3FD5097FA0FC0052981B /* HTMLNameCollection.cpp in Sources */,
</span><ins>+                                CDCD41E71C3DDB0900965D99 /* ParsedContentRange.cpp in Sources */,
</ins><span class="cx">                                 A8D06B3A0A265DCD005E7203 /* HTMLNames.cpp in Sources */,
</span><span class="cx">                                 A871D45B0A127CBC00B12A68 /* HTMLObjectElement.cpp in Sources */,
</span><span class="cx">                                 A8EA79FB0A1916DF00A8EF5F /* HTMLOListElement.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcWebCoreAVFResourceLoadermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -65,10 +65,10 @@
</span><span class="cx">     if (m_resource || !m_parent)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    URL requestURL = [[m_avRequest.get() request] URL];
</del><ins>+    NSURLRequest *nsRequest = [m_avRequest.get() request];
</ins><span class="cx"> 
</span><span class="cx">     // ContentSecurityPolicyImposition::DoPolicyCheck is a placeholder value. It does not affect the request since Content Security Policy does not apply to raw resources.
</span><del>-    CachedResourceRequest request(ResourceRequest(requestURL), ResourceLoaderOptions(SendCallbacks, DoNotSniffContent, BufferData, DoNotAllowStoredCredentials, DoNotAskClientForCrossOriginCredentials, ClientDidNotRequestCredentials, DoSecurityCheck, UseDefaultOriginRestrictionsForType, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading));
</del><ins>+    CachedResourceRequest request(nsRequest, ResourceLoaderOptions(SendCallbacks, DoNotSniffContent, BufferData, DoNotAllowStoredCredentials, DoNotAskClientForCrossOriginCredentials, ClientDidNotRequestCredentials, DoSecurityCheck, UseDefaultOriginRestrictionsForType, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading));
</ins><span class="cx"> 
</span><span class="cx">     request.mutableResourceRequest().setPriority(ResourceLoadPriority::Low);
</span><span class="cx">     CachedResourceLoader* loader = m_parent-&gt;player()-&gt;cachedResourceLoader();
</span><span class="lines">@@ -76,7 +76,7 @@
</span><span class="cx">     if (m_resource)
</span><span class="cx">         m_resource-&gt;addClient(this);
</span><span class="cx">     else {
</span><del>-        LOG_ERROR(&quot;Failed to start load for media at url %s&quot;, requestURL.string().ascii().data());
</del><ins>+        LOG_ERROR(&quot;Failed to start load for media at url %s&quot;, [[[nsRequest URL] absoluteString] UTF8String]);
</ins><span class="cx">         [m_avRequest.get() finishLoadingWithError:0];
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -101,8 +101,8 @@
</span><span class="cx"> 
</span><span class="cx"> void WebCoreAVFResourceLoader::responseReceived(CachedResource* resource, const ResourceResponse&amp; response)
</span><span class="cx"> {
</span><ins>+    ASSERT(resource);
</ins><span class="cx">     ASSERT(resource == m_resource);
</span><del>-    UNUSED_PARAM(resource);
</del><span class="cx"> 
</span><span class="cx">     int status = response.httpStatusCode();
</span><span class="cx">     if (status &amp;&amp; (status &lt; 200 || status &gt; 299)) {
</span><span class="lines">@@ -114,7 +114,9 @@
</span><span class="cx">         String uti = UTIFromMIMEType(response.mimeType().createCFString().get()).get();
</span><span class="cx"> 
</span><span class="cx">         [contentInfo setContentType:uti];
</span><del>-        [contentInfo setContentLength:response.expectedContentLength()];
</del><ins>+
+        ParsedContentRange&amp; contentRange = resource-&gt;response().contentRange();
+        [contentInfo setContentLength:contentRange.isValid() ? contentRange.instanceLength() : response.expectedContentLength()];
</ins><span class="cx">         [contentInfo setByteRangeAccessSupported:YES];
</span><span class="cx"> 
</span><span class="cx">         if (![m_avRequest dataRequest]) {
</span><span class="lines">@@ -147,6 +149,7 @@
</span><span class="cx"> 
</span><span class="cx"> void WebCoreAVFResourceLoader::fulfillRequestWithResource(CachedResource* resource)
</span><span class="cx"> {
</span><ins>+    ASSERT(resource);
</ins><span class="cx">     ASSERT(resource == m_resource);
</span><span class="cx">     AVAssetResourceLoadingDataRequest* dataRequest = [m_avRequest dataRequest];
</span><span class="cx">     if (!dataRequest)
</span><span class="lines">@@ -156,6 +159,11 @@
</span><span class="cx">     if (!data)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    NSUInteger responseOffset = 0;
+    ParsedContentRange contentRange = resource-&gt;response().contentRange();
+    if (contentRange.isValid())
+        responseOffset = static_cast&lt;NSUInteger&gt;(contentRange.firstBytePosition());
+
</ins><span class="cx">     // Check for possible unsigned overflow.
</span><span class="cx">     ASSERT([dataRequest currentOffset] &gt;= [dataRequest requestedOffset]);
</span><span class="cx">     ASSERT([dataRequest requestedLength] &gt;= ([dataRequest currentOffset] - [dataRequest requestedOffset]));
</span><span class="lines">@@ -163,11 +171,11 @@
</span><span class="cx">     NSUInteger remainingLength = [dataRequest requestedLength] - static_cast&lt;NSUInteger&gt;([dataRequest currentOffset] - [dataRequest requestedOffset]);
</span><span class="cx">     do {
</span><span class="cx">         // Check to see if there is any data available in the buffer to fulfill the data request.
</span><del>-        if (data-&gt;size() &lt;= [dataRequest currentOffset])
</del><ins>+        if (data-&gt;size() &lt;= [dataRequest currentOffset] - responseOffset)
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         const char* someData;
</span><del>-        NSUInteger receivedLength = data-&gt;getSomeData(someData, static_cast&lt;unsigned&gt;([dataRequest currentOffset]));
</del><ins>+        NSUInteger receivedLength = data-&gt;getSomeData(someData, static_cast&lt;unsigned&gt;([dataRequest currentOffset] - responseOffset));
</ins><span class="cx"> 
</span><span class="cx">         // Create an NSData with only as much of the received data as necessary to fulfill the request.
</span><span class="cx">         NSUInteger length = MIN(receivedLength, remainingLength);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkBlobResourceHandlecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #include &quot;FileSystem.h&quot;
</span><span class="cx"> #include &quot;HTTPHeaderNames.h&quot;
</span><span class="cx"> #include &quot;HTTPParsers.h&quot;
</span><ins>+#include &quot;ParsedContentRange.h&quot;
</ins><span class="cx"> #include &quot;URL.h&quot;
</span><span class="cx"> #include &quot;ResourceError.h&quot;
</span><span class="cx"> #include &quot;ResourceHandleClient.h&quot;
</span><span class="lines">@@ -50,7 +51,6 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> static const unsigned bufferSize = 512 * 1024;
</span><del>-static const long long positionNotSpecified = -1;
</del><span class="cx"> 
</span><span class="cx"> static const int httpOK = 200;
</span><span class="cx"> static const int httpPartialContent = 206;
</span><span class="lines">@@ -159,16 +159,6 @@
</span><span class="cx">     : ResourceHandle(0, request, client, false, false)
</span><span class="cx">     , m_blobData(blobData)
</span><span class="cx">     , m_async(async)
</span><del>-    , m_errorCode(0)
-    , m_aborted(false)
-    , m_rangeOffset(positionNotSpecified)
-    , m_rangeEnd(positionNotSpecified)
-    , m_rangeSuffixLength(positionNotSpecified)
-    , m_totalRemainingSize(0)
-    , m_currentItemReadSize(0)
-    , m_sizeItemCount(0)
-    , m_readItemCount(0)
-    , m_fileOpened(false)
</del><span class="cx"> {
</span><span class="cx">     if (m_async)
</span><span class="cx">         m_asyncStream = std::make_unique&lt;AsyncFileStream&gt;(*this);
</span><span class="lines">@@ -300,6 +290,7 @@
</span><span class="cx">     m_itemLengthList.append(size);
</span><span class="cx"> 
</span><span class="cx">     // Count the size.
</span><ins>+    m_totalSize += size;
</ins><span class="cx">     m_totalRemainingSize += size;
</span><span class="cx">     m_sizeItemCount++;
</span><span class="cx"> 
</span><span class="lines">@@ -312,13 +303,13 @@
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> 
</span><span class="cx">     // Convert from the suffix length to the range.
</span><del>-    if (m_rangeSuffixLength != positionNotSpecified) {
</del><ins>+    if (m_rangeSuffixLength != kPositionNotSpecified) {
</ins><span class="cx">         m_rangeOffset = m_totalRemainingSize - m_rangeSuffixLength;
</span><span class="cx">         m_rangeEnd = m_rangeOffset + m_rangeSuffixLength - 1;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Bail out if the range is not provided.
</span><del>-    if (m_rangeOffset == positionNotSpecified)
</del><ins>+    if (m_rangeOffset == kPositionNotSpecified)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // Skip the initial items that are not in the range.
</span><span class="lines">@@ -330,7 +321,7 @@
</span><span class="cx">     m_currentItemReadSize = offset;
</span><span class="cx"> 
</span><span class="cx">     // Adjust the total remaining size in order not to go beyond the range.
</span><del>-    if (m_rangeEnd != positionNotSpecified) {
</del><ins>+    if (m_rangeEnd != kPositionNotSpecified) {
</ins><span class="cx">         long long rangeSize = m_rangeEnd - m_rangeOffset + 1;
</span><span class="cx">         if (m_totalRemainingSize &gt; rangeSize)
</span><span class="cx">             m_totalRemainingSize = rangeSize;
</span><span class="lines">@@ -583,10 +574,12 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> 
</span><del>-    bool isRangeRequest = m_rangeOffset != positionNotSpecified;
</del><ins>+    bool isRangeRequest = m_rangeOffset != kPositionNotSpecified;
</ins><span class="cx">     ResourceResponse response(firstRequest().url(), m_blobData-&gt;contentType(), m_totalRemainingSize, String());
</span><span class="cx">     response.setHTTPStatusCode(isRangeRequest ? httpPartialContent : httpOK);
</span><span class="cx">     response.setHTTPStatusText(isRangeRequest ? httpPartialContentText : httpOKText);
</span><ins>+    if (isRangeRequest)
+        response.setHTTPHeaderField(HTTPHeaderName::ContentRange, ParsedContentRange(m_rangeOffset, m_rangeEnd, m_totalSize).headerValue());
</ins><span class="cx">     // FIXME: If a resource identified with a blob: URL is a File object, user agents must use that file's name attribute,
</span><span class="cx">     // as if the response had a Content-Disposition header with the filename parameter set to the File's name attribute.
</span><span class="cx">     // Notably, this will affect a name suggested in &quot;File Save As&quot;.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkBlobResourceHandleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/BlobResourceHandle.h (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/BlobResourceHandle.h        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/platform/network/BlobResourceHandle.h        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -90,22 +90,25 @@
</span><span class="cx">     void notifyFail(int errorCode);
</span><span class="cx">     void notifyFinish();
</span><span class="cx"> 
</span><ins>+    enum { kPositionNotSpecified = -1 };
+
</ins><span class="cx">     RefPtr&lt;BlobData&gt; m_blobData;
</span><span class="cx">     bool m_async;
</span><span class="cx">     std::unique_ptr&lt;AsyncFileStream&gt; m_asyncStream; // For asynchronous loading.
</span><span class="cx">     std::unique_ptr&lt;FileStream&gt; m_stream; // For synchronous loading.
</span><span class="cx">     Vector&lt;char&gt; m_buffer;
</span><span class="cx">     Vector&lt;long long&gt; m_itemLengthList;
</span><del>-    int m_errorCode;
-    bool m_aborted;
-    long long m_rangeOffset;
-    long long m_rangeEnd;
-    long long m_rangeSuffixLength;
-    long long m_totalRemainingSize;
-    long long m_currentItemReadSize;
-    unsigned m_sizeItemCount;
-    unsigned m_readItemCount;
-    bool m_fileOpened;
</del><ins>+    int m_errorCode { 0 };
+    bool m_aborted { false };
+    long long m_rangeOffset { kPositionNotSpecified };
+    long long m_rangeEnd { kPositionNotSpecified };
+    long long m_rangeSuffixLength { kPositionNotSpecified };
+    long long m_totalSize { 0 };
+    long long m_totalRemainingSize { 0 };
+    long long m_currentItemReadSize { 0 };
+    unsigned m_sizeItemCount { 0 };
+    unsigned m_readItemCount { 0 };
+    bool m_fileOpened { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPHeaderNamesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPHeaderNames.in (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPHeaderNames.in        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderNames.in        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> Content-Security-Policy-Report-Only
</span><span class="cx"> Content-Type
</span><span class="cx"> Content-Transfer-Encoding
</span><ins>+Content-Range
</ins><span class="cx"> Cookie
</span><span class="cx"> Cookie2
</span><span class="cx"> Date
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkParsedContentRangecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/network/ParsedContentRange.cpp (0 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ParsedContentRange.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/network/ParsedContentRange.cpp        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -0,0 +1,133 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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;config.h&quot;
+#include &quot;ParsedContentRange.h&quot;
+
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+static bool areContentRangeValuesValid(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength)
+{
+    // From &lt;http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html&gt;
+    // 14.16 Content-Range
+    // A byte-content-range-spec with a byte-range-resp-spec whose last- byte-pos value is less than its first-byte-pos value,
+    // or whose instance-length value is less than or equal to its last-byte-pos value, is invalid.
+    if (firstBytePosition &lt; 0)
+        return false;
+
+    if (lastBytePosition &lt; firstBytePosition)
+        return false;
+
+    if (instanceLength == ParsedContentRange::UnknownLength)
+        return true;
+
+    return lastBytePosition &lt; instanceLength;
+}
+
+static bool parseContentRange(const String&amp; headerValue, int64_t&amp; firstBytePosition, int64_t&amp; lastBytePosition, int64_t&amp; instanceLength)
+{
+    // From &lt;http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html&gt;
+    // 14.16 Content-Range
+    //
+    // Content-Range = &quot;Content-Range&quot; &quot;:&quot; content-range-spec
+    // content-range-spec      = byte-content-range-spec
+    // byte-content-range-spec = bytes-unit SP
+    //                          byte-range-resp-spec &quot;/&quot;
+    //                          ( instance-length | &quot;*&quot; )
+    // byte-range-resp-spec = (first-byte-pos &quot;-&quot; last-byte-pos)
+    //                               | &quot;*&quot;
+    // instance-length           = 1*DIGIT
+
+    static const char* prefix = &quot;bytes &quot;;
+    static const size_t prefixLength = 6;
+
+    if (!headerValue.startsWith(prefix))
+        return false;
+
+    size_t byteSeparatorTokenLoc = headerValue.find('-', prefixLength);
+    if (byteSeparatorTokenLoc == notFound)
+        return false;
+
+    size_t instanceLengthSeparatorToken = headerValue.find('/', byteSeparatorTokenLoc + 1);
+    if (instanceLengthSeparatorToken == notFound)
+        return false;
+
+    bool isOk = true;
+    String firstByteString = headerValue.substring(prefixLength, byteSeparatorTokenLoc - prefixLength);
+    if (!firstByteString.isAllSpecialCharacters&lt;isASCIIDigit&gt;())
+        return false;
+
+    firstBytePosition = firstByteString.toInt64Strict(&amp;isOk);
+    if (!isOk)
+        return false;
+
+    String lastByteString = headerValue.substring(byteSeparatorTokenLoc + 1, instanceLengthSeparatorToken - (byteSeparatorTokenLoc + 1));
+    if (!lastByteString.isAllSpecialCharacters&lt;isASCIIDigit&gt;())
+        return false;
+
+    lastBytePosition = lastByteString.toInt64Strict(&amp;isOk);
+    if (!isOk)
+        return false;
+
+    String instanceString = headerValue.substring(instanceLengthSeparatorToken + 1);
+    if (instanceString == &quot;*&quot;)
+        instanceLength = ParsedContentRange::UnknownLength;
+    else {
+        if (!instanceString.isAllSpecialCharacters&lt;isASCIIDigit&gt;())
+            return false;
+
+        instanceLength = instanceString.toInt64Strict(&amp;isOk);
+        if (!isOk)
+            return false;
+    }
+
+    return areContentRangeValuesValid(firstBytePosition, lastBytePosition, instanceLength);
+}
+
+ParsedContentRange::ParsedContentRange(const String&amp; headerValue)
+{
+    m_isValid = parseContentRange(headerValue, m_firstBytePosition, m_lastBytePosition, m_instanceLength);
+}
+
+ParsedContentRange::ParsedContentRange(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength)
+    : m_firstBytePosition(firstBytePosition)
+    , m_lastBytePosition(lastBytePosition)
+    , m_instanceLength(instanceLength)
+{
+    m_isValid = areContentRangeValuesValid(m_firstBytePosition, m_lastBytePosition, m_instanceLength);
+}
+
+String ParsedContentRange::headerValue() const
+{
+    if (!m_isValid)
+        return String();
+    if (m_instanceLength == UnknownLength)
+        return String::format(&quot;bytes %&quot; PRId64 &quot;-%&quot; PRId64 &quot;/*&quot;, m_firstBytePosition, m_lastBytePosition);
+    return String::format(&quot;bytes %&quot; PRId64 &quot;-%&quot; PRId64 &quot;/%&quot; PRId64, m_firstBytePosition, m_lastBytePosition, m_instanceLength);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkParsedContentRangeh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/network/ParsedContentRange.h (0 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ParsedContentRange.h                                (rev 0)
+++ trunk/Source/WebCore/platform/network/ParsedContentRange.h        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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. 
+ */
+
+#ifndef ParsedContentRange_h
+#define ParsedContentRange_h
+
+#include &lt;wtf/Forward.h&gt;
+
+namespace WebCore {
+
+class ParsedContentRange {
+public:
+    WEBCORE_EXPORT explicit ParsedContentRange(const String&amp;);
+    WEBCORE_EXPORT ParsedContentRange() { }
+    WEBCORE_EXPORT ParsedContentRange(int64_t firstBytePosition, int64_t lastBytePosition, int64_t instanceLength);
+
+    WEBCORE_EXPORT bool isValid() const { return m_isValid; }
+    int64_t firstBytePosition() const { return m_firstBytePosition; }
+    int64_t lastBytePosition() const { return m_lastBytePosition; }
+    int64_t instanceLength() const { return m_instanceLength; }
+
+    WEBCORE_EXPORT String headerValue() const;
+
+    enum { UnknownLength = std::numeric_limits&lt;int64_t&gt;::max() };
+
+private:
+    template&lt;typename T&gt; static bool isPositive(T);
+
+    bool m_isValid { false };
+    int64_t m_firstBytePosition { 0 };
+    int64_t m_lastBytePosition { 0 };
+    int64_t m_instanceLength { UnknownLength };
+};
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceResponseBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;CacheValidation.h&quot;
</span><span class="cx"> #include &quot;HTTPHeaderNames.h&quot;
</span><span class="cx"> #include &quot;HTTPParsers.h&quot;
</span><ins>+#include &quot;ParsedContentRange.h&quot;
</ins><span class="cx"> #include &quot;ResourceResponse.h&quot;
</span><span class="cx"> #include &lt;wtf/CurrentTime.h&gt;
</span><span class="cx"> #include &lt;wtf/MathExtras.h&gt;
</span><span class="lines">@@ -300,6 +301,10 @@
</span><span class="cx">         m_haveParsedLastModifiedHeader = false;
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case HTTPHeaderName::ContentRange:
+        m_haveParsedContentRangeHeader = false;
+        break;
+
</ins><span class="cx">     default:
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -461,6 +466,27 @@
</span><span class="cx">     return m_lastModified;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static ParsedContentRange parseContentRangeInHeader(const HTTPHeaderMap&amp; headers)
+{
+    String contentRangeValue = headers.get(HTTPHeaderName::ContentRange);
+    if (contentRangeValue.isEmpty())
+        return ParsedContentRange();
+
+    return ParsedContentRange(contentRangeValue);
+}
+
+ParsedContentRange&amp; ResourceResponseBase::contentRange() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    if (!m_haveParsedContentRangeHeader) {
+        m_contentRange = parseContentRangeInHeader(m_httpHeaderFields);
+        m_haveParsedContentRangeHeader = true;
+    }
+
+    return m_contentRange;
+}
+
</ins><span class="cx"> bool ResourceResponseBase::isAttachment() const
</span><span class="cx"> {
</span><span class="cx">     lazyInit(AllFields);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceResponseBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceResponseBase.h        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.h        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;CacheValidation.h&quot;
</span><span class="cx"> #include &quot;CertificateInfo.h&quot;
</span><span class="cx"> #include &quot;HTTPHeaderMap.h&quot;
</span><ins>+#include &quot;ParsedContentRange.h&quot;
</ins><span class="cx"> #include &quot;ResourceLoadTiming.h&quot;
</span><span class="cx"> #include &quot;URL.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -110,6 +111,7 @@
</span><span class="cx">     WEBCORE_EXPORT Optional&lt;std::chrono::microseconds&gt; age() const;
</span><span class="cx">     WEBCORE_EXPORT Optional&lt;std::chrono::system_clock::time_point&gt; expires() const;
</span><span class="cx">     WEBCORE_EXPORT Optional&lt;std::chrono::system_clock::time_point&gt; lastModified() const;
</span><ins>+    ParsedContentRange&amp; contentRange() const;
</ins><span class="cx"> 
</span><span class="cx">     // This is primarily for testing support. It is not necessarily accurate in all scenarios.
</span><span class="cx">     enum class Source { Unknown, Network, DiskCache, DiskCacheAfterValidation, MemoryCache, MemoryCacheAfterValidation };
</span><span class="lines">@@ -175,6 +177,7 @@
</span><span class="cx">     mutable Optional&lt;std::chrono::system_clock::time_point&gt; m_date;
</span><span class="cx">     mutable Optional&lt;std::chrono::system_clock::time_point&gt; m_expires;
</span><span class="cx">     mutable Optional&lt;std::chrono::system_clock::time_point&gt; m_lastModified;
</span><ins>+    mutable ParsedContentRange m_contentRange;
</ins><span class="cx">     mutable CacheControlDirectives m_cacheControlDirectives;
</span><span class="cx"> 
</span><span class="cx">     mutable bool m_haveParsedCacheControlHeader { false };
</span><span class="lines">@@ -182,6 +185,7 @@
</span><span class="cx">     mutable bool m_haveParsedDateHeader { false };
</span><span class="cx">     mutable bool m_haveParsedExpiresHeader { false };
</span><span class="cx">     mutable bool m_haveParsedLastModifiedHeader { false };
</span><ins>+    mutable bool m_haveParsedContentRangeHeader { false };
</ins><span class="cx"> 
</span><span class="cx">     Source m_source { Source::Unknown };
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Tools/ChangeLog        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-01-12  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        Custom protocol loading through AVFoundation does not support byte-range requests.
+        https://bugs.webkit.org/show_bug.cgi?id=152919
+        &lt;rdar://problem/23664657&gt;
+
+        Reviewed by Alex Christensen.
+
+        Add tests for new ParsedContntRange class.
+
+        * TestWebKitAPI/PlatformWin.cmake:
+        * TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj:
+        * TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp: Added.
+        (TestWebKitAPI::TEST):
+
</ins><span class="cx"> 2016-01-28  Konstantin Tokarev  &lt;annulen@yandex.ru&gt;
</span><span class="cx"> 
</span><span class="cx">         Use isAnyWindows() instead of isCygwin() || isWindows() in Perl scripts.
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPIPlatformWincmake"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/PlatformWin.cmake (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/PlatformWin.cmake        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Tools/TestWebKitAPI/PlatformWin.cmake        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WebCore/CalculationValue.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WebCore/CSSParser.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WebCore/LayoutUnit.cpp
</span><ins>+    ${TESTWEBKITAPI_DIR}/Tests/WebCore/ParsedContentRange.cpp
</ins><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WebCore/TimeRanges.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WebCore/URL.cpp
</span><span class="cx"> )
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIvcxprojTestWebKitAPIvcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -295,6 +295,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\CalculationValue.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\CSSParser.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\LayoutUnit.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\Tests\WebCore\ParsedContentRange.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\TimeRanges.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\URL.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\win\BitmapImage.cpp&quot;&gt;
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIvcxprojTestWebKitAPIvcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -157,6 +157,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\CalculationValue.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Tests\WebCore&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\Tests\WebCore\ParsedContentRange.cpp&quot;&gt;
+      &lt;Filter&gt;Tests\WebCore&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\TimeRanges.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Tests\WebCore&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (195763 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-01-28 19:07:40 UTC (rev 195763)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -313,6 +313,7 @@
</span><span class="cx">                 C540F784152E5A9A00A40C8C /* verboseMarkup.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C540F783152E5A7800A40C8C /* verboseMarkup.html */; };
</span><span class="cx">                 C54237F116B8957D00E638FC /* PasteboardNotifications_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C54237ED16B8955800E638FC /* PasteboardNotifications_Bundle.cpp */; };
</span><span class="cx">                 C5E1AFFE16B221F1006CC1F2 /* execCopy.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C5E1AFFD16B22179006CC1F2 /* execCopy.html */; };
</span><ins>+                CD225C081C45A69200140761 /* ParsedContentRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD225C071C45A69200140761 /* ParsedContentRange.cpp */; };
</ins><span class="cx">                 CD59F53419E9110D00CF1835 /* file-with-mse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53219E910AA00CF1835 /* file-with-mse.html */; };
</span><span class="cx">                 CD59F53519E9110D00CF1835 /* test-mse.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53319E910BC00CF1835 /* test-mse.mp4 */; };
</span><span class="cx">                 CDBFCC451A9FF45300A7B691 /* FullscreenZoomInitialFrame.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDBFCC431A9FF44800A7B691 /* FullscreenZoomInitialFrame.mm */; };
</span><span class="lines">@@ -783,6 +784,7 @@
</span><span class="cx">                 C54237EE16B8955800E638FC /* PasteboardNotifications.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteboardNotifications.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C5E1AFFD16B22179006CC1F2 /* execCopy.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = execCopy.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C95501BE19AD2FAF0049BE3E /* Preferences.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Preferences.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                CD225C071C45A69200140761 /* ParsedContentRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParsedContentRange.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 CD5393C71757BA9700C07123 /* MD5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MD5.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD5393C91757BAC400C07123 /* SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SHA1.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD5451E919E41F9D0016936F /* CSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -989,6 +991,7 @@
</span><span class="cx">                                 26F6E1EF1ADC749B00DE696B /* DFAMinimizer.cpp */,
</span><span class="cx">                                 41973B5A1AF2286A006C7B36 /* FileSystem.cpp */,
</span><span class="cx">                                 14464012167A8305000BD218 /* LayoutUnit.cpp */,
</span><ins>+                                CD225C071C45A69200140761 /* ParsedContentRange.cpp */,
</ins><span class="cx">                                 41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */,
</span><span class="cx">                                 CDC2C7141797089D00E627FB /* TimeRanges.cpp */,
</span><span class="cx">                                 440A1D3814A0103A008A66F2 /* URL.cpp */,
</span><span class="lines">@@ -1835,6 +1838,7 @@
</span><span class="cx">                                 1CB9BC381A67482300FE5678 /* WeakPtr.cpp in Sources */,
</span><span class="cx">                                 2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */,
</span><span class="cx">                                 2D8104CC1BEC13E70020DA46 /* FindInPage.mm in Sources */,
</span><ins>+                                CD225C081C45A69200140761 /* ParsedContentRange.cpp in Sources */,
</ins><span class="cx">                                 41973B5D1AF22875006C7B36 /* SharedBuffer.cpp in Sources */,
</span><span class="cx">                                 2DD355361BD08378005DF4A7 /* AutoLayoutIntegration.mm in Sources */,
</span><span class="cx">                                 7AA6A1521AAC0B31002B2ED3 /* WorkQueue.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebCoreParsedContentRangecpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp (0 => 195764)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp        2016-01-28 19:17:17 UTC (rev 195764)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+/*
+ * Copyright (C) 2016 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;config.h&quot;
+
+#include &lt;WebCore/ParsedContentRange.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+TEST(WebCore, ParsedContentRangeFromString)
+{
+    // Basic parsing
+    ASSERT_TRUE(ParsedContentRange(&quot;bytes 0-1/2&quot;).isValid());
+    ASSERT_TRUE(ParsedContentRange(&quot;bytes 0-1/*&quot;).isValid());
+    ASSERT_EQ(0, ParsedContentRange(&quot;bytes 0-1/2&quot;).firstBytePosition());
+    ASSERT_EQ(1, ParsedContentRange(&quot;bytes 0-1/2&quot;).lastBytePosition());
+    ASSERT_EQ(2, ParsedContentRange(&quot;bytes 0-1/2&quot;).instanceLength());
+    ASSERT_EQ(ParsedContentRange::UnknownLength, ParsedContentRange(&quot;bytes 0-1/*&quot;).instanceLength());
+
+    // Whitespace errors
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes  0-1/*&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0 -1/*&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0- 1/*&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-1 /*&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-1/ *&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-1/* &quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-1/ 2&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-1/2 &quot;).isValid());
+
+    // Non-digit errors
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes abcd-1/2&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-abcd/2&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-1/abcd&quot;).isValid());
+
+    // Range requirement errors
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 1-0/2&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-2/1&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 2/0-1&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;abcd 0/1-2&quot;).isValid());
+
+    // Negative value errors
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes -0-1/*&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes -1/*&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0--0/2&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 0-1/-2&quot;).isValid());
+
+    // Edge cases
+    ASSERT_TRUE(ParsedContentRange(&quot;bytes 9223372036854775805-9223372036854775806/9223372036854775807&quot;).isValid());
+    ASSERT_FALSE(ParsedContentRange(&quot;bytes 9223372036854775808-9223372036854775809/9223372036854775810&quot;).isValid());
+}
+
+TEST(WebCore, ParsedContentRangeFromValues)
+{
+    ASSERT_TRUE(ParsedContentRange(0, 1, 2).isValid());
+    ASSERT_TRUE(ParsedContentRange(0, 1, ParsedContentRange::UnknownLength).isValid());
+    ASSERT_FALSE(ParsedContentRange().isValid());
+    ASSERT_FALSE(ParsedContentRange(1, 0, 2).isValid());
+    ASSERT_FALSE(ParsedContentRange(0, 2, 1).isValid());
+    ASSERT_FALSE(ParsedContentRange(0, 0, 0).isValid());
+    ASSERT_FALSE(ParsedContentRange(-1, 1, 2).isValid());
+    ASSERT_FALSE(ParsedContentRange(0, -1, 2).isValid());
+    ASSERT_FALSE(ParsedContentRange(0, 1, -2).isValid());
+    ASSERT_FALSE(ParsedContentRange(-2, -1, 2).isValid());
+}
+
+TEST(WebCore, ParsedContentRangeToString)
+{
+    ASSERT_STREQ(&quot;bytes 0-1/2&quot;, ParsedContentRange(0, 1, 2).headerValue().utf8().data());
+    ASSERT_STREQ(&quot;bytes 0-1/*&quot;, ParsedContentRange(0, 1, ParsedContentRange::UnknownLength).headerValue().utf8().data());
+    ASSERT_STREQ(&quot;&quot;, ParsedContentRange().headerValue().utf8().data());
+}
+
+}
</ins></span></pre>
</div>
</div>

</body>
</html>