2015-07-12 20:36:46 +02:00
|
|
|
import logging
|
|
|
|
import time
|
|
|
|
import cgi
|
2015-09-13 23:17:13 +02:00
|
|
|
import socket
|
2015-12-28 00:19:58 +01:00
|
|
|
import sys
|
2015-07-12 20:36:46 +02:00
|
|
|
|
2015-01-12 02:03:45 +01:00
|
|
|
from gevent.pywsgi import WSGIServer
|
|
|
|
from gevent.pywsgi import WSGIHandler
|
|
|
|
from lib.geventwebsocket.handler import WebSocketHandler
|
2015-07-12 20:36:46 +02:00
|
|
|
|
version 0.2.7, plugin system, multiuser plugin for zeroproxies, reworked imports, cookie parse, stats moved to plugin, usermanager class, dont generate site auth on listing, multiline notifications, allow server side prompt from user, update script keep plugins disabled status
2015-03-24 01:33:09 +01:00
|
|
|
from UiRequest import UiRequest
|
2015-01-12 02:03:45 +01:00
|
|
|
from Site import SiteManager
|
|
|
|
from Config import config
|
2015-01-17 18:50:56 +01:00
|
|
|
from Debug import Debug
|
2015-01-12 02:03:45 +01:00
|
|
|
|
version 0.2.7, plugin system, multiuser plugin for zeroproxies, reworked imports, cookie parse, stats moved to plugin, usermanager class, dont generate site auth on listing, multiline notifications, allow server side prompt from user, update script keep plugins disabled status
2015-03-24 01:33:09 +01:00
|
|
|
|
2015-01-12 02:03:45 +01:00
|
|
|
# Skip websocket handler if not necessary
|
|
|
|
class UiWSGIHandler(WSGIHandler):
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.server = args[2]
|
|
|
|
super(UiWSGIHandler, self).__init__(*args, **kwargs)
|
|
|
|
self.args = args
|
|
|
|
self.kwargs = kwargs
|
|
|
|
|
|
|
|
def run_application(self):
|
|
|
|
if "HTTP_UPGRADE" in self.environ: # Websocket request
|
|
|
|
try:
|
|
|
|
ws_handler = WebSocketHandler(*self.args, **self.kwargs)
|
|
|
|
ws_handler.__dict__ = self.__dict__ # Match class variables
|
|
|
|
ws_handler.run_application()
|
|
|
|
except Exception, err:
|
|
|
|
logging.error("UiWSGIHandler websocket error: %s" % Debug.formatException(err))
|
|
|
|
if config.debug: # Allow websocket errors to appear on /Debug
|
|
|
|
import sys
|
|
|
|
sys.modules["main"].DebugHook.handleError()
|
|
|
|
else: # Standard HTTP request
|
|
|
|
try:
|
|
|
|
super(UiWSGIHandler, self).run_application()
|
|
|
|
except Exception, err:
|
|
|
|
logging.error("UiWSGIHandler error: %s" % Debug.formatException(err))
|
|
|
|
if config.debug: # Allow websocket errors to appear on /Debug
|
|
|
|
import sys
|
|
|
|
sys.modules["main"].DebugHook.handleError()
|
2015-09-13 23:17:13 +02:00
|
|
|
|
|
|
|
def handle(self):
|
|
|
|
# Save socket to be able to close them properly on exit
|
|
|
|
self.server.sockets[self.client_address] = self.socket
|
|
|
|
super(UiWSGIHandler, self).handle()
|
|
|
|
del self.server.sockets[self.client_address]
|
2015-01-12 02:03:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
class UiServer:
|
2015-02-20 01:37:12 +01:00
|
|
|
|
2015-07-12 20:36:46 +02:00
|
|
|
def __init__(self):
|
|
|
|
self.ip = config.ui_ip
|
|
|
|
self.port = config.ui_port
|
|
|
|
if self.ip == "*":
|
|
|
|
self.ip = "" # Bind all
|
2015-09-10 23:25:09 +02:00
|
|
|
self.wrapper_nonces = []
|
2015-07-12 20:36:46 +02:00
|
|
|
self.sites = SiteManager.site_manager.list()
|
|
|
|
self.log = logging.getLogger(__name__)
|
|
|
|
|
2016-03-06 02:17:58 +01:00
|
|
|
# After WebUI started
|
|
|
|
def afterStarted(self):
|
|
|
|
from util import Platform
|
|
|
|
Platform.setMaxfilesopened(config.max_files_opened)
|
|
|
|
|
2015-07-12 20:36:46 +02:00
|
|
|
# Handle WSGI request
|
|
|
|
def handleRequest(self, env, start_response):
|
|
|
|
path = env["PATH_INFO"]
|
|
|
|
if env.get("QUERY_STRING"):
|
|
|
|
get = dict(cgi.parse_qsl(env['QUERY_STRING']))
|
|
|
|
else:
|
|
|
|
get = {}
|
|
|
|
ui_request = UiRequest(self, get, env, start_response)
|
|
|
|
if config.debug: # Let the exception catched by werkezung
|
|
|
|
return ui_request.route(path)
|
|
|
|
else: # Catch and display the error
|
|
|
|
try:
|
|
|
|
return ui_request.route(path)
|
|
|
|
except Exception, err:
|
|
|
|
logging.debug("UiRequest error: %s" % Debug.formatException(err))
|
|
|
|
return ui_request.error500("Err: %s" % Debug.formatException(err))
|
|
|
|
|
|
|
|
# Reload the UiRequest class to prevent restarts in debug mode
|
|
|
|
def reload(self):
|
|
|
|
global UiRequest
|
|
|
|
import imp
|
|
|
|
import sys
|
|
|
|
reload(sys.modules["User.UserManager"])
|
|
|
|
reload(sys.modules["Ui.UiWebsocket"])
|
|
|
|
UiRequest = imp.load_source("UiRequest", "src/Ui/UiRequest.py").UiRequest
|
|
|
|
# UiRequest.reload()
|
|
|
|
|
|
|
|
# Bind and run the server
|
|
|
|
def start(self):
|
|
|
|
handler = self.handleRequest
|
|
|
|
|
|
|
|
if config.debug:
|
|
|
|
# Auto reload UiRequest on change
|
|
|
|
from Debug import DebugReloader
|
|
|
|
DebugReloader(self.reload)
|
|
|
|
|
|
|
|
# Werkzeug Debugger
|
|
|
|
try:
|
|
|
|
from werkzeug.debug import DebuggedApplication
|
|
|
|
handler = DebuggedApplication(self.handleRequest, evalex=True)
|
|
|
|
except Exception, err:
|
|
|
|
self.log.info("%s: For debugging please download Werkzeug (http://werkzeug.pocoo.org/)" % err)
|
|
|
|
from Debug import DebugReloader
|
|
|
|
self.log.write = lambda msg: self.log.debug(msg.strip()) # For Wsgi access.log
|
|
|
|
self.log.info("--------------------------------------")
|
|
|
|
self.log.info("Web interface: http://%s:%s/" % (config.ui_ip, config.ui_port))
|
|
|
|
self.log.info("--------------------------------------")
|
|
|
|
|
|
|
|
if config.open_browser:
|
|
|
|
logging.info("Opening browser: %s...", config.open_browser)
|
|
|
|
import webbrowser
|
|
|
|
if config.open_browser == "default_browser":
|
|
|
|
browser = webbrowser.get()
|
|
|
|
else:
|
|
|
|
browser = webbrowser.get(config.open_browser)
|
2016-02-06 02:03:31 +01:00
|
|
|
browser.open("http://%s:%s/%s" % (config.ui_ip if config.ui_ip != "*" else "127.0.0.1", config.ui_port, config.homepage), new=2)
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
self.server = WSGIServer((self.ip.replace("*", ""), self.port), handler, handler_class=UiWSGIHandler, log=self.log)
|
|
|
|
self.server.sockets = {}
|
2016-03-06 02:17:58 +01:00
|
|
|
self.afterStarted()
|
2015-12-28 00:19:58 +01:00
|
|
|
try:
|
|
|
|
self.server.serve_forever()
|
|
|
|
except Exception, err:
|
|
|
|
self.log.error("Web interface bind error, must be running already, exiting.... %s" % err)
|
|
|
|
sys.modules["main"].file_server.stop()
|
2015-07-12 20:36:46 +02:00
|
|
|
self.log.debug("Stopped.")
|
|
|
|
|
|
|
|
def stop(self):
|
|
|
|
self.log.debug("Stopping...")
|
|
|
|
# Close WS sockets
|
|
|
|
if "clients" in dir(self.server):
|
|
|
|
for client in self.server.clients.values():
|
|
|
|
client.ws.close()
|
|
|
|
# Close http sockets
|
|
|
|
sock_closed = 0
|
|
|
|
for sock in self.server.sockets.values():
|
|
|
|
try:
|
2015-09-13 23:17:13 +02:00
|
|
|
sock.send("bye")
|
|
|
|
sock.shutdown(socket.SHUT_RDWR)
|
2015-10-25 23:08:25 +01:00
|
|
|
# sock._sock.close()
|
|
|
|
# sock.close()
|
2015-07-12 20:36:46 +02:00
|
|
|
sock_closed += 1
|
2015-09-13 23:17:13 +02:00
|
|
|
except Exception, err:
|
|
|
|
self.log.debug("Http connection close error: %s" % err)
|
2015-07-12 20:36:46 +02:00
|
|
|
self.log.debug("Socket closed: %s" % sock_closed)
|
2015-09-13 23:17:13 +02:00
|
|
|
time.sleep(0.1)
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
self.server.socket.close()
|
|
|
|
self.server.stop()
|
2016-03-06 02:17:58 +01:00
|
|
|
time.sleep(1)
|