private function validateAccessControl(entry $entry, flavorAsset $flavorAsset, $referrer64base) { $referrer = base64_decode(str_replace(" ", "+", $referrer64base)); if (!is_string($referrer)) { $referrer = ""; } // base64_decode can return binary data $secureEntryHelper = new KSecureEntryHelper($entry, kCurrentContext::$ks, $referrer, ContextType::PLAY); if (!$secureEntryHelper->isKsAdmin()) { if (!$entry->isScheduledNow()) { throw new KalturaWidevineLicenseProxyException(KalturaWidevineErrorCodes::ENTRY_NOT_SCHEDULED_NOW); } if ($secureEntryHelper->isEntryInModeration()) { throw new KalturaWidevineLicenseProxyException(KalturaWidevineErrorCodes::ENTRY_MODERATION_ERROR); } } if ($secureEntryHelper->shouldBlock()) { throw new KalturaWidevineLicenseProxyException(KalturaWidevineErrorCodes::ACCESS_CONTROL_RESTRICTED); } if (!$secureEntryHelper->isAssetAllowed($flavorAsset)) { throw new KalturaWidevineLicenseProxyException(KalturaWidevineErrorCodes::FLAVOR_ASSET_ID_NOT_FOUND); } }
public function execute() { KExternalErrors::setResponseErrorCode(KExternalErrors::HTTP_STATUS_NOT_FOUND); $this->deliveryAttributes = new DeliveryProfileDynamicAttributes(); // Parse input parameters $this->deliveryAttributes->setSeekFromTime($this->getRequestParameter("seekFrom", -1)); if ($this->deliveryAttributes->getSeekFromTime() <= 0) { $this->deliveryAttributes->setSeekFromTime(-1); } $this->deliveryAttributes->setClipTo($this->getRequestParameter("clipTo", 0)); $this->deliveryAttributes->setPlaybackRate($this->getRequestParameter("playbackRate", 0)); $deliveryCode = $this->getRequestParameter("deliveryCode", null); $playbackContext = $this->getRequestParameter("playbackContext", null); $this->deliveryAttributes->setMediaProtocol($this->getRequestParameter("protocol", null)); if (!$this->deliveryAttributes->getMediaProtocol() || $this->deliveryAttributes->getMediaProtocol() === "null") { $this->deliveryAttributes->setMediaProtocol(PlaybackProtocol::HTTP); } $this->deliveryAttributes->setFormat($this->getRequestParameter("format")); if (!$this->deliveryAttributes->getFormat()) { $this->deliveryAttributes->setFormat(PlaybackProtocol::HTTP); } if ($this->deliveryAttributes->getFormat() == self::HDNETWORKSMIL) { $this->deliveryAttributes->setMediaProtocol(PlaybackProtocol::HTTP); } // Akamai HD doesn't support any other protocol if ($this->deliveryAttributes->getFormat() == PlaybackProtocol::AKAMAI_HDS) { if (strpos($this->deliveryAttributes->getMediaProtocol(), "http") !== 0) { $this->deliveryAttributes->setMediaProtocol(PlaybackProtocol::HTTP); } } $tags = $this->getRequestParameter("tags", null); if (!$tags) { $this->deliveryAttributes->setTags(self::getDefaultTagsByFormat($this->deliveryAttributes->getFormat())); } else { $tagsArray = explode(',', $tags); $tags = array(); foreach ($tagsArray as $tag) { $tags[] = array(trim($tag)); } $this->deliveryAttributes->setTags($tags); } $this->deliveryAttributes->setpreferredBitrate($this->getRequestParameter("preferredBitrate", null)); $this->maxBitrate = $this->getRequestParameter("maxBitrate", null); if ($this->maxBitrate && (!is_numeric($this->maxBitrate) || $this->maxBitrate <= 0)) { KExternalErrors::dieError(KExternalErrors::INVALID_MAX_BITRATE); } $this->deliveryAttributes->setStorageId($this->getRequestParameter("storageId", null)); $this->cdnHost = $this->getRequestParameter("cdnHost", null); $this->deliveryAttributes->setResponseFormat($this->getRequestParameter("responseFormat", null)); // Initialize $this->initEntry(); $this->deliveryAttributes->setEntryId($this->entryId); $this->deliveryAttributes->setUsePlayServer((bool) $this->getRequestParameter("usePlayServer") && PermissionPeer::isValidForPartner(PermissionName::FEATURE_PLAY_SERVER, $this->entry->getPartnerId())); if ($this->deliveryAttributes->getUsePlayServer()) { $this->deliveryAttributes->setPlayerConfig($this->getRequestParameter("playerConfig")); //In case request needs to be redirected to play-server we need to add the ui conf id to the manifest url as well $this->deliveryAttributes->setUiConfId($this->getRequestParameter("uiConfId")); } $this->secureEntryHelper->updateDeliveryAttributes($this->deliveryAttributes); $this->enforceEncryption(); $renderer = null; switch ($this->entry->getType()) { case entryType::MEDIA_CLIP: // VOD $renderer = $this->serveVodEntry(); break; case entryType::LIVE_STREAM: case entryType::LIVE_CHANNEL: // Live stream $renderer = $this->serveLiveEntry(); break; default: KExternalErrors::dieError(KExternalErrors::INVALID_ENTRY_TYPE); } if (!$renderer) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'This format is unsupported'); } $renderer->contributors = array(); $config = new kManifestContributorConfig(); $config->format = $this->deliveryAttributes->getFormat(); $config->deliveryCode = $deliveryCode; $config->storageId = $this->deliveryAttributes->getStorageId(); $config->entryId = $this->entryId; $contributors = KalturaPluginManager::getPluginInstances('IKalturaPlayManifestContributor'); foreach ($contributors as $contributor) { /* @var $contributor IKalturaPlayManifestContributor */ $renderer->contributors = array_merge($renderer->contributors, $contributor->getManifestEditors($config)); } $renderer->entryId = $this->entryId; $renderer->duration = $this->duration; if ($this->deliveryProfile) { $renderer->tokenizer = $this->deliveryProfile->getTokenizer(); } $renderer->defaultDeliveryCode = $this->entry->getPartner()->getDefaultDeliveryCode(); $renderer->lastModified = time(); // Handle caching $canCacheAccessControl = false; if (kConf::hasParam("force_caching_headers") && in_array($this->entry->getPartnerId(), kConf::get("force_caching_headers"))) { $renderer->cachingHeadersAge = 60; $renderer->forceCachingHeaders = true; } if (!$this->secureEntryHelper) { $canCacheAccessControl = true; // TODO: reconsider this if/when expired ktokens will be used } else { if (!$this->secureEntryHelper->shouldDisableCache() && !$this->secureEntryHelper->isKsAdmin() && ($this->secureEntryHelper->isKsWidget() || !$this->secureEntryHelper->hasRules())) { $canCacheAccessControl = true; } } if (!$renderer->tokenizer && $canCacheAccessControl) { // Note: kApiCache::hasExtraFields is checked in kManifestRenderers $renderer->cachingHeadersAge = 60; } if (!$this->secureEntryHelper || !$this->secureEntryHelper->shouldDisableCache()) { $cache = kPlayManifestCacher::getInstance(); $cache->storeRendererToCache($renderer); } // Output the response KExternalErrors::terminateDispatch(); $renderer->output($deliveryCode, $playbackContext); }
public function execute() { $this->seekFrom = $this->getRequestParameter("seekFrom", -1); if ($this->seekFrom <= 0) { $this->seekFrom = -1; } $this->clipTo = $this->getRequestParameter("clipTo", 0); $this->deliveryCode = $this->getRequestParameter("deliveryCode", null); $playbackContext = $this->getRequestParameter("playbackContext", null); $this->protocol = $this->getRequestParameter("protocol", null); if (!$this->protocol || $this->protocol === "null") { $this->protocol = StorageProfile::PLAY_FORMAT_HTTP; } $this->format = $this->getRequestParameter("format"); if (!$this->format) { $this->format = StorageProfile::PLAY_FORMAT_HTTP; } $this->tags = $this->getRequestParameter("tags", null); if (!$this->tags) { switch ($this->format) { case StorageProfile::PLAY_FORMAT_SILVER_LIGHT: $this->tags = array(array(assetParams::TAG_SLWEB)); break; case StorageProfile::PLAY_FORMAT_APPLE_HTTP: case StorageProfile::PLAY_FORMAT_HDS: $this->tags = array(array(assetParams::TAG_APPLEMBR), array('ipadnew', 'iphonenew'), array('ipad', 'iphone')); break; default: $this->tags = array(array(assetParams::TAG_MBR), array(assetParams::TAG_WEB)); } } else { $this->tags = array(array($this->tags)); } $this->cdnHost = $this->getRequestParameter("cdnHost", null); $this->preferredBitrate = $this->getRequestParameter("preferredBitrate", null); $this->maxBitrate = $this->getRequestParameter("maxBitrate", null); if ($this->maxBitrate && (!is_numeric($this->maxBitrate) || $this->maxBitrate <= 0)) { KExternalErrors::dieError(KExternalErrors::INVALID_MAX_BITRATE); } $this->initEntry(); $this->initFlavorIds(); $this->storageId = $this->getRequestParameter("storageId", null); $this->validateStorageId(); $partner = $this->entry->getPartner(); if (!$this->cdnHost || $partner->getForceCdnHost()) { $this->cdnHost = myPartnerUtils::getCdnHost($this->entry->getPartnerId(), $this->protocol); } $playbackParams = array(); if (kConf::hasMap("optimized_playback")) { $partnerId = $this->entry->getPartnerId(); $optimizedPlayback = kConf::getMap("optimized_playback"); if (array_key_exists($partnerId, $optimizedPlayback)) { $playbackParams = $optimizedPlayback[$partnerId]; } } if (array_key_exists('enforce_encryption', $playbackParams) && $playbackParams['enforce_encryption']) { if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') { KExternalErrors::dieError(KExternalErrors::ACCESS_CONTROL_RESTRICTED, 'unencrypted manifest request - forbidden'); } if (strtolower($this->protocol) != 'https') { KExternalErrors::dieError(KExternalErrors::ACCESS_CONTROL_RESTRICTED, 'unencrypted playback protocol - forbidden'); } } $renderer = null; switch ($this->format) { case StorageProfile::PLAY_FORMAT_HTTP: $renderer = $this->serveHttp(); break; case StorageProfile::PLAY_FORMAT_RTMP: $renderer = $this->serveRtmp(); break; case StorageProfile::PLAY_FORMAT_SILVER_LIGHT: $renderer = $this->serveSilverLight(); break; case StorageProfile::PLAY_FORMAT_APPLE_HTTP: $renderer = $this->serveAppleHttp(); break; case StorageProfile::PLAY_FORMAT_HDS: $renderer = $this->serveHds(); break; case "url": $this->format = "http"; // build url for an http delivery $renderer = $this->serveUrl(); break; case "rtsp": $renderer = $this->serveRtsp(); break; case "hdnetworksmil": $renderer = $this->serveHDNetworkSmil(); break; case "hdnetwork": $renderer = $this->serveHDNetwork(); break; case "hdnetworkmanifest": $renderer = $this->serveHDNetworkManifest(); break; } if (!$renderer) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'This format is unsupported'); } $canCacheAccessControl = false; if (!$this->secureEntryHelper) { $canCacheAccessControl = true; // TODO: reconsider this if/when expired ktokens will be used } else { if (!$this->secureEntryHelper->shouldDisableCache() && !$this->secureEntryHelper->isKsAdmin() && ($this->secureEntryHelper->isKsWidget() || !$this->secureEntryHelper->hasRules())) { $canCacheAccessControl = true; } } if (!$renderer->tokenizer && $canCacheAccessControl) { // Note: kApiCache::hasExtraFields is checked in kManifestRenderers $renderer->cachingHeadersAge = 60; } if (!$this->secureEntryHelper || !$this->secureEntryHelper->shouldDisableCache()) { $cache = kPlayManifestCacher::getInstance(); $cache->storeCache($renderer); } $renderer->output($playbackContext); }