首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python 3中主动编写HTTPS webserver服务器

在Python 3中主动编写HTTPS webserver服务器
EN

Code Review用户
提问于 2018-07-02 14:46:09
回答 1查看 293关注 0票数 2

请帮助我改进这个现有的,工作的代码。我并不是要求您改变它所做的,因为它已经完美地处理了由我自己的规范设计的连接。我只想确认一下密码。

代码语言:javascript
复制
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, ssl
from socketserver import ThreadingMixIn
from http.server import SimpleHTTPRequestHandler, HTTPServer

global sslcontext
sslcontext = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
sslcontext.options |= ssl.OP_NO_TLSv1
sslcontext.options |= ssl.OP_NO_TLSv1_1
sslcontext.protocol = ssl.PROTOCOL_TLSv1_2
sslcontext.set_ciphers("ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305")
sslcontext.set_ecdh_curve("secp384r1")
sslcontext.load_cert_chain("/home/pi/keys/fullchain.pem", "/home/pi/keys/privkey.pem")

class HSTSHandler(SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload")
        SimpleHTTPRequestHandler.end_headers(self)

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    daemon_threads = True

def main():
    try:
        os.chdir("/media/external")#auto-change working directory
        SimpleHTTPRequestHandler.sys_version = "0.1"#display custom Python system version
        SimpleHTTPRequestHandler.server_version = "0.2"#display custom server software version
        my_server = ThreadedHTTPServer(('', 443), HSTSHandler)
        my_server.socket = sslcontext.wrap_socket(my_server.socket, server_side=True)
        print('Starting server, use <Ctrl-C> to stop')
        my_server.serve_forever()

    except KeyboardInterrupt:
        print(' received, shutting down server')
        my_server.shutdown()

if __name__ == '__main__':
    main()
EN

回答 1

Code Review用户

回答已采纳

发布于 2018-07-06 12:55:41

  1. 当从位置导入名称(模块、包、动态库、.)时,不要在一行中混合多个位置。也就是说,这个:导入操作系统,ssl .应该是:导入os导入ssl --这纯粹是一个文体上的考虑,它是佩普-8官方风格指南中列出的规则之一。
  2. 全球变量应该是最后的手段。它们扰乱了全局命名空间,在读取代码时很难跟踪,并且在使用线程时非常容易出现争用条件。在这里,您可以将上下文作为参数传递,也可以通过附加上下文作为属性来设置另一个类。假设您必须在foofunc_a()之间共享func_b()。三种不同的方法:
    • 使foo全局化(类似于您对上下文所做的操作,而不是很好):foo = Foo() def func_a():foo.method_1() def func_b():foo.method_2() func_a() func_b()
    • 传递foo作为参数: def func_a( foo ):foo.method_1() def func_b(foo):foo.method_2() def main():Foo= Foo() func_a(foo=foo) func_b(foo=foo)
    • 使foo具有一个类属性: MyClass: def __init__(self,foo):self.foo = foo func_a(self):self.foo.method_1() def func_b(self):self.foo.method_2() my_class = MyClass(Foo()) my_class.func_a() my_class.func_b()

即使坚持使用全局变量,设置global sslcontext也是不必要的,因为您没有重新分配它。如果没有为变量赋值,Python将: i.尝试在本地查找名称。如果失败,请查找全局范围中的名称;最后,引发一个NameError以指示变量不存在于任何作用域中。因此,如果在本地引用sslcontext,解释器将找到全局名称(ii.)。但它读不懂你的心思。如果您指定了sslcontext = 42,Python将假设您希望创建一个名为“sslcontext”和值为42的新的局部变量,而不是重新分配全局sslcontext。就这样。这就是global进来的地方,这就是它的全部好处。

  1. HSTSHandler.end_headers()中,这个成语:SimpleHTTPRequestHandler.end_headers(自我).可以通过调用super(),然后调用super().end_headers()来更清楚地表示。这是一个很好的实践,同时也保证了多重继承的正确处理.
  2. 这里不需要显式设置源代码编码,因为ASCII就足够了。

这是我所能给你的,没有更多的背景来回答这个问题。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/197666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档