Task #87528
openVimeoHelper/AbstractOEmbedHelper must send Referer Header to fetch proper oEmbed.json for videos with restricted embedding.
0%
Description
VideoHelper uses an oEmbed request, as documented here: https://developer.vimeo.com/api/oembed/videos
curl 'https://vimeo.com/api/oembed.json?width=2048&url=https%3A%2F%2Fvimeo.com%2F123456789' | python -m json.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 387 100 387 0 0 1646 0 --:--:-- --:--:-- --:--:-- 1646 { "domain_status_code": 403, "height": 1152, "html": "<iframe src=\"https://player.vimeo.com/video/123456789?app_id=122963\" width=\"2048\" height=\"1152\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen></iframe>", "provider_name": "Vimeo", "provider_url": "https://vimeo.com/", "type": "video", "uri": "/videos/123456789", "version": "1.0", "video_id": 123456789, "width": 2048 }
Note:
Due to privacy reasons, the video ID was replaced by 123456789.
To test this, create a Vimeo video, set the privacy settings to "Who can watch?" to "Anyone" and "Where can this be embedded?" to "Specific domains" and choose your domain.
The API docs (https://developer.vimeo.com/api/oembed/videos) state the following:
NOTE: In the case of a video with domain-level privacy, the oEmbed request returns a simplified response containing the embed code only and no private metadata. To get the complete response, send the Referer header along with the request, and set its value to the video's whitelisted domain.
This is the case here. As you see, the JSON response contains no title.
When adding the video in the TYPO3 filelist, it will be successfully saved as ".vimeo" ($oEmbed['title'] . '.' . $fileExtension
in \TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\AbstractOEmbedHelper::transformMediaIdToFile
):
if (!empty($oEmbed)) {
$fileName = $oEmbed['title'] . '.' . $fileExtension;
} else {
$fileName = $mediaId . '.' . $fileExtension;
}
Actually, $oEmbed['title']
is undefined (!isset()
) here, but the script only checks if $oEmbed
is empty, which is insufficient. (This is a bug on its own!)
Following, a success flash message is shown, but the file will not be visible because of the default filterHiddenFilesAndFolders
filter defined in defaultFilterCallbacks
.
When trying to create the vimeo file once more, \TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\AbstractOnlineMediaHelper::findExistingFileByOnlineMediaId()
will find the existing file, but not tell the user about it.
So again a green success flash message is shown. (This is another bug. The user should be informed that this video exists already in the folder.)
The actual solution, however, would be to send a referer header with the hostname, like:
curl 'https://vimeo.com/api/oembed.json?width=2048&url=https%3A%2F%2Fvimeo.com%2F123456789' -H 'Referer: https://example.com' | python -m json.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 950 100 950 0 0 4166 0 --:--:-- --:--:-- --:--:-- 4166 { "account_type": "pro", "author_name": "Redacted", "author_url": "https://vimeo.com/redacted", "description": "", "domain_status_code": 200, "duration": 235, "height": 1152, "html": "<iframe src=\"https://player.vimeo.com/video/123456789?app_id=122963\" width=\"2048\" height=\"1152\" frameborder=\"0\" title=\"Redacted video title\" allow=\"autoplay; fullscreen\" allowfullscreen></iframe>", "is_plus": "0", "provider_name": "Vimeo", "provider_url": "https://vimeo.com/", "thumbnail_height": 540, "thumbnail_url": "https://i.vimeocdn.com/video/redacted_960.jpg", "thumbnail_url_with_play_button": "https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2Fredacted_960.jpg&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png", "thumbnail_width": 960, "title": "Redacted video title", "type": "video", "upload_date": "2019-01-01 00:00:00", "uri": "/videos/123456789", "version": "1.0", "video_id": 123456789, "width": 2048 }
You can see the full response being sent due to the -H 'Referer: https://example.com'
header. (For testing, use the hostname you applied as embed restriction in the vimeo privacy settings.)
Only now is a title sent, and $oEmbed['title'] . '.' . $fileExtension
no longer results in .vimeo
but, in this example case, in Redacted video title.vimeo
.
A little gotcha:
Unfortunately the filelist module does not "know" which of the TYPO3 installation's possibly many domain records match the video's privacy restrictions.
Therefore, TYPO3 would have no choice but to try sys_domain records until the oEmbed request returns a video title.
Meaning: If only one of multiple sites within a TYPO3 installation is whitelisted for the video, then the video can be added.
Otherwise you might want to let the request fail or succeed with a warning to the user (using the video ID as filename and remaining unable to set a preview image (thumbnail).
Target:
Same in TYPO3 8 and 9.