import gevent
import gevent.monkey
# Monkeypatching and all the stuff
-
gevent.monkey.patch_all()
+# Startup delay for daemon restart
+gevent.sleep(5)
import glob
import os
import signal
import vpconfig
from vpconfig import VPConfig
import vlcclient
+import gc
import plugins.modules.ipaddr as ipaddr
from clientcounter import ClientCounter
from plugins.modules.PluginInterface import VPProxyPlugin
except ImportError:
pass
+import uuid
+from apscheduler.schedulers.background import BackgroundScheduler
class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
try:
while True:
-
+
if not self.clientconnected:
logger.debug("Client is not connected, terminating")
break
+ VPStuff.vlcclient.mark(self.vlcid)
data = self.video.read(4096)
if data and self.clientconnected:
self.wfile.write(data)
'''
GET request handler
'''
+
logger = logging.getLogger('http_HTTPHandler')
self.clientconnected = True
# Don't wait videodestroydelay if error happened
# Connected client IP address
self.clientip = self.request.getpeername()[0]
+ req_headers = self.headers
+ self.client_data = {
+ 'ip': self.clientip,
+ 'forwarded-for': req_headers.get('X-Forwarded-For'),
+ 'client-agent': req_headers.get('User-Agent'),
+ 'uuid': uuid.uuid4()
+ }
+
if VPConfig.firewall:
# If firewall enabled
self.clientinrange = any(map(lambda i: ipaddr.IPAddress(self.clientip) \
self.reqtype = self.splittedpath[1].lower()
# If first parameter is 'pid' or 'torrent' or it should be handled
# by plugin
- if not (self.reqtype in ('get','mp4') or self.reqtype in VPStuff.pluginshandlers):
+ if not (self.reqtype in ('get','mp4','ogg','ogv') or self.reqtype in VPStuff.pluginshandlers):
self.dieWithError(400) # 400 Bad Request
return
except IndexError:
self.handleRequest(headers_only)
def handleRequest(self, headers_only):
-
+
# Limit concurrent connections
- print VPStuff.clientcounter.total
if 0 < VPConfig.maxconns <= VPStuff.clientcounter.total:
logger.debug("Maximum connections reached, can't serve this")
self.dieWithError(503) # 503 Service Unavailable
self.params.append('0')
# Adding client to clientcounter
- clients = VPStuff.clientcounter.add(self.reqtype+'\\'+self.path_unquoted, self.clientip)
+ clients = VPStuff.clientcounter.add(self.reqtype+'/'+self.path_unquoted, self.client_data)
# If we are the one client, but sucessfully got vp instance from clientcounter,
# then somebody is waiting in the videodestroydelay state
# Check if we are first client
- if VPStuff.clientcounter.get(self.reqtype+'\\'+self.path_unquoted)==1:
+ if VPStuff.clientcounter.get(self.reqtype+'/'+self.path_unquoted)==1:
logger.debug("First client, should create VLC session")
shouldcreatevp = True
else:
logger.debug("Can reuse existing session")
shouldcreatevp = False
- self.vlcid = hashlib.md5(self.reqtype+'\\'+self.path_unquoted).hexdigest()
+ self.vlcid = hashlib.md5(self.reqtype+'/'+self.path_unquoted).hexdigest()
# Send fake headers if this User-Agent is in fakeheaderuas tuple
if fakeua:
logger.debug(
"Sending fake headers for " + useragent)
self.send_response(200)
- self.send_header("Content-Type", "video/mpeg")
+ self.send_header('Cache-Control','no-cache, no-store, must-revalidate');
+ self.send_header('Pragma','no-cache');
+ if self.reqtype in ("ogg","ogv"):
+ self.send_header("Content-Type", "video/ogg")
+ else:
+ self.send_header("Content-Type", "video/mpeg")
self.end_headers()
# Do not send real headers at all
self.headerssent = True
else:
self.vlcprefix = ''
- logger.debug("Ready to start broadcast....")
+ logger.info("Starting broadcasting "+self.path)
VPStuff.vlcclient.startBroadcast(
self.vlcid, self.vlcprefix + self.path_unquoted, VPConfig.vlcmux, VPConfig.vlcpreaccess, self.reqtype)
# Sleep a bit, because sometimes VLC doesn't open port in
del self.video.info().dict['server']
if self.video.info().dict.has_key('transfer-encoding'):
del self.video.info().dict['transfer-encoding']
+ if self.video.info().dict.has_key('content-type'):
+ del self.video.info().dict['content-type']
if self.video.info().dict.has_key('keep-alive'):
del self.video.info().dict['keep-alive']
for key in self.video.info().dict:
self.send_header(key, self.video.info().dict[key])
+
+ self.send_header('Cache-Control','no-cache, no-store, must-revalidate');
+ self.send_header('Pragma','no-cache');
+
+ if self.reqtype=="ogg":
+ self.send_header("Content-Type", "video/ogg")
+ else:
+ self.send_header("Content-Type", "video/mpeg")
+
# End headers. Next goes video data
self.end_headers()
logger.debug("Headers sent")
+ self.headerssent = True
# Run proxyReadWrite
self.proxyReadWrite()
self.dieWithError()
finally:
logger.debug("END REQUEST")
- VPStuff.clientcounter.delete(self.reqtype+'\\'+self.path_unquoted, self.clientip)
- if not VPStuff.clientcounter.get(self.reqtype+'\\'+self.path_unquoted):
- try:
- logger.debug("That was the last client, destroying VPClient")
- VPStuff.vlcclient.stopBroadcast(self.vlcid)
- except:
- pass
- self.vp.destroy()
-
+ logger.info("Closed connection from " + self.clientip + " path " + self.path)
+ VPStuff.clientcounter.delete(self.reqtype+'/'+self.path_unquoted, self.client_data)
+ self.vp.destroy()
class HTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
continue
logger.debug('Plugin loaded: ' + plugname)
for j in plugininstance.handlers:
+ logger.info("Registering handler '" + j +"'")
VPStuff.pluginshandlers[j] = plugininstance
VPStuff.pluginlist.append(plugininstance)
from vpconfig import VPConfig
logger.info('Config reloaded')
+sched = BackgroundScheduler()
+sched.start()
+
+def clean_streams():
+ VPStuff.vlcclient.clean_streams(VPConfig.videodestroydelay)
+
+job = sched.add_job(clean_streams, 'interval', seconds=15)
+
# setting signal handlers
try:
gevent.signal(signal.SIGHUP, _reloadconfig)
try:
logger.info("Using gevent %s" % gevent.__version__)
- logger.info("Using psutil %s" % psutil.__version__)
+ logger.info("Usig psutil %s" % psutil.__version__)
logger.info("Using VLC %s" % VPStuff.vlcclient._vlcver)
logger.info("Server started.")
while True:
# Return to our server tasks
server.handle_request()
except (KeyboardInterrupt, SystemExit):
+ sched.shutdown()
shutdown()