This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== Gebruik van content.omroep.nl ====== Dit document beschrijft het gebruik van http://content.omroep.nl Het contentplatform is meer dan 1 simpele webserver; het is een samenspel van webservers en scripts die ervoor moeten zorgen dat er via content minimaal tussen 20-30 Gbit per seconde aan dataverkeer naar buiten geduwd kan worden. Er wordt uitgelegd waar rekening mee te houden bij het gebruik van http://content.omroep.nl en hoe de GeoIP en anti-hotlink features gebruikt kunnen worden. ===== Inleiding ===== content.omroep.nl is een webserveromgeving die bedoeld is voor het uitserveren van grote bestanden. In het bijzonder flash video's, H264-bestanden en podcasts. Vanwege de toegenomen populariteit van met name flash video is content geschaald om een bandbreedte tussen de 50 en 100 Gbit te kunnen vullen. Om dit mogelijk te maken is het mechanisme achter het contentplatform iets aangepast, dit staat uitgelegd in de sectie [[#redirector|Redirector]] Tegelijkertijd is de functionaliteit van het contentplatform uitgebreid. Het is nu ook mogelijk om content af te schermen op basis van [[#GeoIP afscherming|GeoIp]] of om te beschermen tegen [[#Hotlink bescherming|hotlinks]] Daarnaast is het mogelijk om voor flash video (zowel flv als h264) en mp3 files [[#Pseudo streaming|pseudo streaming]] te doen. Ook kan er gebruik gemaakt worden van een extra content-type tag om bijvoorbeeld [[#Geforceerde downloads|geforceerde downloads]] te faciliteren. ===== Redirector ===== Bij een "normale" webserver is het meestal zo dat als er een bestand opvraagd wordt, de webserver een HTTP status code 200 teruggeeft en het bestand direct zelf uitserveert. Bij content.omroep.nl is dat niet meer zo, in verband met de schaalgrootte van de hele omgeving. Als er nu bij het contentplatform een bestand opgevraagd wordt, dan kan het voorkomen dat content niet zelf het bestand uitserveert, maar een redirect stuurt ("HTTP 307 Temporary Redirect" status code) naar een uitspeelserver die de uiteindelijke content uit kan serveren. Dit is een standaard HTTP response, die door alle browsers ondersteund wordt. Vervolgens zal de browser het bestand ophalen bij de webserver waar naar geredirect wordt. Deze verwijzing is nodig om het verkeer uit te kunnen splitsen naar populariteit. Populaire bestanden kunnen op deze manier vanaf snelle webservers uitgeserveerd worden, terwijl de minder populaire bestanden vanuit het archief uitgeserveerd kunnen worden. ==== Niet deeplinken aan de redirect urls ==== De redirect urls die gegenereerd worden zijn alleen voor de aanvrager (ip adres) bruikbaar. Stel dat er een request plaatsvond op ''http://content.omroep.nl/test/wilhelmus.mp3'' dan wordt er een tijdelijke redirect gegenereerd worden die er ongeveer zo uit ziet: ''http://content1c.omroep.nl/urishieldv2/l27m4b485f123b8d2a0f00526e3ea1000000.1d2a05c90addf69c1b2968a21dc4e002/test/wilhelmus.mp3'' Vanaf deze locatie kan het bestand gedownload worden, maar deze link is niet deelbaar met anderen. Dit is gedaan om ervoor te zorgen dat de uitsplitsing van verkeer naar populariteit goed blijft werken. Stel dat op enig moment /test/wilhelmus.mp3 niet populair is, dan wordt er naar een archief server verwezen. Als nou deze verwijzing ergens permanent opgeslagen zou worden en /test/wilhelmus.mp3 wordt opeens heel populair, dan kan die archief server de grote load niet aan. Het is dus zeer wenselijk dat volgende requests op dit bestand via een snelle webserver uitgeserveerd worden. Oftewel, die redirect link moet vooral niet permanent op een site komen, in plaats daarvan moet altijd de oorspronkelijke url: ''http://content.omroep.nl/test/wilhelmus.mp3'' gebruikt worden, zodat van moment tot moment bijgehouden kan worden wat populair is en dus vanaf snelle webservers uitgeserveerd moet worden. ==== IP afscherming op redirect urls ==== In de redirect URLs zit een afscherming op IP basis. Dat betekent dat het IP adres van het device dat de originele aanvraag doet (''content.omroep.nl/test/wilhelmus.mp3'') en de uiteindelijke aanvraag (''contentXX.omroep.nl/urishield/<hash>/test/wilhelmus.mp3'') gelijk moeten zijn. Voorheen was er een andere afscherming, op basis van tijdelijk houdbare urls. Daar zat geen IP adres in, maar inplaats daarvan een timestamp. Door de komst van mobiele devices die voornamelijk op basis van range requests werken was de afscherming op basis van tijdcode niet meer werkbaar (want voor een clip van 1 uur lengte blijft een device een uur lang range requests doen en tegen die tijd is de timeout al lang verlopen). Een lange timeout van -zeg- een uur is niet werkbaar omdat die al zo lang is dat er dan deeplinks de wereld ingeslingerd kunnen worden die voor problemen met de caching kunnen gaan zorgen. en een korte timeout (van een minuut ofzo) in combinatie met een terugredirect naar de redirector om zo een nieuwe redirect url te genereren blijkt in de praktijk ook niet te werken omdat er dan veel devices blijken te zijn die elk range request (dwz elke paar seconde) via de redirector opvragen, wat weer voor teveel load op de redirector en de daarachterhangende machinerie zorgt. ==== Aanpassen crossdomain.xml ==== Flash (swf) bestanden gebruiken een bestand genaamd ''crossdomain.xml'' om te zien in hoeverre redirects gehonoreerd mogen worden. Wij adviseren om in crossdomain.xml de volgende entry op te nemen: <code> <allow-access-from domain="content*.omroep.nl" /> </code> Op deze manier worden alle servers waar content.omroep.nl naartoe kan redirecten gecovered. ===== GeoIP afscherming ===== Het is mogelijk om op bepaalde delen van het contentplatform GeoIP afscherming in te laten stellen. Hiertoe kan een verzoek bij de NPO Hosting en Streamign ingediend worden via https://support.npohosting.nl. In het verzoek moet aangegeven worden: * Welk deel van GeoIP afscherming voorzien moet worden. B.v. ''/xrtv/clips/afgeschermd'' * Voor welke regio de GeoIP afscherming geldt. Dit kan uitsluitend op landen niveau. B.v. Nederland of Nederland+Antillen. * Een redirect url waar naar verwezen kan worden indien men niet door de geoip check komt. Bijvoorbeeld: ''http://www.xrtv.nl/geo-sorry-page.html'' Nadat dit ingesteld is zullen alle requests op content onder ''http://content.omroep.nl/xrtv/clips/afgeschermd'' tegen een GeoIP check aangehouden worden. Slaagt de check dan wordt men geredirect naar de eigenlijke content. Faalt de test dan gaat de redirect naar ''http://www.xrtv.nl/geo-sorry-page.html'' === Uitzonderingen ==== Niet alle extensies worden door door GeoIP afscherming beschermd. Er zijn een aantal uitzonderingen welke direct door de proxy behandeld worden. Het kan dus zijn dat bij het testen of de GeoIP afscherming goed zijn werk doet, er een resultaat terugkomt wat misschien onverwacht is. De volgende extensies worden niet afgeschermd door GeoIP: * xml * html * swf * ico * txt * m3u8 * jpg * gif * png * js ===== Hotlink bescherming ===== Het is mogelijk om op bepaalde delen [[http://en.wikipedia.org/wiki/Inline_linking|hotlink]] afscherming in te laten stellen. Met hotlink afscherming kan ervoor gezorgd worden dat er niet meer direct vanaf een externe site naar bepaalde content op het contentplatform gelinked kan worden. Links naar deze content worden alleen gehonoreerd indien er een juiste code meegegeven wordt die berekend is op basis van een geheim password, een timestamp en het pad naar de content. Op deze manier kan ervoor gezorgd worden dat b.v. alleen vanuit uw eigen website gelinkt kan worden naar deze content, om er zeker van te zijn dat de content in de gewenste context getoond wordt. Het mechanisme werkt op basis van zgn tokens. Een token is een md5 hash van de concatenatie van: * een geheime string * het pad van de te contenten content * een timestamp in hex Gewapend met een token en een timestamp in hex kan er op twee manieren aan de content gelinked worden: * Als HTTP GET parameters md5 en t: <code> http://content.omroep.nl/pad/naar/clip.flv?md5=$token&t=$t_hex </code> * Als clean url, beginnend met de string "/secure" en vervolgens de md5 en t parameters in de url verwerkt: <code> http://content.omroep.nl/secure/$token/$t_hex/pad/naar/clip.flv </code> Het is gebleken dat de tweede variant (met /secure) het beter doet in flash players, deze vallen namelijk over de meegegeven HTTP get parameters van de eerste variant. Hieronder is een stukje voorbeeld code in php voor het genereren van de urls. Voorbeelden in andere programmeertalen staan [[http://redmine.lighttpd.net/wiki/lighttpd/|op de website van lighttpd]] <code php> <?php $secret = "heelgeheimpassword"; $uri = "/xrtv/clips/afgeschermd/file.flv"; $server = "content.omroep.nl"; $t_hex = sprintf("%08x", time()); $token = md5($secret.$uri.$t_hex); $url1 = sprintf("http://%s%s?md5=%s&t=%s", $server,$uri,$token,$t_hex); $url2 = sprintf("http://%s/secure/%s/%s%s", $server,$token,$t_hex,$uri); printf('<a href="%s">Link style 1</a>', $url); printf('<a href="%s">Link style 2</a>', $url); ?> </code> Via https://support.npohosting.nl kan een verzoek ingediend worden om bepaalde delen van het contentplatform van hotlink bescherming te voorzien. In het verzoek moet aangegeven worden: * Welk deel van hotlink bescherming voorzien moet worden. Bijvoorbeeld ''/xrtv/clips/incontextonly'' * Het secret dat gebruikt wordt voor het genereren va het token (dit secret moet tegelijkertijd aan beide kanten bekend zijn en kan dus niet zomaar aan een van beide kanten gewijzigd worden!) * Een timeout die aangeeft hoe lang de tijdelijke urls geldig mogen blijven * Een optionele pagina waarheen verwezen kan worden als iemand een ongeldige pagina bezoekt Nadat dit is ingesteld zullen links voor content onder ''http://content.omroep.nl/xrtv/clips/incontextonly'' alleen gehonoreerd worden indien de correcte md5 hash en timestamp meegegeven worden. Requests met verkeerde waardes voor de md5 hash of requests op links waarvan de timeout verstreken is krijgen een "HTTP 403 Forbidden" statuscode terug. ==== Meerdere shared secrets op dezelfde uri ==== Het kan voorkomen dat meerdere applicaties bij dezelfde content moeten kunnen, maar dat het niet gewenst is om die applicaties onderling hetzelfde secret te laten delen. In dit geval kan er een extra parameter genaamd ''appname'' meegegeven worden. Aan elke ''appname'' kan een eigen shared secret gekoppeld worden. Stel de configuratie ziet er zo uit: ^ uri ^ appname ^ shared secret ^ | ''/xrtv/clips/incontextonly'' | NULL | "default_secret" | | ''/xrtv/clips/incontextonly'' | npoplayer | "npo_secret" | | ''/xrtv/clips/incontextonly'' | xrtvplayer | "xrtv_secret" | Afhankelijk van hoe de clip aangeroepen wordt, kunnen nu verschillende shared secrets gebruikt worden: ^ url ^ shared secret ^ | ''http://content.omroep.nl/secure/$token/$t_hex/xrtv/clips/incontextonly/file.flv'' | "default_secret" | | ''http://content.omroep.nl/secure/$token/$t_hex/xrtv/clips/incontextonly/file.flv?appname=randomzooi'' | "default_secret" | | ''http://content.omroep.nl/secure/$token/$t_hex/xrtv/clips/incontextonly/file.flv?appname=npoplayer'' | "npo_secret" | | ''http://content.omroep.nl/secure/$token/$t_hex/xrtv/clips/incontextonly/file.flv?appname=xrtvplayer'' | "xrtv_secret" | Wat **niet** kan is voor de ene app __wel__ en voor de andere __geen__ afscherming te doen. Dwz zo gauw je ergens afscherming op zet is het voor alles afgeschermd. Hooguit heb je keuze met wel secret je toegang gaat krijgen. ===== Hotlink bescherming zonder timeouts ===== In sectie [[#Hotlink bescherming]] wordt uitgelegd hoe op bepaalde delen van de content ervoor gezorgd kan worden dat er niet meer vanaf externe (dwz ongeauthoriseerde) sites naar gelinkt kan worden. Deze stijl van hotlink bescherming heeft ook een tijdscode in zich en hier zou het dus ook kunnen gebeuren dat een browser te lang op een URL zit, waardoor deze niet meer geldig is op het moment dat ie opgevraagd wordt. Een oplossing in dit geval is een challenge-response protocol. De gedachte hier is dat we in de redirector state bij gaan houden en op basis van die state kunnen besluiten om na een redirect wegens timeout een nieuwe redirect te maken. De hotlink bescherming gebeurt hier dan niet door het maken van een /secure url, maar door een challenge/response conversatie. Inplaats van 1 request zijn er nu 2 requests; eerst een request om een challenge op te vragen, en daarna pas het "echte" request op de eigenlijke data, waar in het eigenlijke request ("geef mij clip x") ook een response op de challenge zit. De eerste stap is dat er vantevoren wordt ingesteld dat er op een bepaald gedeelte van de content challenge-response authenticatie plaats moet vinden. Hiertoe kan een verzoek via https://support.npohosting.nl ingediend worden. In het verzoek moet aangegeven worden: - De prefix van de content die beschermd moet worden (b.v. /xrtv/clips/afgeschermd) - Hoeveel maal een afgeschermde URL opgevraagd mag worden na een succesvolle challenge-response dialoog (default 1) - Of er een IP check plaats moet vinden die kijkt of de aanvrager van de challenge hetzelfde IP adres heeft als de aanvrager van de content (default true) - een geheime string die wordt gebruikt om een response te kunnen maken op basis van een gegeven challenge - een redirect url waarnaartoe verwezen moet worden indien gepoogd wordt de content op te vragen zonder dat daar een succesvole challenge-response dialoog aan vooraf is gegaan Nadat bovenstaande zaken zijn ingesteld werkt het als volgt: De challenge is op te vragen door een extra parameter "getchallenge" mee te geven. Bijvoorbeeld: http://content.omroep.nl/xrtv/clips/afgeschermd/file.flv?getchallenge Deze levert een id en een challenge, welke zowel in de headers als in een stukje xml terugkomen. De headers zijn <code> X-Id: [het id] X-Challenge: [de challenge] </code> De xml ziet er zo uit <code> <xml> <id>[het id]</id> <challenge>[de challenge]</challenge> </xml> </code> Vervolgens moet uw applicatie de response uitrekenen en samen met het id aan het contentplatform geven. De response is de md5 hash van de geheime string, de opgevraagde clip en de challenge. In php zou het er zo uit zien <code> $secret = "heelgeheimpassword"; $uri = "/xrtv/clips/afgeschermd/file.flv"; $challenge = "2a9f101b"; # de challenge zoals die uit ?getchallenge kwam $response = md5($secret . $uri . $challenge); </code> Het doorgeven van het id en de response gaat met de ''id'' en ''response'' parameters. Als in: http://content.omroep.nl/xrtv/clips/afgeschermd/file.flv?id=$id&response=$response Dit request wordt door de contentserver gevalideerd en indien de validatie slaagt volgt er een redirect naar de eigenlijke content. ===== Pseudo streaming ===== Onze webserverfarm ondersteunt een vorm van pseudo streaming voor flash video bestanden die het mogelijk maakt om te skippen in video, nog voordat deze helemaal gecontent is. Gebruik hiervan staat [[http://blog.lighttpd.net/articles/2006/03/09/flv-streaming-with-lighttpd|hier]] uitgelegd. Voor h264-bestanden maken we gebruik van de [[http://h264.code-shop.com/trac/wiki|mod_h264_streaming]] module (versie 2) waarmee op basis van tijdcodes geskipped kan worden in h264 encoded mp4 bestanden. Momenteel kan deze worden module losgelaten op '.m4v' en '.mp4' bestanden. Let op: deze module past de inhoud van de h264 bestanden aan; de headers worden naar het begin v/d file gemoved zodat browsers meteen aan het begin v/h inladen v/e bestand informatie over tijdcodes tot hun beschikking hebben en er meteen in bestanden gesprongen kan worden. Indien het bestand as-is uitgeserveerd moet worden kan dat door de volgende parameter aan de url toe te voegen: * pure=true De regeltjes voor het al-dan-niet gebruiken van deze module zijn: * normaliter wordt deze module niet gebruikt, dus als je een willekeurig mp4 of m4v bestand aanroept zonder verdere parameters dan wordt de module niet gebruikt en wordt het bestand as-is uitgevoerd. * pas als er een ''start='' of ''end='' parameter wordt meegegeven dan wordt de module geactiveerd * uitzondering hierop is een enkele ''start=0''. dan wordt de module **niet** geactiveerd * bij een combinatie ''start=0&start=N'' wordt de module **wel** geactiveerd (en "wint" de laatste ''start=N'') Daarnaast is het mogelijk om in mp3's te skippen door een byte-offset mee te geven met de "start=" parameter en een einde aantegeven met de "end=" parameter. Er kan dus aan content gelinked worden middels <code> http://content.omroep.nl/xrtv/file.mp3?start=$offset </code> waarbij de content de eerste $offset bytes zal skippen. Om de byterange van ''$offset1'' tot ''$offset2'' uit te spelen kan er gelinked worden middels <code> http://content.omroep.nl/xrtv/file.mp3?start=$offset1&end=$offset2 </code> Default wordt het begin van de file als ''start'' en het eind van de file als ''end'' waarde genomen. Indien er een range opgegeven wordt die niet gehonoreerd kan worden (b.v. ''start > end'' of ''end > filesize'') dan wordt er een ''HTTP Error 416 Requested Range not satisfiable'' gegenereerd. ===== Geforceerde downloads ===== Het Content-Type dat de webserver teruggeeft hangt af van het filetype dat wordt opgevraagd. Bijvoorbeeld, alls .mp4 bestanden krijgen "video/mp4" als Content-Type. Dat mechanisme zorgt ervoor dat je browser de geschikte actie uit kan voeren, bv een player opstarten die mp4 bestanden kan afspelen. Soms is dit echter niet gewenst. Dan wil je dat het bestand gewoon opgeslagen wordt ipv afgespeeld. Dit kan afgedwongen worden door een custom Content-Type "application/octet-stream" mee te laten geven. Response headers kunnen gezet worden door in het request toe te voegen: sethdr=<Header>:<Value> of voor het zetten van meerdere headers: sethdr1=<Header1>:<Value1> sethdr2=<Header2>:<Value2> sethdr3=<Header3>:<Value3> ... Bijvoorbeeld, onderstaande URL: http://content.omroep.nl/test/wilhelmus.mp3?sethdr=Content-Type:application/octet-stream leidt ertoe dat in de response de volgende header voorkomt: Content-Type: application/octet-stream Speciale karakters in headers kunnen via [[http://www.w3schools.com/tags/ref_urlencode.asp|url encoding]] doorgegeven worden, het simpelst door een ''+'' voor een spatie te gebruiken. B.v. sethdr=X-Test:test+met+spaties Uit veiligheidsoverwegingen kunnen geen willekeurige response headers gezet worden op deze manier. Uitsluitend de volgende headers kunnen gezet worden: * X-* * Content-Type * Content-Description * Content-Disposition * Content-Transfer-Encoding Deze optie is beschikbaar voor alle type bestanden m.u.v. de volgende types: * *.xml, *.html, *.swf, *.ico, *.txt, *.m3u8, *.jpg, *.gif, *.png, *.js: deze worden door de redirector zelf afgehandeld en deze heeft niet de mogelijkheid return headers in te stellen. Voor de volgende types gelden speciale regels: * *.mp4, *.m4v Deze bestanden worden normaliter door de [[#pseudo_streaming|pseudo streaming]] module afgehandeld. Deze pikt het request af voordat eventuele response headers gezet kunnen worden. De workaround is om ''&pure=true'' toe te voegen aan de query string. Op die manier wordt het bestand "as-is" uitgeserveerd en worden de response headers wel meegenomen. Voorbeeld: * http://content.omroep.nl/test/journaal.m4v?pure=true&sethdr1=Content-Type:application/octet-stream&sethdr2=Content-Disposition:attachment ===== Ondersteuning van de iPhone media player ===== FIXME: onderstaande sectie is niet meer van toepassing, omdat er tegenwoordig geen timestamps meer zitten in de redirect links. De iPhone media player gaat niet goed samen met de huidige opzet van het contentplatform. Dat komt omdat deze zicht niet houdt aan het [[#Niet deeplinken aan de redirect urls|niet hergebruiken van redirect urls]] adagium. Zie http://mobiforge.com/developing/story/content-delivery-mobile-devices > Apple iPhone uses HTTP byte-ranges for requesting audio and video files. > First, the Safari Web Browser requests the content, and if it's an audio or > video file it opens it's media player. The media player then requests the > first 2 bytes of the content, to ensure that the Webserver supports byte-range > requests. Then, if it supports them, the iPhone's media player requests the > rest of the content by byte-ranges and plays it. Als de MPMoviePlayerController class gebruikt wordt, en het object wordt geinitialiseerd met initWithContentURL dan doet Safari het eerste request. Die krijgt van de redirector de deeplink naar de uitspeelserver terug. Die deeplink wordt aan de media player gegeven en die wordt steeds hergebruikt. Dit resulteert erin dat de iphone player dezelfde deeplink (met steeds andere range headers) op blijft vragen en dus na korte tijd tegen de timeout van de uitspeelserver opbotst. Wat valt hier nou tegen te doen? ==== Terugredirecten bij timeout ==== In de uitspeelservers waarnaartoe geredirect wordt zit al [[#Timeouts op redirect urls|support]] om netjes om te gaan met oude links. Als er namelijk request binnenkomt op een link waarvan de tijdsduur vertreken is, dan wordt er een redirect (HTTP 301) terug naar de redirector gegenereerd. Op zijn beurt zal de redirector weer een verse nieuwe deeplink naar een uitspeelserver genereren die vervolgens gebruikt kan worden. De situatie is dus dat de player al een aantal deelrequests heeft gedaan, steeds HTTP 206 (partial content) terugkrijgt en na het zoveelste request "opeens" een HTTP 301 terugkrijgt. Uit testen blijkt dat de iphone player dit snapt. Derhalve is er bij onbeschermde content geen probleem voor de iPhone player. Maar content waar hotlink afscherming op van toepassing is heeft wel een probleem in dit scenario. ==== Bug in hotlink afscherming ==== Het terugredirecten bij een timeout kan dus werken voor onbeschermde content, maar heeft een probleem bij content waar hotlink protectie op van toepassing is. Er wordt namelijk teruggeredirect naar een onbeschermde url, die dus niet gehonoreerd zal worden voor de delen van het contentplatform waar hotlink protectie op van toepassing is. En op die manier zal men toch eindigen met een HTTP 401 Forbidden code. Dit probleem doet zich alleen maar voor bij content die gelinkt wordt als http://content.omroep.nl/secure/$token/$t_hex/pad/naar/clip.flv Indien de alternatieve manier van linken gebruikt wordt: http://content.omroep.nl/pad/naar/clip.flv?md5=$token&t=$t_hex dan worden de parameters doorgestuurd naar de uitspeelservers en zullen bij een timeout op de uitspeelserver ook weer terugkomen. Zoals uitgelegd in sectie [[#Timeouts op redirect urls]] is dit een bug, welke op de nominatie staat om gefixed te worden. ==== Timeouts in hotlink afscherming ==== So far, so good. Maar, in die hotlink urls zit ook een timecode en is ook een timeout op van toepassing. In geval van de iPhone player betekent dat dat content voor deze player een langere hotlink timeout nodig gaat hebben. Want, wat gebeurt er: - er wordt door de applicatie een link (compleet met ''$token'' en ''$t_hex'') gegenereerd - deze gaat naar het contentplatform - het contentplatform redirect naar een uitspeelserver - de iPhone player gaat stukje bij beetje (range requests) de data opvragen - op enig moment loopt deze aan te gen de timeout van de uitspeelserver - die redirect terug naar content.omroep.nl - op het contentplatform vind de hotlink check weer plaats - als de hotlink timeout nog niet verstreken is dan wordt er weer een redirect naar een uitspeelserver gegenereerd - lather, rinse, repeat - op enig moment is de hotlink timeout **wel** verstreken - en dan krijg je van de redirector een redirect naar een "sorry de timeout is verstreken" pagina. In tegenstelling tot de uitspeelserver timeout is de hotlink timeout per applicatie in te stellen. Op zich volstaat het dus om de hotlink timeout flink op te rekken, als deze langer is dan de lengte van het langste clipje, dan is er weinig aan de hand. Vandaar dat wij ook een anti hotlink mechanisme bieden dat niet gebaseerd is op timeouts, zie [[#Hotlink bescherming zonder timeouts]] ===== Appendix ===== ===== Vragen? ===== Voor vragen over het contentplatform kunt u zich tot ons wenden via https://support.npohosting.nl of door ons te bellen via 035-3333355. sterretje-cluster/content-hosting.txt Last modified: 2026/05/27 14:01by 127.0.0.1 Log In