def create_requesthandlers(rfwconf, cmd_queue, expiry_queue):
    """Create RequestHandler type. This is a way to avoid global variables: a closure returning a class type that binds rfwconf and cmd_queue inside. 
    """

    ver = '0.0.0'
    try:
        version_file = os.path.join(os.path.dirname(__file__), '_version.py')
        with open(version_file) as f:
            verline = f.read().strip()
            VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"
            mo = re.search(VSRE, verline, re.M)
            if mo:
                ver = mo.group(1)
            else:
                log.error('Could not find version string in {}'.format(version_file))
    except IOError, e:
        log.error('Could not read {}: {} {}'.format(version_file, e.strerror, e.filename))
    server_ver = 'SecurityKISS rfw/{}'.format(ver)


    def check_whitelist_conflict(ip, whitelist):
        if ip != '0.0.0.0/0' and iputil.ip_in_list(ip, whitelist):
            msg = 'Ignoring the request conflicting with the whitelist'
            log.warn(msg)
            raise Exception(msg)


    def process(handler, modify, urlpath):
        # modify should be 'D' for Delete or 'I' for Insert understood as -D and -I iptables flags
        assert modify in ['D', 'I', 'L']
        log.debug('process {} urlpath: {}'.format(modify, urlpath))
      
        try:
            action, rule, directives = cmdparse.parse_command(urlpath)
            log.debug('\nAction: {}\nRule: {}\nDirectives: {}'.format(action, rule, directives))
            if modify == 'L':
                if action == 'help':
                    resp = 'TODO usage'
                    return handler.http_resp(200, resp)
                elif action == 'list':
                    chain = rule
                    rules = Iptables.read_simple_rules(chain)
                    log.debug('List rfw rules: %s', rules) 
                    list_of_dict = map(iptables.Rule._asdict, rules)                    
                    resp = json.dumps(list_of_dict)
                    return handler.http_resp(200, resp)
                elif rfwconf.is_non_restful():
                    mod = directives.get('modify')
                    if not mod:
                        raise Exception('Unrecognized command. Non-restful enabled, you need to provide modify parameter.'.format(action))
                    if mod == 'insert':
                        modify = 'I'
                    elif mod == 'delete':
                        modify = 'D'
                    else:
                        raise Exception('Unrecognized command. Modify parameter can be "insert" or "delete".')
                else:
                    raise Exception('Unrecognized command. Non-restful disabled.')

            if modify in ['D', 'I'] and action.upper() in iptables.RULE_TARGETS:
                # eliminate ignored/whitelisted IP related commands early to prevent propagating them to expiry queue
                check_whitelist_conflict(rule.source, rfwconf.whitelist())
                check_whitelist_conflict(rule.destination, rfwconf.whitelist())
                ctup = (modify, rule, directives)
                log.debug('PUT to Cmd Queue. Tuple: {}'.format(ctup))
                cmd_queue.put_nowait(ctup)
                return handler.http_resp(200, ctup)
            else:
                raise Exception('Unrecognized command.')
        except Exception, e:
            msg = 'ERROR: {}'.format(e.message)
            # logging as error disabled - bad client request is not an error 
            # log.exception(msg)
            log.info(msg)
            return handler.http_resp(400, msg) # Bad Request
            


    class LocalRequestHandler(CommonRequestHandler):
        
        def version_string(self):
            return server_ver

        def go(self, modify, urlpath, remote_addr):
            process(self, modify, urlpath)

        def do_modify(self, modify):
            self.go(modify, self.path, self.client_address[0])

        def do_PUT(self):
            self.go('I', self.path, self.client_address[0])
    
        def do_DELETE(self):
            self.go('D', self.path, self.client_address[0])
    
        def do_GET(self):
            self.go('L', self.path, self.client_address[0])
    
   

    class OutwardRequestHandler(BasicAuthRequestHandler):
        
        def version_string(self):
            return server_ver

        def creds_check(self, user, password):
            return user == rfwconf.auth_username() and password == rfwconf.auth_password()

        def go(self, modify, urlpath, remote_addr):
            # authenticate by checking if client IP is in the whitelist - normally reqests from non-whitelisted IPs should be blocked by firewall beforehand
            if not iputil.ip_in_list(remote_addr, rfwconf.whitelist()):
                log.error('Request from client IP: {} which is not authorized in the whitelist. It should have been blocked by firewall.'.format(remote_addr))
                return self.http_resp(403, '') # Forbidden 

            process(self, modify, urlpath)

        def do_PUT(self):
            self.go('I', self.path, self.client_address[0])
    
        def do_DELETE(self):
            self.go('D', self.path, self.client_address[0])
    
        def do_GET(self):
            self.go('L', self.path, self.client_address[0])
    
   
    return LocalRequestHandler, OutwardRequestHandler
dataset/ETHPy150Open securitykiss-com/rfw/rfw/rfw.py/create_requesthandlers/original