Open In App

Creating a Proxy Webserver in Python | Set 2

Prerequisite: Creating a Proxy Webserver in Python – Set1 

In this tutorial, a few interesting features are added to make it more useful. 



      
# Check if the host:port is blacklisted
for i in range(0, len(config['BLACKLIST_DOMAINS'])):
    if config['BLACKLIST_DOMAINS'][i] in url:
        conn.close()
return

Note: We would be creating a full-fledged custom webserver in upcoming tutorials, their creation of a createResponse function will be done to handle the generic response creation.

def _ishostAllowed(self, host):

    """ Check if host is allowed to access
        the content """
    for wildcard in config['HOST_ALLOWED']:
        if fnmatch.fnmatch(host, wildcard):
            return True
    return False

Default host match regex would be ‘*’ to match all the hosts. Though, regex of the form ‘192.168.*’ can also be used. The server currently processes requests but does not show any messages, so we are not aware of the state of the server. Its messages should be logged onto the console. For this purpose, use the logging module as it is thread-safe. (server is multi-threaded if you remember.)

Import module and setup its initial configuration.  



logging.basicConfig(level = logging.DEBUG,
format = '[%(CurrentTime)-10s] (%(ThreadName)-10s) %(message)s',)
def log(self, log_level, client, msg):

    """ Log the messages to appropriate place """
    LoggerDict = {
       'CurrentTime' : strftime("%a, %d %b %Y %X", localtime()),
       'ThreadName' : threading.currentThread().getName()
    }
    if client == -1: # Main Thread
        formatedMSG = msg
    else: # Child threads or Request Threads
        formatedMSG = '{0}:{1} {2}'.format(client[0], client[1], msg)
    logging.debug('%s', utils.colorizeLog(config['COLORED_LOGGING'],
    log_level, formatedMSG), extra=LoggerDict)
# ColorizePython.py
class pycolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m' # End color
BOLD = '\033[1m'
UNDERLINE = '\033[4m'

Module: 

import ColorizePython

Method: 

def colorizeLog(shouldColorize, log_level, msg):
    ## Higher is the log_level in the log()
    ## argument, the lower is its priority.
    colorize_log = {
    "NORMAL": ColorizePython.pycolors.ENDC,
    "WARNING": ColorizePython.pycolors.WARNING,
    "SUCCESS": ColorizePython.pycolors.OKGREEN,
    "FAIL": ColorizePython.pycolors.FAIL,
    "RESET": ColorizePython.pycolors.ENDC
    }

    if shouldColorize.lower() == "true":
        if log_level in colorize_log:
            return colorize_log[str(log_level)] + msg + colorize_log['RESET']
        return colorize_log["NORMAL"] + msg + colorize_log["RESET"]
    return msg 

“join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.” 

So, skip it appropriately. Here’s the code for the same. 

def shutdown(self, signum, frame):
    """ Handle the exiting server. Clean all traces """
    self.log("WARNING", -1, 'Shutting down gracefully...')
    main_thread = threading.currentThread() # Wait for all clients to exit
    for t in threading.enumerate():
        if t is main_thread:
            continue
            self.log("FAIL", -1, 'joining ' + t.getName())
        t.join()
        self.serverSocket.close()
    sys.exit(0)

If you have any comments/suggestions/queries then feel free to ask. 🙂 
 

About the Author:

Pinkesh Badjatiya hails from IIIT Hyderabad. He is a geek at heart with ample projects worth looking for. His project work can be seen here. 

If you also wish to showcase your blog here, please see GBlog for guest blog writing on GeeksforGeeks.

 
 

Article Tags :