123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- #
- # internet-radio-recorder lighttpd configuration
- # /usr/share/doc/lighttpd-doc/configuration.txt.gz
- #
- ##
- ## # URLs & Routes
- ##
- ## / list of everything (HTML)
- ##
- ## ## Stations
- ##
- ## /stations/ list of all stations (HTML)
- ## /stations/b2/now redirect to current broadcast on station
- ## /stations/b2/about.rdf RDF describing the station
- ## /stations/b2/app/station.cfg lua table describing the station
- ##
- ## ## Broadcasts
- ##
- ## /stations/b2/2009/12/31/1830%20radioMikro logical full address of a single broadcast
- ## /stations/b2/2009-12-31T18:35:17+01:00 point in time (=> single broadcast)
- ##
- ## /stations/b2/2009/12/31/1830%20radioMikro.xml storage of future or current day broadcasts (technical)
- ## /stations/b2/2009/12/31/1830%20radioMikro.json podcast/channel (technical)
- ## /stations/b2/2009/12/31/index.xml.gz storage of past days' broadcasts (technical)
- ## /stations/b2/2009/12/31/index#T1830 anchor of past days' broadcast (technical)
- ##
- ## /stations/modified.ttl recent changes (current day)
- ## /stations/b2/modified.ttl recent changes per station (current day)
- ##
- ## ## Podcasts / Recording channels
- ##
- ## /podcasts/ list of all podcasts (HTML)
- ## /podcasts/pumuckl/app/podcast.cfg podcast/channel settings
- ## /podcasts/pumuckl.rss RSS feed (logical)
- ## /podcasts/pumuckl/boradcasts.rss RSS feed (technical)
- ## /podcasts/pumuckl/boradcasts.ics iCal calendar
- ##
- ## /podcasts/pumuckl/b2/2011/08/26/1830%20radioMikro podcast/channel member candidate (logical)
- ##
- ## ## Enclosures / Recording mp3s
- ##
- ## /enclosures/b2/2011/08/26/1830%20radioMikro.mp3 past recording (technical)
- ## /enclosures/b2/2021/08/26/1830%20radioMikro.pending future recording (technical)
- ##
- var.baseurl = "/"
- var.auth_realm = "Radio Pi"
- var.auth_method = "digest"
- # for legal reasons mp3 access must be restricted, http://de.wikipedia.org/wiki/Privatkopie#Deutschland :
- # see /usr/share/doc/lighttpd/authentication.txt.gz
- auth.backend = "htdigest"
- auth.backend.htdigest.userfile = "/etc/lighttpd/internet-radio-recorder.user.htdigest"
- #
- $HTTP["useragent"] =~ "^AppleCoreMedia/.*\((iP)" {
- # Workaround for Apples Podcast App.
- # 1. does a HEAD request on mp3 with user agent "Podcasts/2.1.2" (auth works if required for HEAD requests)
- # 2. does a GET request on mp3 with user agent "AppleCoreMedia/1.0.0.11D257 (iPhone; U; CPU OS 7_1_2 like Mac OS X; de_de)" (strangely drops credentials => auth fails)
- # so we just allow all such GET requests :-(
- # Really strange is, that PLAYING the mp3 (also agent "AppleCoreMedia/.*\((iPhone)") does properly keep the credentials.
- } else $HTTP["useragent"] =~ "^(Podcasts|Instacast)/" {
- # require auth for user agent "Podcasts/" for everything (rss+mp3)
- auth.require = ( baseurl => (
- # see /usr/share/doc/lighttpd/authentication.txt.gz
- "method" => auth_method,
- "realm" => auth_realm,
- "require" => "valid-user",
- ), )
- } else $HTTP["request-method"] !~ "^(HEAD)$" {
- # Allow all HEAD requests, but require auth for all others on 'enclosures'
- auth.require = ( baseurl + "enclosures" => (
- # see /usr/share/doc/lighttpd/authentication.txt.gz
- "method" => auth_method,
- "realm" => auth_realm,
- "require" => "valid-user",
- ), )
- }
- # http://www.golem.de/news/content-security-policy-schutz-vor-cross-site-scripting-1306-99795.html
- setenv.add-response-header = (
- # http://www.w3.org/TR/CSP/#example-policies
- "Content-Security-Policy" => "default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self'; connect-src 'self'; font-src 'self'; img-src *;",
- )
- # enable directory browsing:
- dir-listing.activate = "enable"
- dir-listing.encoding = "utf-8"
- dir-listing.show-readme = "enable"
- # register lua cgi handler:
- static-file.exclude-extensions = ( )
- cgi.assign = (
- ".lua" => "/usr/bin/lua",
- ".sh" => "/bin/dash",
- )
- # recommended: some convenience redirects (internal):
- # http://redmine.lighttpd.net/projects/1/wiki/Docs_ModRewrite
- url.rewrite-once = (
- # .cgi to according suffix:
- "^(" + baseurl + "enclosures/app/ad_hoc)\.cgi(.*)$" => "$1.sh$2",
- # legacy: podcast ics + rss
- "^(" + baseurl + "podcasts)/([^\/]*)\.(ics|rss)$" => "$1/$2/broadcasts.$3",
- # consistency: station ics:
- "^(" + baseurl + "stations)/([^\/]*)\.(ics)$" => "$1/$2/broadcasts.$3",
- )
- url.rewrite-if-not-file = (
- # proper tech-neutral urls, respond with .xml content
- "^(" + baseurl + "stations/[^/]+/\d{4}/\d{2}/\d{2}/(index))$" => "$1.xml.gz",
- # proper tech-neutral urls, respond with .xml content
- "^(" + baseurl + "stations/[^/]+/\d{4}/\d{2}/\d{2}/(\d{4}%20.+))$" => "$1.xml",
- # temporary:
- "^" + baseurl + "stations/[^/]+/app/(broadcasts2html\.xslt)$" => "../../../assets/broadcast2html.xslt",
- # default station assets
- "^" + baseurl + "stations/[^/]+/app/(broadcast2html\.xslt|style\.css)$" => "../../../assets/$1",
- )
- # required, functional, redirects:
- url.redirect = (
- # redirect 'now' to cgi:
- "^" + baseurl + "stations/([^/]+)/now$" => "../../app/now.lua?station=$1",
- # redirect podcast episode markers to regular broadcast page: (.xml for legacy compat)
- "^" + baseurl + "podcasts/[^/]+/([^/]+/\d{4}/\d{2}/\d{2}/\d{4}.*?)(\.xml)?$" => baseurl + "stations/$1",
- # redirect unfinished enclosure markers to regular broadcast page:
- "^" + baseurl + "enclosures/([^/]+/\d{4}/\d{2}/\d{2}/\d{4}.*)\.(pending|ripping|failed|purged)$" => baseurl + "stations/$1",
- # convenience
- # redirect time-only, non-title URL
- "^(" + baseurl + ")stations/([^/]+)/(\d{4})/(\d{2})/(\d{2})/(\d{2})(\d{2})(00)?/?$" => "$1app/now.lua?station=$2&t=$3-$4-$5T$6:$7:00",
- "^(" + baseurl + ")stations/([^/]+)/(\d{4})-?(\d{2})-?(\d{2})T?(\d{2}):?(\d{2}):?(\d{2})([+-]\d{2}:?\d{2})" => "$1app/now.lua?station=$2&t=$3-$4-$5T$6:$7:$8$9",
- # legacy:
- # "^" + baseurl + "[^\/]*/([^\/]*)/app/now\.lua$" => "../../../app/now.lua?station=$1",
- # as long as we don't have a proper index.html per day, just use the dir listing:
- # "^(" + baseurl + "stations/[^/]*/\d{4}/\d{2}/\d{2}/)index.html$" => "$1",
- )
- $HTTP["url"] =~ "(\.xml\.gz|/index)$" {
- # serve compressed content to be unpacked by client – both for .xml.gz and naked index files
- setenv.add-response-header = ( "Content-Encoding" => "gzip")
- mimetype.assign = (".xml.gz" => "text/xml; charset=utf-8" )
- }
- # proper mimetypes + encodings:
- mimetype.assign = (
- ".cfg" => "text/plain; charset=utf-8",
- ".css" => "text/css; charset=utf-8",
- ".html" => "text/html; charset=utf-8",
- ".ico" => "image/vnd.microsoft.icon",
- ".ics" => "text/calendar; charset=utf-8",
- ".js" => "text/javascript; charset=utf-8",
- ".json" => "application/json; charset=utf-8",
- ".log" => "text/plain; charset=utf-8",
- ".mp3" => "audio/mpeg",
- ".png" => "image/png",
- ".svg" => "image/svg+xml",
- ".rb" => "text/plain; charset=utf-8",
- ".rdf" => "application/rdf+xml; charset=utf-8",
- ".rq" => "application/sparql-query",
- ".rss" => "application/rss+xml; charset=utf-8",
- ".ttl" => "text/turtle; charset=utf-8",
- ".txt" => "text/plain; charset=utf-8",
- ".xml" => "text/xml; charset=utf-8",
- ".xslt" => "text/xml; charset=utf-8",
- )
- # bandwidth saving:
- compress.filetype = (
- "application/json",
- "application/rdf+xml",
- "application/rss+xml",
- "application/xslt+xml",
- "text/calendar",
- "text/css",
- "text/html",
- "image/svg+xml",
- "text/javascript",
- "text/plain",
- "text/turtle",
- # "text/xml",
- )
- # /usr/share/doc/lighttpd-doc/expire.txt
- $HTTP["url"] !~ "/now\.lua$" {
- # expire all but now.lua - sets header itself
- expire.url = (
- "/app/" => "access 0 years",
- "" => "access 2 minutes",
- )
- }
- $HTTP["url"] =~ "\.(cfg|js|css|xslt|png|ico|mp3|ttl)$" {
- expire.url = ( "" => "access 1 days" )
- }
- $HTTP["url"] =~ "\.(ics|rdf)$" {
- expire.url = ( "" => "access 55 minutes" )
- }
- $HTTP["url"] =~ "\.(rss)$" {
- expire.url = ( "" => "access 2 minutes" )
- }
- $HTTP["url"] =~ "(modified\.ttl)$" {
- expire.url = ( "" => "modification 55 minutes" )
- }
- $HTTP["url"] =~ "modified-.*\.ttl$" {
- expire.url = ( "" => "modification 10 years" )
- }
- $HTTP["useragent"] =~ "^Overcast/" {
- expire.url = ( "" => "access 55 minutes" ),
- setenv.add-response-header = (
- # http://redmine.lighttpd.net/projects/1/wiki/Docs_ModMagnet#Status-Codes
- "Status" => "410",
- ),
- }
- etag.use-inode = "enable"
- etag.use-mtime = "enable"
- etag.use-size = "enable"
- static-file.etags = "enable"
|