https://bugs.webkit.org/show_bug.cgi?id=78614
Reviewed by Alexey Proskuryakov.
Source/WebCore:
Test: http/tests/media/video-referer.html was modified to test this change.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaPlayerReferrer): New, return the document's referer.
* html/HTMLMediaElement.h:
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::referrer): New, return the client's mediaPlayerReferrer.
* platform/graphics/MediaPlayer.h:
(WebCore::MediaPlayerClient::mediaPlayerReferrer):
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL): Tell AVFoundation to add
a referer header.
LayoutTests:
* http/tests/media/resources/video-referer-check-referer.php: Get the test file and content-type
from parameters on the url. Fail if referrer is anything but video-referer.html. Add support for
byte-range requests so it will work with AVFoundation.
* http/tests/media/video-referer.html: Pass video file name and content-type as url parameters
instead of having another cgi set a cookie. Set the php script as the 'src' on a <source> element
instead of on the <video> element so we can also add a 'type' attribute.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@108387
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-02-21 Eric Carlson <eric.carlson@apple.com>
+
+ Set Referrer header for media downloads
+ https://bugs.webkit.org/show_bug.cgi?id=78614
+
+ Reviewed by Alexey Proskuryakov.
+
+ * http/tests/media/resources/video-referer-check-referer.php: Get the test file and content-type
+ from parameters on the url. Fail if referrer is anything but video-referer.html. Add support for
+ byte-range requests so it will work with AVFoundation.
+ * http/tests/media/video-referer.html: Pass video file name and content-type as url parameters
+ instead of having another cgi set a cookie. Set the php script as the 'src' on a <source> element
+ instead of on the <video> element so we can also add a 'type' attribute.
+
2012-02-21 Chris Fleizach <cfleizach@apple.com>
AX: move aria-invalid test to top level, so other platforms can use it
+++ /dev/null
-#!/usr/bin/perl -wT
-use CGI;
-
-$query = new CGI;
-$name = $query->param('name');
-$referer = $query->param('referer');
-
-print "Content-Type: text/plain\n";
-print "Cache-Control: no-store\n";
-print 'Cache-Control: no-cache="set-cookie"' . "\n";
-
-print "Referer: ${referer}\n";
-
-# We only map the SET_COOKIE request header to "Set-Cookie"
-print "Set-Cookie: TEST=${name}\n\n";
<?php
- if($_SERVER['HTTP_REFERER'])
+
+ $refer = $_SERVER["HTTP_REFERER"];
+ if (!isset($refer) || stripos($refer, "video-referer.html") === false)
+ die;
+
+ $fileName = $_GET["name"];
+ $type = $_GET["type"];
+
+ $fileSize = filesize($fileName);
+ $start = 0;
+ $end = $fileSize - 1;
+ $contentRange = $_SERVER["HTTP_RANGE"];
+ if (isset($contentRange))
{
- $extension = substr($_COOKIE["TEST"], -3);
-
- if ($extension == 'mp4') {
- header("Content-Type: video/mp4");
- $fileName = "test.mp4";
- } else if ($extension == 'ogv') {
- header("Content-Type: video/ogg");
- $fileName = "test.ogv";
- } else
- die;
-
- header("Cache-Control: no-store");
- header("Connection: close");
-
- $fn = fopen($fileName, "r");
- fpassthru($fn);
- fclose($fn);
- exit;
+ $range = explode("-", substr($contentRange, 6));
+ $start = intval($range[0]);
+ if (!empty($range[1]))
+ $end = intval($range[1]);
+ $httpStatus = "HTTP/1.1 206 Partial Content";
} else
- die;
+ $httpStatus = "200 OK";
+
+ header("Status: " . $httpStatus);
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ header("Pragma: no-cache");
+ header("Etag: " . '"' . $fileSize . "-" . filemtime($fileName) . '"');
+ header("Content-Type: " . $type);
+ header("Accept-Ranges: bytes");
+ header("Content-Length: " . ($end - $start) + 1);
+ if ($contentRange)
+ header("Content-Range: bytes " . $start . "-" . $end . "/" . $fileSize);
+ header("Connection: close");
+
+ $chunkSize = 1024 * 256;
+ $offset = $start;
+
+ $fn = fopen($fileName, "rb");
+ fseek($fn, $offset, 0);
+
+ while (!feof($fn) && $offset <= $end && connection_status() == 0)
+ {
+ $readSize = min($chunkSize, ($end - $offset) + 1);
+ $buffer = fread($fn, $readSize);
+ print($buffer);
+ flush();
+ $offset += $chunkSize;
+ }
+ fclose($fn);
+
+ exit;
?>
<head>
</head>
<body onload="loadCookieAndReferer()">
-<video id="video"></video>
+<video id="video">
+ <source id="source">
+</video>
<script src=../../media-resources/video-test.js></script>
<script src=../../media-resources/media-file.js></script>
<script>
- if (window.layoutTestController) {
- layoutTestController.setAlwaysAcceptCookies(true);
- }
-
function loadCookieAndReferer () {
- var movie = findMediaFile('video', 'resources/test');
+ var movie = findMediaFile('video', 'test');
+ var type = mimeTypeForExtension(movie.split('.').pop());
var frame = document.createElement('iframe');
frame.width = 0;
frame.height = 0;
- frame.src = 'http://127.0.0.1:8000/media/resources/setCookieAndReferer.cgi?name=' + movie + '&referer=http://127.0.0.1:8000/media/resources';
-
+ frame.src = "data:text/html,<b>test</b>";
frame.addEventListener('load', function () {
video = document.getElementById('video');
- video.src='http://127.0.0.1:8000/media/resources/video-referer-check-referer.php';
- video.play();
+ source = document.getElementById('source');
+ source.src = 'http://127.0.0.1:8000/media/resources/video-referer-check-referer.php?name=' + movie + '&type=' + type;
+ source.type = type;
+ video.load();
});
document.body.appendChild(frame);
+2012-02-21 Eric Carlson <eric.carlson@apple.com>
+
+ Set Referrer header for media downloads
+ https://bugs.webkit.org/show_bug.cgi?id=78614
+
+ Reviewed by Alexey Proskuryakov.
+
+ Test: http/tests/media/video-referer.html was modified to test this change.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::mediaPlayerReferrer): New, return the document's referer.
+ * html/HTMLMediaElement.h:
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::referrer): New, return the client's mediaPlayerReferrer.
+ * platform/graphics/MediaPlayer.h:
+ (WebCore::MediaPlayerClient::mediaPlayerReferrer):
+
+ * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL): Tell AVFoundation to add
+ a referer header.
+
2012-02-21 Antti Koivisto <antti@apple.com>
Not reviewed.
#include "ScriptController.h"
#include "ScriptEventListener.h"
#include "SecurityOrigin.h"
+#include "SecurityPolicy.h"
#include "Settings.h"
#include "ShadowRoot.h"
#include "ShadowRootList.h"
}
#endif
+String HTMLMediaElement::mediaPlayerReferrer() const
+{
+ Frame* frame = document()->frame();
+ if (!frame)
+ return String();
+
+ return SecurityPolicy::generateReferrerHeader(document()->referrerPolicy(), m_currentSrc, frame->loader()->outgoingReferrer());
}
+}
#endif
virtual String mediaPlayerSourceURL() const;
#endif
+ virtual String mediaPlayerReferrer() const OVERRIDE;
+
void loadTimerFired(Timer<HTMLMediaElement>*);
void progressEventTimerFired(Timer<HTMLMediaElement>*);
void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
return m_private->audioSourceProvider();
}
#endif // WEB_AUDIO
+
+String MediaPlayer::referrer() const
+{
+ if (!m_mediaPlayerClient)
+ return String();
+
+ return m_mediaPlayerClient->mediaPlayerReferrer();
+}
}
virtual void mediaPlayerSourceOpened() { }
virtual String mediaPlayerSourceURL() const { return "x-media-source-unsupported:"; }
#endif
+
+ virtual String mediaPlayerReferrer() const { return String(); }
};
class MediaPlayer {
void firstVideoFrameAvailable();
void characteristicChanged();
-
void repaint();
MediaPlayerClient* mediaPlayerClient() const { return m_mediaPlayerClient; }
String sourceURL() const;
#endif
+ String referrer() const;
+
private:
MediaPlayer(MediaPlayerClient*);
void loadWithNextMediaEngine(MediaPlayerFactory*);
const String& assetURL() const { return m_assetURL; }
+ MediaPlayer* player() { return m_player; }
+
private:
MediaPlayer* m_player;
setDelayCallbacks(true);
- NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInt:AVAssetReferenceRestrictionForbidRemoteReferenceToLocal | AVAssetReferenceRestrictionForbidLocalReferenceToRemote], AVURLAssetReferenceRestrictionsKey,
- nil];
+ RetainPtr<NSMutableDictionary> options(AdoptNS, [[NSMutableDictionary alloc] init]);
+
+ [options.get() setObject:[NSNumber numberWithInt:AVAssetReferenceRestrictionForbidRemoteReferenceToLocal | AVAssetReferenceRestrictionForbidLocalReferenceToRemote] forKey:AVURLAssetReferenceRestrictionsKey];
+
+#if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION)
+ String referrer = player()->referrer();
+ if (!referrer.isEmpty()) {
+ RetainPtr<NSMutableDictionary> headerFields(AdoptNS, [[NSMutableDictionary alloc] init]);
+ [headerFields.get() setObject:referrer forKey:@"Referer"];
+ [options.get() setObject:headerFields.get() forKey:@"AVURLAssetHTTPHeaderFieldsKey"];
+ }
+#endif
+
NSURL *cocoaURL = KURL(ParsedURLString, url);
- m_avAsset.adoptNS([[AVURLAsset alloc] initWithURL:cocoaURL options:options]);
+ m_avAsset.adoptNS([[AVURLAsset alloc] initWithURL:cocoaURL options:options.get()]);
m_haveCheckedPlayability = false;