sterretje-cluster:content-hosting

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
sterretje-cluster:content-hosting [2012/01/17 11:17] dicksterretje-cluster:content-hosting [2026/05/27 14:01] (current) – external edit 127.0.0.1
Line 14: Line 14:
 van grote bestanden. In het bijzonder flash video's, H264-bestanden en podcasts. van grote bestanden. In het bijzonder flash video's, H264-bestanden en podcasts.
 Vanwege de toegenomen populariteit van met name flash video is content Vanwege de toegenomen populariteit van met name flash video is content
-geschaald om een bandbreedte tussen de 20 en 30 Gbit te kunnen vullen.+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 Om dit mogelijk te maken is het mechanisme achter het contentplatform iets
Line 48: Line 48:
  
 ==== Niet deeplinken aan de redirect urls ==== ==== Niet deeplinken aan de redirect urls ====
-De redirect urls die gegenereerd worden zijn slechts korte tijd (1 minuut) +De redirect urls die gegenereerd worden zijn alleen voor de aanvrager (ip 
-bruikbaar. Stel dat er een request plaatsvond op+adres) bruikbaar.  Stel dat er een request plaatsvond op
 ''http://content.omroep.nl/test/wilhelmus.mp3'' ''http://content.omroep.nl/test/wilhelmus.mp3''
 dan wordt er een tijdelijke redirect gegenereerd worden die er ongeveer zo uit ziet: dan wordt er een tijdelijke redirect gegenereerd worden die er ongeveer zo uit ziet:
-''http://content1a.omroep.nl/3f07ae38c69578928fc5559a97a5cc9f/487320e8/test/wilhelmus.mp3''+''http://content1c.omroep.nl/urishieldv2/l27m4b485f123b8d2a0f00526e3ea1000000.1d2a05c90addf69c1b2968a21dc4e002/test/wilhelmus.mp3''
 Vanaf deze locatie kan het bestand gedownload worden, maar deze link is Vanaf deze locatie kan het bestand gedownload worden, maar deze link is
-niet permanent.+niet deelbaar met anderen.
 Dit is gedaan om ervoor te zorgen dat de uitsplitsing Dit is gedaan om ervoor te zorgen dat de uitsplitsing
 van verkeer naar populariteit goed blijft werken. van verkeer naar populariteit goed blijft werken.
Line 69: Line 69:
 vanaf snelle webservers uitgeserveerd moet worden. vanaf snelle webservers uitgeserveerd moet worden.
  
-==== Timeouts op redirect urls ==== +==== IP afscherming op redirect urls ==== 
-Een redirect url is dus slechts een korte tijd bruikbaarStel nu echter dat +In de redirect URLs zit een afscherming op IP basisDat betekent dat het IP 
-om de +adres van het device dat de originele aanvraag doet 
-een of andere reden een browser te lang "op een redirect url zit" en deze pas +(''content.omroep.nl/test/wilhelmus.mp3'') en 
-opvraagt op het moment dat de houdbaarheid verstreken is. Wat gebeurt er dan? +de uiteindelijke aanvraag 
-In zo'n geval wordt dit herkend door de uitspeelserver en inplaats van het +(''contentXX.omroep.nl/urishield/<hash>/test/wilhelmus.mp3''gelijk moeten 
-request af te keuren stuurt de uitspeelserver een redirect terug naar +zijn.
-het contentplatform, zodat deze weer een nieuwe redirect url kan genereren. +
-Bijvoorbeeld: ''http://content.omroep.nl/test/wilhelmus.mp3'' wordt opgrvraagd. +
-Deze krijgt een redirect naar  +
-''http://content1a.omroep.nl/3f07ae38c69578928fc5559a97a5cc9f/487320e8/test/wilhelmus.mp3'' +
-Vervolgens gebeurt daar een tijdje niks mee en pas na een te lange periode +
-wordt deze url opgevraagd (in dit geval bij content1a.omroep.nl). In zo'n +
-geval genereert content1a.omroep.nl weer een redirect terug naar +
-''http://content.omroep.nl/test/wilhelmus.mp3'', zodat wanneer deze opgevraagd +
-wordt er een nieuwe tijdelijke url gemaakt kan worden.+
  
-In de [[#Redirecten zonder timeouts|appendix]] wordt een idee beschreven om +Voorheen was er een andere afscherming, op basis van tijdelijk houdbare urls. 
-de redirector zonder timeouts te kunnen laten werken+Daar zat geen IP adres in, maar inplaats daarvan een timestampDoor de komst 
- +van mobiele devices die voornamelijk op basis van range requests werken was de 
-=== Bug! === +afscherming op basis van tijdcode niet meer werkbaar (want voor een clip van 1 
-Indien er gebruik gemaakt wordt van +uur lengte blijft een device een uur lang range requests doen en tegen die 
-[[#Hotlink bescherming|hotlink bescherming]] waarbij gebruik gemaakt wordt +tijd is de timeout al lang verlopen). Een lange timeout van -zeg- een uur 
-van de clean url vorm van aanroep (''/secure/$token/$t_hex/pad/naar/clip.flv'') +is niet werkbaar omdat die al zo lang is dat er dan deeplinks de wereld 
-dan werkt bovenstaande terugredirect niet meer. Er wordt dan namelijk bij een +ingeslingerd kunnen worden die voor problemen met de caching kunnen gaan 
-timeout teruggerdirect naar de onbeschermde url (''/pad/naar/clip.flv''+zorgen. en een korte timeout (van een minuut ofzo) in combinatie met een 
-Dat is een bug die op de lijst staat om gefixed te worden. +terugredirect naar de redirector om zo een nieuwe redirect url te genereren 
-Er is echter wel een workaround, namelijk om inplaats van de clean url vorm +blijkt in de praktijk ook niet te werken omdat er dan veel devices blijken te 
-de geparametriseerde vorm te gebruiken +zijn die elk range request  (dwz elke paar secondevia de redirector 
-(''/pad/naar/clip.flv&md5=$token&t=$t_hex'')+opvragen, wat weer voor teveel load op de redirector en de daarachterhangende 
 +machinerie zorgt.
  
 ==== Aanpassen crossdomain.xml ==== ==== Aanpassen crossdomain.xml ====
Line 110: Line 102:
 Op deze manier worden alle servers waar content.omroep.nl naartoe kan redirecten gecovered. Op deze manier worden alle servers waar content.omroep.nl naartoe kan redirecten gecovered.
  
-==== HEAD vs GET requests ==== 
-Het is zo dat niet alle requests een redirect naar een uitspeelserver krijgen. 
-Sommige content (o.a. .html en .swf bestanden) worden door de redirector zelf 
-uitgeserveerd. 
-Verder worden HEAD requests ook altijd direct beantwoord. 
-Het kan dus voorkomen (o.a. voor .flv en .mp3 en .mp4 bestanden) dat een HEAD 
-request op zo'n bestand een direct antwoord krijgt: 
- HEAD /test/wilhelmus.mp3 
- 
- HTTP/1.1 200 OK 
- Date: Thu, 25 Jun 2009 09:01:03 GMT 
- Server: Apache/2.2.9 (Unix) 
- Last-Modified: Thu, 10 Jul 2003 19:09:40 GMT 
- ETag: "8760f-b0d3c-3c21f32ab6500" 
- Accept-Ranges: bytes 
- Content-Length: 724284 
- Content-Type: audio/mpeg 
-maar dat een GET request een redirect krijgt: 
- GET /test/wilhelmus.mp3 
- 
- HTTP/1.1 307 Temporary Redirect 
- Date: Thu, 25 Jun 2009 09:04:48 GMT 
- Server: Apache/2.2.9 (Unix) PHP/5.2.6 
- Location: http://content1b.omroep.nl/1e0562ac97ff9d8df1673ef181de1dbb/4a433db0/test/wilhelmus.mp3 
- Content-Length: 176 
- Content-Type: text/html 
  
-Wij denken dat dit conform [[http://www.ietf.org/rfc/rfc2616.txt|RFC2626]] is. 
  
 ===== GeoIP afscherming ===== ===== GeoIP afscherming =====
Line 143: Line 108:
 in te laten stellen. in te laten stellen.
  
-Hiertoe kan een verzoek bij de NPO ICT Servicedesk ingediend worden.+Hiertoe kan een verzoek bij de NPO Hosting en Streamign ingediend worden via https://support.npohosting.nl.
 In het verzoek moet aangegeven worden: In het verzoek moet aangegeven worden:
  
Line 238: Line 203:
 </code> </code>
  
-Bij de NPO ICT Servicedesk kan een verzoek ingediend worden om bepaalde+Via https://support.npohosting.nl kan een verzoek ingediend worden om bepaalde
 delen van het contentplatform van hotlink bescherming te voorzien. delen van het contentplatform van hotlink bescherming te voorzien.
 In het verzoek moet aangegeven worden: In het verzoek moet aangegeven worden:
Line 258: Line 223:
 of requests op links waarvan de timeout verstreken is of requests op links waarvan de timeout verstreken is
 krijgen een "HTTP 403 Forbidden" statuscode terug. 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 ===== ===== Hotlink bescherming zonder timeouts =====
Line 282: Line 275:
 De eerste stap is dat er vantevoren wordt ingesteld dat er op een De eerste stap is dat er vantevoren wordt ingesteld dat er op een
 bepaald gedeelte van de content challenge-response authenticatie bepaald gedeelte van de content challenge-response authenticatie
-plaats moet vinden. Hiertoe kan een verzoek bij de NPO ICT Servicedesk ingediend+plaats moet vinden. Hiertoe kan een verzoek via https://support.npohosting.nl ingediend
 worden. In het verzoek moet aangegeven worden:  worden. In het verzoek moet aangegeven worden: 
   - De prefix van de content die beschermd moet worden (b.v.  /xrtv/clips/afgeschermd)   - De prefix van de content die beschermd moet worden (b.v.  /xrtv/clips/afgeschermd)
Line 343: Line 336:
 waarmee op basis van tijdcodes geskipped kan worden in h264 encoded mp4 waarmee op basis van tijdcodes geskipped kan worden in h264 encoded mp4
 bestanden. bestanden.
-Momenteel wordt deze module losgelaten op alle '.m4v' en '.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 Daarnaast is het mogelijk om in mp3's te skippen door een
-byte-offset mee te geven met de "start=" parameter+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 Er kan dus aan content gelinked worden middels
 <code> <code>
Line 353: Line 359:
 waarbij de content de eerste $offset bytes zal skippen. waarbij de content de eerste $offset bytes zal skippen.
  
-Vanaf begin 31 januari 2012 zullen ook ''end='' parameters gehonoreerd worden die gebruikt kunnen worden +Om de byterange van ''$offset1'' tot ''$offset2'' uit te spelen kan er gelinked
-om een eindpunt aan te geven. Om de byterange van ''$offset1'' tot ''$offset2'' uit te spelen kan er gelinked+
 worden middels worden middels
 <code> <code>
Line 374: Line 379:
 Response headers kunnen gezet worden door in het request toe te voegen: Response headers kunnen gezet worden door in het request toe te voegen:
  sethdr=<Header>:<Value>  sethdr=<Header>:<Value>
 +of voor het zetten van meerdere headers:
 +        sethdr1=<Header1>:<Value1>
 +        sethdr2=<Header2>:<Value2>
 +        sethdr3=<Header3>:<Value3>
 +        ...
 +
 Bijvoorbeeld, onderstaande URL: Bijvoorbeeld, onderstaande URL:
  http://content.omroep.nl/test/wilhelmus.mp3?sethdr=Content-Type:application/octet-stream  http://content.omroep.nl/test/wilhelmus.mp3?sethdr=Content-Type:application/octet-stream
 leidt ertoe dat in de response de volgende header voorkomt: leidt ertoe dat in de response de volgende header voorkomt:
  Content-Type: application/octet-stream  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 Uit veiligheidsoverwegingen kunnen geen willekeurige response headers gezet
-worden op deze manier. Uitsluitend Content-Type en X-* headers kunnen gezet +worden op deze manier. Uitsluitend de volgende headers kunnen gezet worden: 
-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 meegenomenVoorbeeld: 
 +  * http://content.omroep.nl/test/journaal.m4v?pure=true&sethdr1=Content-Type:application/octet-stream&sethdr2=Content-Disposition:attachment
  
-Bovendien is deze optie alleen beschikbaar voor .mp3 bestanden. 
-Op verzoek kan deze ook op andere types bestanden geactiveerd worden. 
  
 ===== Ondersteuning van de iPhone media player ===== ===== 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. De iPhone media player gaat niet goed samen met de huidige opzet van het contentplatform.
 Dat komt omdat deze zicht niet houdt aan het Dat komt omdat deze zicht niet houdt aan het
Line 473: Line 502:
  
 ===== Appendix ===== ===== Appendix =====
- 
-==== Redirecten zonder timeouts ==== 
-in sectie [[#Timeouts op redirect urls]] wordt uitgelegd dat de door het contentplatform 
-gegenereerde redirects naar de uitspeelservers slechts korte tijd houdbaar zijn 
-en dat als die tijd verstreken is de uitspeelserver je weer terugredirect naar 
-content.omroep.nl (die dan op zijn beurt weer een verse redirect naar een uitspeelserver 
-kan maken) 
- 
-Het is denkbaar dat er clients bestaan die hier niet tegen kunnen. 
-Stel je voor dat een client een aantal deelrequests doet (met range headers 
-ofzo), dan zou deze dus steeds een HTTP 206 statuscode terugkrijgen maar na 
-het verstrijken van de timeout "opeens" een HTTP 301 redirect terugkrijgt. 
-(de iPhone player overkomt dit, maar die gaat er wel goed mee om, dus daar 
-speelt het probleem niet) 
- 
-In zo'n geval zou het aardig zijn als de redirects langer houdbaar zouden 
-zijn of uberhaupt niet aan een timeout gebonden zouden zijn. 
-Bij het originele request zou je dan aankunnen geven dat je een ander 
-soort redirect wilt: 
- http://content.omroep.nl/xrtv/file.mp3?redirectstyle=... 
- 
-Er is een manier om dit te implementeren, maar omdat het niet triviaal is 
-bieden we deze vorm nog niet aan. De gedachte is dat op het moment dat de 
-redirector een redirect naar een uitspeelserver genereert, de redirector de 
-uitspeelserver zou kunnen inseinen dat er een download aan zit te komen. 
-De uitspeelserver honoreert vervolgens alleen "vantevoren ingeseinde" downloads 
-en reject de rest. Om te voorkomen dat deze ingeseinde contents als deeplinks 
-gebruikt kunnen worden valt er te denken aan een IP check (het client IP adres 
-bij de redirector en uitspeelserver moet gelijk zijn) of een limiet op aantal 
-requests op een uitspeelserver. 
- 
-Hiervoor is het nodig dat er ergens state wordt bewaard tussen de redirector 
-en de uitspeelservers ("client X mag een request voor voor clip Y doen") 
-Een mogelijkheid is om deze state in de uitspeelserver te bewaren. 
-Onze uitspeelservers zijn 
-[[http://www.lighttpd.net/|lighttpd]] instanties met 
-[[http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModMagnet|ingecompileerde]] 
-[[http://www.lua.org/|lua]] support. 
-Het is mogelijk om 1 lua scriptje te maken dat enerzijds door de redirector 
-aangeroepen kan worden om een request in te schieten. Dit script kan deze 
-informatie dan in de zogenaamde "Global State" (de _G table in lua) op slaan. 
-Aan de andere kant wordt dit script bij het uitserveren van content weer 
-aangeroepen om een request tegen de inhoud van de Global state te houden 
-en al dan niet door te laten. 
-De global state bevindt zich gewoon in het geheugen van de webserver en het 
-voordeel van deze aanpak is dat er dus geen extra componenten (memcached, 
-mysql oid) nodig zijn. 
-Van tijd tot tijd zal er wat garbage collection nodig zijn om de grootte van de 
-global state binnen de perken te houden. Bijvoorbeeld 1x per nacht oude 
-zaken opruimen. 
- 
-Ondat in het huidige contentplatform de redirector percies weet naar 
-welke uitspeelserver er geredirect gaat worden (dwz: er zit geen loadbalancer 
-oid tussen) hoeft de redirector alleen maar die ene specifieke content 
-server in te seinen. 
- 
-Als er wel een loadbalancer gebruikt zou worden, dan zou het misschien 
-logischer zijn om het andersom te implementeren: de state wordt dan 
-bijgehouden in de buurt van de redirector en de uitspeelservers checken 
-het daar alvorens een request te honoreren. Nadeel daarvan is dat lighttpd in 
-essentie stilstaat gedurende de executie tijd van een lua script, en aangezien 
-dat checken relatief lang kan duren (opzetten van tcp connectie) kan het 
-eigenlijk niet meer in lua en moeten de uitspeelservers opeens iets met php 
-oid gaan doen, wat het allemaal veel zwaarder zou maken. 
  
 ===== Vragen? ===== ===== Vragen? =====
-Voor vragen over het contentplatform kunt u zich wenden tot de NPO ICT Servicedesk, +Voor vragen over het contentplatform kunt u zich tot ons wenden via https://support.npohosting.nl of door ons te bellen via 035-3333355.
-welke te bereiken is via [[mailto:servicedesk@omroep.nl|servicedesk@omroep.nl]] telefoon 035 67 73 555.+
  
  • sterretje-cluster/content-hosting.1326795433.txt.gz
  • Last modified: 2026/05/27 14:01
  • (external edit)