Gracefully handling application exceptions in a Tornado application
之前在DigitalOcean 的主機上用wordpress架了一個web site站臺,只使用了 port 80, 後來在 443 port 架了 tornado, 滿神奇的,tornado 可以直接使用 letsencrypt 的憑證檔案。
後來發現 googlebot 會來parse 443 port 裡的資料。所以我希望 404 錯誤的資料就從80 port 裡重新取得一次,丟給Google.
取得 ssl 憑證
照上面教學的指令下,只用一行就可以產生憑證。知道網站的根目錄用這行(指令1號):
letsencrypt certonly --webroot -w /var/www/example -d example.com
如果你完全沒有網站,可以使用這行(指令2號):
letsencrypt certonly --standalone -d example.com -d www.example.com
指令1號,letsencrypt 會放東西在 webroot 目錄裡,然後letsencrypt用 80 port 連回我們伺服器進去測試。
指令2號,會自動產生一個 80 port 的 service,然後letsencrypt用 80 port 連回我們伺服器進去測試。
這2個指令,都會因此去使用 443 port,實際上原理不需要了解太多,certbot 寫的滿聰明的,會在畫面上有提醒。產生完,手動測一下 renew,沒問題的把把 renew 指令放進排程裡。
letsencrypt renew --dry-run --agree-tos
成功後就會在ubuntu的/etc/letsencrypt/archive/ 下面看到憑證了。
在 80和443 port 都已經被其他程式使用中的請況下,需要更進階的設定,參考看看這一篇:
例如:
letsencrypt certonly --standalone -d example.com --tls-sni-01-port 445 --http-01-port 82
修改Tornado的 ssl_options
tornado改程式,須追加此兩個檔案的路徑在ssl_options下面,並注意檔案許可權要能被讀。
http_server = tornado.httpserver.HTTPServer(Application(),
ssl_options={
“certfile”: “cert.pem”, #自行填好路徑
“keyfile”: “privkey.pem”, #自行填好路徑
})
要使用下面的這組設定值來完成自動轉發:
default_handler_class
anddefault_handler_args
: This handler will be used if no other match is found; use this to implement custom 404 pages (new in Tornado 3.2).
範例寫法:
import tornado.web
class BaseHandler(tornado.web.RequestHandler):
"""
Base handler gonna to be used instead of RequestHandler
"""
def write_error(self, status_code, **kwargs):
if status_code in [403, 404, 500, 503]:
self.write('Error %s' % status_code)
else:
self.write('BOOM!')
class ErrorHandler(tornado.web.ErrorHandler, BaseHandler):
"""
Default handler gonna to be used in case of 404 error
"""
pass
class MainHandler(BaseHandler):
"""
Main handler
"""
def get(self):
self.write('Hello world!')
- Settings. We need to define
default_handler_class
anddefault_handler_args
as well
settings = {
'default_handler_class': ErrorHandler,
'default_handler_args': dict(status_code=404)
}
- Application.
application = tornado.web.Application([
(r"/", MainHandler)
], **settings)
as result. all errors except 404 gonna be handled by BaseHandler. 404 – ErrorHandler. that’s it