#!/usr/bin/lua local ClientTimeout = 20 local Backlog = 32 DisableDLNA = true local socket = require("socket") local mime = require("mime") local upnp = require("UPnP") local cman = require("ConnectionManager") local cdir = require("ContentDirectory") local mreg = require("MediaReceiverRegistrar") function sendXMLFile(client,data) local r = "HTTP/1.1 200 OK\r\n" .. 'Content-Type: text/xml; charset="utf-8"\r\n' .. "Connection: close\r\n" .. "Content-Length: "..string.format("%d",#data).."\r\n" .. "Server: "..UPnP.Server.."\r\n" .. "Date: "..os.date("!%a, %d %b %Y %H:%M:%S GMT").."\r\n" .. "EXT:\r\n" .. "\r\n" .. data client:send(r) end function sendImage(client,path) local p = string.gsub(path,"%.+",".") if string.sub(p,1,7) == "/icons/" then local f = io.open("."..p,"r") if f then local image = f:read(100000) f:close() local t = "jpeg" if p.sub(p,-3) == "png" then t = "png" end local r = "HTTP/1.1 200 OK\r\n" .. "Content-Type: image/"..t.."\r\n" .. "Content-Length: "..string.format("%d",#image).."\r\n" .. "Connection: Close\r\n" .. "Server: "..UPnP.Server.."\r\n" .. "Date: "..os.date("!%a, %d %b %Y %H:%M:%S GMT").."\r\n" .. "\r\n" .. image client:send(r) else upnp:SendHTTPError(client,404) end else upnp:SendHTTPError(client,404) end end function sendRedirect(client,host) local r = "HTTP/1.1 200 OK\r\n" .. "Content-Type: text/html\r\n" .. "Connection: Close\r\n" .. "Server: "..UPnP.Server.."\r\n" .. "Refresh: 0; url=http://"..host.."/\r\n" .. "\r\n" .. 'Click\r\n' client:send(r) end function LoadFile(fname) print(fname) t = "" local f = io.open(fname,"r") if not f then os.exit() end while true do local line = f:read() if not line then break end t = t .. line .. "\r\n" end f:close() return t end upnp:SetDebug(true) local port = 8080 -- local RootLocation = "http://10.0.4.31:8080/dms.xml" local uuid,sernbr,myip = upnp:SystemParameters("f0287290-e1e1-11e2-9a21-000000000000") local Desc = LoadFile("dms.xml") Desc = string.gsub(Desc,"##(%a+)##",{ UUID = uuid, SERNBR = sernbr, HOST = myip }) if DisableDLNA then Desc = string.gsub(Desc,"(%)","") end local server = socket.tcp() assert(server:setoption("reuseaddr", true)) assert(server:bind("*", port)) local ip, port = server:getsockname() print("Listen: " .. ip .. ":" .. port) assert(server:listen(Backlog)) while true do local client = server:accept() client:settimeout(ClientTimeout) local method,path,proto,attributes = upnp:ReadHTTPHeader(client) if method then if method == "GET" then if path == "/dms.xml" then sendXMLFile(client,Desc) elseif path == "/cman.xml" then sendXMLFile(client,cman:Description()) elseif path == "/cdir.xml" then sendXMLFile(client,cdir:Description()) elseif path == "/mreg.xml" then sendXMLFile(client,mreg:Description()) elseif path == "/" then sendRedirect(client,attributes["host"]) else sendImage(client,path) end elseif method == "SUBSCRIBE" then if attributes["NT"] then if attributes["NT"] == "upnp:event" and attributes["CALLBACK"] ~= "" then if path == "/cde" then cdir:Subscribe(client,attributes["CALLBACK"],attributes["TIMEOUT"]) elseif path == "/cme" then cman:Subscribe(client,attributes["CALLBACK"],attributes["TIMEOUT"]) elseif path == "/mre" then mreg:Subscribe(client,attributes["CALLBACK"],attributes["TIMEOUT"]) else upnp:SendSoapError(client,401) end else upnp:SendSoapError(client,412) end else if attributes["SID"] and attributes["SID"] ~= "" then if path == "/cde" then cdir:Renew(client,attributes["SID"],attributes["TIMEOUT"]) elseif path == "/cme" then cman:Renew(client,attributes["SID"],attributes["TIMEOUT"]) elseif path == "/mre" then mreg:Renew(client,attributes["SID"],attributes["TIMEOUT"]) else upnp:SendSoapError(client,401) end else upnp:SendSoapError(client,412) end end elseif method == "UNSUBSCRIBE" then if attributes["SID"] and attributes["SID"] ~= "" then if path == "/cde" then cdir:Unsubscribe(client,attributes["SID"]) elseif path == "/cme" then cman:Unsubscribe(client,attributes["SID"]) elseif path == "/mre" then mreg:Unsubscribe(client,attributes["SID"]) else upnp:SendSoapError(client,401) end else upnp:SendSoapError(client,412) end elseif method == "POST" then local soap = upnp:ReadHTTPBody(client,attributes["CONTENT-LENGTH"]) if path == "/cdc" then cdir:Invoke(client,attributes,soap) elseif path == "/cmc" then cman:Invoke(client,attributes,soap) elseif path == "/mrc" then mreg:Invoke(client,attributes,soap) else upnp:SendSoapError(client,404) end else upnp:SendHTTPError(client,"500") end end client:close() collectgarbage() end