Small status changes
This commit is contained in:
parent
b3a73d6ea9
commit
9aee12decd
4 changed files with 75 additions and 22 deletions
31
README.md
31
README.md
|
@ -5,7 +5,7 @@ Webserver is published to the web trough ssh remote forward. In /etc/ssh/sshd_co
|
||||||
Then start `autossh` to maintain the connection:
|
Then start `autossh` to maintain the connection:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -R 8888:localhost:8888 here.rubenvandeven.com
|
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -R 8127:localhost:8888 here.rubenvandeven.com
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,3 +59,32 @@ sudo udevadm control --reload-rules && sudo udevadm trigger
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Apache on here.rubenvandeven.com
|
||||||
|
|
||||||
|
Unfortunately an SSH remote port-forward does change the ip of the requester into ::1/127.0.0.1. One solution would be to run a proxy on the server itself, which forwards a port to our server port, while adding a X-Forwarded-For header.
|
||||||
|
|
||||||
|
Example of apache host setup to forward remote port 8888 to local port 8127, to which we connect our (auto)ssh remote tunnel (see above).
|
||||||
|
|
||||||
|
```
|
||||||
|
Listen 8888
|
||||||
|
|
||||||
|
<VirtualHost *:8888>
|
||||||
|
Servername here.rubenvandeven.com
|
||||||
|
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteCond %{HTTP:Upgrade} =websocket [NC]
|
||||||
|
RewriteRule /(.*) ws://localhost:8127/$1 [P,L]
|
||||||
|
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
|
||||||
|
RewriteRule /(.*) http://localhost:8127/$1 [P,L]
|
||||||
|
|
||||||
|
ProxyPass / http://localhost:8127/
|
||||||
|
ProxyPassReverse / http://localhost:8127/
|
||||||
|
ProxyPreserveHost On
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
requires `a2enmod rewrite proxy proxy_http proxy_wstunnel`
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ class Store:
|
||||||
Base.metadata.create_all(self.engine)
|
Base.metadata.create_all(self.engine)
|
||||||
self.Session = sessionmaker(bind=self.engine)
|
self.Session = sessionmaker(bind=self.engine)
|
||||||
self.session = self.Session()
|
self.session = self.Session()
|
||||||
|
|
||||||
|
self.currentHit = None # mirrors Centralmanagmenet, stored here so we can quickly access it from webserver classes
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def getSession(self):
|
def getSession(self):
|
||||||
|
|
|
@ -151,12 +151,12 @@ class CentralManagement():
|
||||||
self.currentHit.open_page_at = datetime.datetime.utcnow()
|
self.currentHit.open_page_at = datetime.datetime.utcnow()
|
||||||
self.store.saveHIT(self.currentHit)
|
self.store.saveHIT(self.currentHit)
|
||||||
self.setLight(True)
|
self.setLight(True)
|
||||||
|
self.server.statusPage.set('state', self.currentHit.getStatus())
|
||||||
elif signal.name == 'server.submit':
|
elif signal.name == 'server.submit':
|
||||||
self.currentHit.submit_page_at = datetime.datetime.utcnow()
|
self.currentHit.submit_page_at = datetime.datetime.utcnow()
|
||||||
self.store.saveHIT(self.currentHit)
|
self.store.saveHIT(self.currentHit)
|
||||||
self.plotter.park()
|
self.plotter.park()
|
||||||
self.setLight(False)
|
self.server.statusPage.set('state', self.currentHit.getStatus())
|
||||||
# park always triggers a plotter.finished after being processed
|
# park always triggers a plotter.finished after being processed
|
||||||
|
|
||||||
elif signal.name[:4] == 'sqs.':
|
elif signal.name[:4] == 'sqs.':
|
||||||
|
@ -210,6 +210,7 @@ class CentralManagement():
|
||||||
self.server.statusPage.set('state', sqsHit.getStatus())
|
self.server.statusPage.set('state', sqsHit.getStatus())
|
||||||
elif signal.name == 'plotter.finished':
|
elif signal.name == 'plotter.finished':
|
||||||
if self.currentHit.submit_page_at:
|
if self.currentHit.submit_page_at:
|
||||||
|
self.setLight(False)
|
||||||
scan = threading.Thread(target=self.scanImage, name='scan')
|
scan = threading.Thread(target=self.scanImage, name='scan')
|
||||||
scan.start()
|
scan.start()
|
||||||
else:
|
else:
|
||||||
|
@ -219,6 +220,7 @@ class CentralManagement():
|
||||||
def makeHit(self):
|
def makeHit(self):
|
||||||
self.server.statusPage.reset()
|
self.server.statusPage.reset()
|
||||||
self.currentHit = self.store.createHIT()
|
self.currentHit = self.store.createHIT()
|
||||||
|
self.store.currentHit = self.currentHit
|
||||||
|
|
||||||
self.logger.info(f"Make HIT {self.currentHit.id}")
|
self.logger.info(f"Make HIT {self.currentHit.id}")
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,11 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
||||||
CORS_ORIGINS = ['localhost', '.mturk.com', 'here.rubenvandeven.com']
|
CORS_ORIGINS = ['localhost', '.mturk.com', 'here.rubenvandeven.com']
|
||||||
connections = set()
|
connections = set()
|
||||||
|
|
||||||
def initialize(self, config, plotterQ: Queue, eventQ: Queue, store: HITStore, geoip_reader: geoip2.database.Reader):
|
def initialize(self, config, plotterQ: Queue, eventQ: Queue, store: HITStore):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.plotterQ = plotterQ
|
self.plotterQ = plotterQ
|
||||||
self.eventQ = eventQ
|
self.eventQ = eventQ
|
||||||
self.store = store
|
self.store = store
|
||||||
self.geoip_reader = geoip_reader
|
|
||||||
|
|
||||||
def check_origin(self, origin):
|
def check_origin(self, origin):
|
||||||
parsed_origin = urlparse(origin)
|
parsed_origin = urlparse(origin)
|
||||||
|
@ -55,14 +54,17 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
||||||
# the client connected
|
# the client connected
|
||||||
def open(self, p = None):
|
def open(self, p = None):
|
||||||
self.__class__.connections.add(self)
|
self.__class__.connections.add(self)
|
||||||
hit_id = self.get_query_argument('id')
|
hit_id = int(self.get_query_argument('id'))
|
||||||
self.hit = self.store.getHitById(hit_id)
|
if hit_id != self.store.currentHit.id:
|
||||||
|
self.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.hit = self.store.currentHit
|
||||||
|
|
||||||
if self.hit.submit_hit_at:
|
if self.hit.submit_hit_at:
|
||||||
raise Exception("Opening websocket for already submitted hit")
|
raise Exception("Opening websocket for already submitted hit")
|
||||||
|
|
||||||
logger.info(f"New client connected: {self.request.remote_ip} for {self.hit.id}/{self.hit.hit_id}")
|
#logger.info(f"New client connected: {self.request.remote_ip} for {self.hit.id}/{self.hit.hit_id}")
|
||||||
self.eventQ.put(Signal('hit.info', dict(hit_id=self.hit.id, ip=self.request.remote_ip)))
|
|
||||||
self.eventQ.put(Signal('server.open', dict(hit_id=self.hit.id)))
|
self.eventQ.put(Signal('server.open', dict(hit_id=self.hit.id)))
|
||||||
self.strokes = []
|
self.strokes = []
|
||||||
|
|
||||||
|
@ -71,14 +73,7 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
||||||
if ua:
|
if ua:
|
||||||
ua_info = httpagentparser.detect(ua)
|
ua_info = httpagentparser.detect(ua)
|
||||||
self.eventQ.put(Signal('hit.info', dict(hit_id=self.hit.id, os=ua_info['os']['name'], browser=ua_info['browser']['name'])))
|
self.eventQ.put(Signal('hit.info', dict(hit_id=self.hit.id, os=ua_info['os']['name'], browser=ua_info['browser']['name'])))
|
||||||
try:
|
|
||||||
geoip = self.geoip_reader.country(self.request.remote_ip)
|
|
||||||
logger.info(f"Geo {geoip}")
|
|
||||||
self.eventQ.put(Signal('hit.info', dict(hit_id=self.hit.id, location=geoip.country.name)))
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception(e)
|
|
||||||
logger.info("No geo IP possible")
|
|
||||||
self.eventQ.put(Signal('hit.info', dict(hit_id=self.hit.id, location='Unknown')))
|
|
||||||
# self.write_message("hello!")
|
# self.write_message("hello!")
|
||||||
|
|
||||||
# the client sent the message
|
# the client sent the message
|
||||||
|
@ -109,6 +104,7 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
||||||
'action': 'submitted',
|
'action': 'submitted',
|
||||||
'msg': f"Submission ok, please refer to your submission as: {self.hit.uuid}"
|
'msg': f"Submission ok, please refer to your submission as: {self.hit.uuid}"
|
||||||
}))
|
}))
|
||||||
|
self.close()
|
||||||
|
|
||||||
elif msg['action'] == 'down':
|
elif msg['action'] == 'down':
|
||||||
# not used, implicit in move?
|
# not used, implicit in move?
|
||||||
|
@ -233,7 +229,7 @@ def strokes2D(strokes):
|
||||||
return d;
|
return d;
|
||||||
|
|
||||||
class DrawPageHandler(tornado.web.RequestHandler):
|
class DrawPageHandler(tornado.web.RequestHandler):
|
||||||
def initialize(self, store: HITStore, path: str, width: int, height: int, draw_width: int, draw_height: int, top_padding: int, left_padding: int):
|
def initialize(self, store: HITStore, eventQ: Queue, path: str, width: int, height: int, draw_width: int, draw_height: int, top_padding: int, left_padding: int, geoip_reader: geoip2.database.Reader):
|
||||||
self.store = store
|
self.store = store
|
||||||
self.path = path
|
self.path = path
|
||||||
self.width = width
|
self.width = width
|
||||||
|
@ -242,11 +238,16 @@ class DrawPageHandler(tornado.web.RequestHandler):
|
||||||
self.draw_height = draw_height
|
self.draw_height = draw_height
|
||||||
self.top_padding = top_padding
|
self.top_padding = top_padding
|
||||||
self.left_padding = left_padding
|
self.left_padding = left_padding
|
||||||
|
self.eventQ = eventQ
|
||||||
|
self.geoip_reader = geoip_reader
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
try:
|
try:
|
||||||
hit_id = self.get_query_argument('id')
|
hit_id = int(self.get_query_argument('id'))
|
||||||
hit = self.store.getHitById(hit_id)
|
if hit_id != self.store.currentHit.id:
|
||||||
|
self.write("Invalid HIT")
|
||||||
|
return
|
||||||
|
hit = self.store.currentHit
|
||||||
except Exception:
|
except Exception:
|
||||||
self.write("HIT not found")
|
self.write("HIT not found")
|
||||||
else:
|
else:
|
||||||
|
@ -273,6 +274,24 @@ class DrawPageHandler(tornado.web.RequestHandler):
|
||||||
.replace("{TOP_PADDING}", str(self.top_padding))\
|
.replace("{TOP_PADDING}", str(self.top_padding))\
|
||||||
.replace("{LEFT_PADDING}", str(self.left_padding))
|
.replace("{LEFT_PADDING}", str(self.left_padding))
|
||||||
self.write(contents)
|
self.write(contents)
|
||||||
|
|
||||||
|
if 'X-Forwarded-For' in self.request.headers:
|
||||||
|
ip = self.request.headers['X-Forwarded-For']
|
||||||
|
else:
|
||||||
|
ip = self.request.remote_ip
|
||||||
|
|
||||||
|
|
||||||
|
logger.info(f"Request from {ip}")
|
||||||
|
self.eventQ.put(Signal('hit.info', dict(hit_id=hit.id, ip=ip)))
|
||||||
|
|
||||||
|
try:
|
||||||
|
geoip = self.geoip_reader.country(ip)
|
||||||
|
logger.info(f"Geo {geoip}")
|
||||||
|
self.eventQ.put(Signal('hit.info', dict(hit_id=hit.id, location=geoip.country.name)))
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(e)
|
||||||
|
logger.info("No geo IP possible")
|
||||||
|
self.eventQ.put(Signal('hit.info', dict(hit_id=hit.id, location='Unknown')))
|
||||||
|
|
||||||
class BackendHandler(tornado.web.RequestHandler):
|
class BackendHandler(tornado.web.RequestHandler):
|
||||||
def initialize(self, store: HITStore, path: str):
|
def initialize(self, store: HITStore, path: str):
|
||||||
|
@ -385,19 +404,20 @@ class Server:
|
||||||
'plotterQ': self.plotterQ,
|
'plotterQ': self.plotterQ,
|
||||||
'eventQ': self.eventQ,
|
'eventQ': self.eventQ,
|
||||||
'store': self.store,
|
'store': self.store,
|
||||||
'geoip_reader': self.geoip_reader
|
|
||||||
}),
|
}),
|
||||||
(r"/status/ws", StatusWebSocketHandler),
|
(r"/status/ws", StatusWebSocketHandler),
|
||||||
(r"/draw", DrawPageHandler,
|
(r"/draw", DrawPageHandler,
|
||||||
dict(
|
dict(
|
||||||
store = self.store,
|
store = self.store,
|
||||||
|
eventQ = self.eventQ,
|
||||||
path=self.web_root,
|
path=self.web_root,
|
||||||
width=self.config['scanner']['width'],
|
width=self.config['scanner']['width'],
|
||||||
height=self.config['scanner']['height'],
|
height=self.config['scanner']['height'],
|
||||||
draw_width=self.config['scanner']['draw_width'],
|
draw_width=self.config['scanner']['draw_width'],
|
||||||
draw_height=self.config['scanner']['draw_height'],
|
draw_height=self.config['scanner']['draw_height'],
|
||||||
top_padding=self.config['scanner']['top_padding'],
|
top_padding=self.config['scanner']['top_padding'],
|
||||||
left_padding=self.config['scanner']['left_padding']
|
left_padding=self.config['scanner']['left_padding'],
|
||||||
|
geoip_reader= self.geoip_reader
|
||||||
)),
|
)),
|
||||||
(r"/backend", BackendHandler,
|
(r"/backend", BackendHandler,
|
||||||
dict(
|
dict(
|
||||||
|
|
Loading…
Reference in a new issue