From 0af44f6e530f55e1f2190dffc859b4b4e815ae64 Mon Sep 17 00:00:00 2001 From: Viktor Varland Date: Tue, 5 Apr 2016 18:50:02 +0200 Subject: [PATCH] added multi user support --- pubip.py | 132 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 35 deletions(-) diff --git a/pubip.py b/pubip.py index 5510dc5..2cc67e1 100755 --- a/pubip.py +++ b/pubip.py @@ -4,50 +4,112 @@ import http.server import socket class pubIpServer(http.server.HTTPServer): - current_ip = 'n/a' - + current_ip = {} class pubIpHandler(http.server.BaseHTTPRequestHandler): + + def update_ip(self, domain, new_ip): + if domain is None or new_ip is None: + raise Exception('No domain or no new ip') + + if valid_ip(new_ip): + stored_ip = self.server.current_ip.get(domain, None) + + if new_ip == stored_ip: + raise Exception('IP was identical, skipping...') + + if 'X-Real-IP' in self.headers: + c_ip = self.headers['X-Real-IP'] + else: + c_ip, c_port = self.client_address + + if new_ip == c_ip: + print('Updating dynamic IP for {}: {}'.format(domain, new_ip)) + self.server.current_ip[domain] = new_ip + else: + raise Exception('Update IP mismatch for {}: {}, {}'.format(domain, c_ip, new_ip)) + + def redirect(self, domain, port): + destination = self.server.current_ip.get(domain, None) + if destination is None or port is None: + raise Exception('No destination address for: {} {}'.format(domain, port)) + + url = 'http://{}:{}'.format(destination, port) + self.send_response(302) + self.send_header('Location', url) + self.end_headers() + def do_GET(self): + ''' + /:command/:domain/:target + /update/vlv/127.0.0.1 + /go/vlv/8080 + ''' + msg = self.path + + if 'favico' in self.path: + return + + action = wrassle(self.path.split('/')) + + command = action.get('command', None) + domain = action.get('domain', None) + target = action.get('target', None) + + if command == 'update': + try: + self.update_ip(domain, target) + except Exception as e: + print(e) + + if command == 'go': + try: + return self.redirect(domain, target) + except Exception as e: + print(e) + + if command == 'show': + msg = self.server.current_ip.get(domain, msg) + self.send_response(200) self.send_header('Content-type','text/html') self.end_headers() - - s_address = self.server.current_ip - - path = self.path.split('/') - - if path[1].startswith('favico'): - return - - if path[1] == 'update': - n_address = path[2] - - try: - socket.inet_aton(n_address) - except socket.error: - print('Error on IP conversion: {}'.format(n_address)) - return - - if n_address == s_address: - print('IP was identical, skipping...') - return - - if 'X-Real-IP' in self.headers: - c_address = self.headers['X-Real-IP'] - else: - c_address, c_port = self.client_address - - if n_address == c_address: - print('Updating dynamic IP: {}'.format(n_address)) - self.server.current_ip = n_address - else: - print('Update IP mismatch: {}, {}'.format(c_address, n_address)) - - msg = self.server.current_ip self.wfile.write(msg.encode('utf-8')) return +def wrassle(array): + result = { + 'command': None, + 'domain': None, + 'target': None + } + + for index, value in enumerate(array): + if value.startswith('favico'): + continue + + if index == 1 and value: + result['command'] = array[index] + + if index == 2 and value: + result['domain'] = array[index] + + if index == 3 and value: + result['target'] = array[index] + + print('Done wrasslin\': {}'.format(result)) + return result + +def valid_ip(ip): + if ip is None: + return False + + try: + socket.inet_aton(ip) + return True + except socket.error: + print('Error on IP conversion: {}'.format(ip)) + return False def run(server_class=pubIpServer, handler_class=pubIpHandler): server_address = ('', 8021)