先决条件: 在Python中创建代理Web服务器–Set1
null
在本教程中,添加了一些有趣的功能,使其更加有用。
- 添加域黑名单 .比如谷歌。com,facebook。通用域名格式。在我们的配置目录中创建一个黑名单域列表。现在,只需忽略/删除黑名单域收到的请求。(理想情况下,我们必须做出禁止的回应。)
# Check if the host:port is blacklistedfor i in range(0, len(config['BLACKLIST_DOMAINS'])): if config['BLACKLIST_DOMAINS'][i] in url: conn.close()return
- 要添加主机阻止,请执行以下操作: 例如,您可能需要允许来自特定子网的连接或特定人员的连接。要添加此项,请创建一个包含所有允许主机的列表。因为主机也可以是子网,所以添加regex以匹配IP地址,特别是IPV4地址。 IPv4地址通常用点十进制表示法表示,它由四个十进制数字组成,每个数字的范围从0到255,用点分隔,例如172.16.254.1。每个部分代表地址的一组8位(八位字节)
- 使用正则表达式匹配正确的IP地址:
- 创建一个新方法,并使用fnmatch模块匹配正则表达式。遍历所有正则表达式,如果与其中任何一个匹配,则允许请求。如果未发现客户端地址是任何正则表达式的一部分,则发送禁止响应。现在,再次跳过这个响应创建部分。
注意:在接下来的教程中,我们将创建一个完整的自定义Web服务器,其中将创建一个createResponse函数来处理通用响应创建。
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
默认主机匹配正则表达式为“*”以匹配所有主机。不过,形式为’192.168.*’的正则表达式也可以使用。服务器当前处理请求,但不显示任何消息,因此我们不知道服务器的状态。它的消息应该记录在控制台上。为此,请使用日志模块,因为它是线程安全的。(如果您还记得的话,服务器是多线程的。)
导入模块并设置其初始配置。
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: PYIT维护一个包含颜色代码的类。将其分离到另一个模块中,以使代码模块化并遵循PEP8标准。
# ColorizePython.pyclass pycolors:HEADER = ' 33[95m'OKBLUE = ' 33[94m'OKGREEN = ' 33[92m'WARNING = ' 33[93m'FAIL = ' 33[91m'ENDC = ' 33[0m' # End colorBOLD = ' 33[1m'UNDERLINE = ' 33[4m'
模块:
import ColorizePython
方法:
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
- 由于colorizeLog不是服务器类的函数,因此它被创建为一个名为utils的单独模块。py存储了所有使代码更容易理解的实用程序,并将此方法放在那里。 在需要时添加适当的日志消息,尤其是在 这个 服务器更改。
- 修改服务器中的shutdown方法,以便在退出应用程序之前退出所有正在运行的线程。 穿线。列举 迭代所有正在运行的线程,因此我们不需要维护它们的列表。当我们试图结束主线程时,线程模块的行为是意外的。官方文件还指出:
“如果试图加入当前线程,join()会引发运行时错误,因为这会导致死锁。在线程启动之前加入()也是一个错误,尝试这样做会引发相同的异常。”
因此,适当地跳过它。这是同样的代码。
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)
如果您有任何意见/建议/疑问,请随时提问。
关于作者:
平克什·巴贾提亚 来自印度海得拉巴。 他本质上是个极客,有很多值得寻找的项目。他的项目工作可见一斑 在这里
如果你也想在这里展示你的博客,请参见 吉微博 在Geeksforgek上写客博。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END