skipped 3 lines 4 4 # https://github.com/t3l3machus 5 5 6 6 from http.server import HTTPServer, BaseHTTPRequestHandler 7 - import ssl, sys, base64, re, os, argparse 7 + import gnureadline as global_readline 8 + import ssl, sys, re, os, argparse 8 9 import netifaces as ni 9 10 from warnings import filterwarnings 10 11 from datetime import date, datetime 11 - from urllib.parse import unquote, urlparse 12 12 from threading import Thread 13 - from io import StringIO 14 13 from time import sleep 15 14 from subprocess import check_output 16 - from string import ascii_uppercase, ascii_lowercase, digits 17 - from platform import system as get_system_type 18 15 from copy import deepcopy 19 16 20 - if get_system_type() == 'Linux': 21 - import gnureadline as global_readline 22 - else: 23 - import readline as global_readline 24 17 25 18 filterwarnings("ignore", category = DeprecationWarning) 26 19 skipped 178 lines 205 198 return [False, e] 206 199 207 200 201 + def get_dt_prefix(): 202 + 203 + now = datetime.now() 204 + today = date.today() 205 + current_time = now.strftime("%H:%M:%S") 206 + #datetime_prefix = f'{today.strftime("%Y-%m-%d")} {current_time}' # Full datetime 207 + datetime_prefix = [today.strftime("%Y-%m-%d"), current_time][1] 208 + return datetime_prefix 209 + 210 + 211 + def is_valid_directory_part(s): 212 + 213 + pattern = r'^[a-zA-Z0-9-._~%!$&\'()*+,;=:@\/]*$' 214 + 215 + if re.match(pattern, s): 216 + return True 217 + 218 + return False 219 + 220 + 208 221 def chill(): 209 222 pass 210 223 skipped 45 lines 256 269 self.send_header('Access-Control-Allow-Origin', '*') 257 270 self.end_headers() 258 271 259 - print_to_prompt(f'{GET_REQ} Received for {ORANGE}{self.path}{END} from {ORANGE}{self.client_address[0]}{END}') 272 + print_to_prompt(f'[ { get_dt_prefix ( ) } ] {GET_REQ} Received for {ORANGE}{self.path}{END} from {ORANGE}{self.client_address[0]}{END}') 260 273 261 274 if response_body: 262 275 content = get_file_contents(response_body) 263 276 264 277 if not content[0]: 265 - print_to_prompt(f'{FAILED} An error occured while reading the file associated with server path {ORANGE}{self.path}{END} ({content[1]})') 278 + print_to_prompt(f'[ { get_dt_prefix ( ) } ] {FAILED} An error occured while reading the file associated with server path {ORANGE}{self.path}{END} ({content[1]})') 266 279 content = [0, ""] 267 280 268 281 else: skipped 20 lines 289 302 290 303 content_len = int(self.headers.get('Content-Length')) 291 304 post_data = self.rfile.read(content_len) 292 - print_to_prompt(f'{POST_REQ} Received for {ORANGE}{self.path}{END} from {ORANGE}{self.client_address[0]}{END}') 305 + print_to_prompt(f'[ { get_dt_prefix ( ) } ] {POST_REQ} Received for {ORANGE}{self.path}{END} from {ORANGE}{self.client_address[0]}{END}') 293 306 print_to_prompt(post_data.decode('utf-8', 'ignore').replace('<br>', '\n')) 294 307 self.wfile.write(b'OK') 295 308 skipped 1 lines 297 310 content = get_file_contents(response_body) 298 311 299 312 if not content[0]: 300 - print_to_prompt(f'{FAILED} An error occured while reading the file associated with server path {ORANGE}{self.path}{END} ({content[1]})') 313 + print_to_prompt(f'[ { get_dt_prefix ( ) } ] {FAILED} An error occured while reading the file associated with server path {ORANGE}{self.path}{END} ({content[1]})') 301 314 content = [None, ""] 302 315 303 316 else: skipped 33 lines 337 350 'details' : f''' 338 351 \rCreates a mapping between an server path name and a local file to serve. 339 352 \r 340 - \r {ORANGE}serve <GET|POST> <HTTP PATH NAME> <LOCAL FILE PATH>{END} 353 + \r{ORANGE}serve <GET|POST> <HTTP PATH NAME> <LOCAL FILE PATH>{END} 341 354 ''', 342 355 'least_args' : 3, 343 356 'max_args' : 3 skipped 2 lines 346 359 347 360 'release' : { 348 361 'details' : f''' 349 - \rRemove a resource mapping (stop serving it). 362 + \rRemove a resource mapping from the user defined endpoints (stop serving it). 350 363 \r 351 - \r {ORANGE}release <HTTP PATH NAME>{END} 364 + \r{ORANGE}release <HTTP PATH NAME>{END} 352 365 ''', 353 366 'least_args' : 1, 354 367 'max_args' : 1 skipped 43 lines 398 411 \r Command Description 399 412 \r ------- ----------- 400 413 \r help [+] Print this message. 401 - \r serve [+] Add a resource to the synergy server's content . 402 - \r release [+] Remove a resource from the synergy server's content . 414 + \r serve [+] Add an endpoint to the synergy server's contents . 415 + \r release [+] Remove an endpoint from the synergy server's contents . 403 416 \r endpoints List all hosted resources. 404 417 \r clear Clear screen. 405 418 \r exit Terminate the synergy server. skipped 250 lines 656 669 if not server_public_ip: 657 670 debug('Invalid interface.') 658 671 exit(1) 659 - # try: 660 - server_port = args.port if args.port else 8080 661 - 662 672 try: 663 - httpd = HTTPServer(('0.0.0.0', server_port), Synergy_Httpx) 673 + server_port = args.port if args.port else 8080 664 674 665 - except OSError: 666 - exit(f'\n{FAILED} Port {server_port} seems to already be in use.{END}\n') 675 + try: 676 + httpd = HTTPServer(('0.0.0.0', server_port), Synergy_Httpx) 667 677 668 - protocol = 'http' 678 + except OSError: 679 + exit(f'\n{FAILED} Port {server_port} seems to already be in use.{END}\n') 669 680 670 - if args.cert and args.key: 681 + protocol = 'http' 671 682 672 - try: 673 - httpd.socket = ssl.wrap_socket ( 674 - httpd.socket, 675 - keyfile = args.key, 676 - certfile = args.cert, 677 - server_side = True, 678 - ssl_version=ssl.PROTOCOL_TLS 679 - ) 683 + if args.cert and args.key: 680 684 681 - protocol = 'https' 685 + try: 686 + httpd.socket = ssl.wrap_socket ( 687 + httpd.socket, 688 + keyfile = args.key, 689 + certfile = args.cert, 690 + server_side = True, 691 + ssl_version=ssl.PROTOCOL_TLS 692 + ) 682 693 683 - except Exception as e: 684 - debug(f'Failed to establish SSL: {e}') 685 - exit(1) 694 + protocol = 'https' 686 695 696 + except Exception as e: 697 + debug(f'Failed to establish SSL: {e}') 698 + exit(1) 687 699 688 - server = Thread(target = httpd.serve_forever, args = ()) 689 - server.daemon = True 690 - server.start() 691 - print(f'[{ORANGE}0.0.0.0{END}:{ORANGE}{server_port}{END}] Synergy {protocol} server is up and running!') 692 700 693 - if not args.interface: 694 - try: 695 - server_public_ip = check_output("curl --connect-timeout 3.14 -s ifconfig.me", shell = True).decode(sys.stdout.encoding) 701 + server = Thread(target = httpd.serve_forever, args = ()) 702 + server.daemon = True 703 + server.start() 704 + print(f'[{get_dt_prefix()}][{ORANGE}0.0.0.0{END}:{ORANGE}{server_port}{END}] Synergy {protocol} server is up and running!') 696 705 697 - except: 698 - server_public_ip = '127.0.0.1' 699 - pass 706 + if not args.interface: 707 + try: 708 + server_public_ip = check_output("curl --connect-timeout 3.14 -s ifconfig.me", shell = True).decode(sys.stdout.encoding) 700 709 701 - for key,val in Synergy_Httpx.basic_endpoints.items(): 702 - print(f'{INFO} Basic {key} endpoint: {protocol}://{server_public_ip}:{server_port}/{val}') 710 + except: 711 + server_public_ip = '127.0.0.1' 712 + pass 703 713 714 + for key,val in Synergy_Httpx.basic_endpoints.items(): 715 + print(f'[{get_dt_prefix()}]{INFO} Basic {key} endpoint: {protocol}://{server_public_ip}:{server_port}/{val}') 704 716 705 - # except KeyboardInterrupt: 706 - # exit(0) 707 717 708 - # except Exception as e: 709 - # debug(f'Something went wrong: {e}') 710 - # exit(1) 718 + except KeyboardInterrupt: 719 + exit(0) 720 + 721 + except Exception as e: 722 + debug(f'Something went wrong: {e}') 723 + exit(1) 711 724 712 725 713 726 ''' Start tab autoComplete ''' skipped 66 lines 780 793 print('This endpoint is already mapped to a resource.') 781 794 continue 782 795 796 + # Check if the endpoint includes illegal characters 797 + if not is_valid_directory_part(cmd_list[2]): 798 + print(f'The path name {cmd_list[2]} includes illegal characters.') 799 + continue 800 + 783 801 # Check if path to local file is valid 784 802 if not os.path.isfile(cmd_list[3]): 785 803 print('File not found.') skipped 18 lines 804 822 elif cmd == 'endpoints': 805 823 print(f'\n{BOLD}Basic endpoints{END}:') 806 824 for method in Synergy_Httpx.basic_endpoints.keys(): 807 - print(f'{protocol}://{server_public_ip}/{Synergy_Httpx.basic_endpoints[method]} ({method})') 825 + print(f'{protocol}://{server_public_ip}: { server_port } /{Synergy_Httpx.basic_endpoints[method]} ({method})') 808 826 809 827 print(f'\n{BOLD}User Defined{END}:') 810 828 for method in Synergy_Httpx.user_defined_endpoints.keys(): 811 829 for key,value in Synergy_Httpx.user_defined_endpoints[method].items(): 812 - print(f'{protocol}://{server_public_ip}/{key} -> {value} ({method})') 830 + print(f'{protocol}://{server_public_ip}: { server_port } /{key} -> {value} ({method})') 813 831 print('') 814 832 815 833 skipped 26 lines