2018年3月

0x00 前情提要
-
Python-EngineIO 没有实现 Socket.IO 中 JSONP-Polling 的支持,于是尝试着动态 Patch。
Python 动态 Patch 实战 (1)

0x01 起因
-
真的是没有想到,在给 Python-EngineIO 加上 JSONP-polling 支持之后,这么快就遇到了第二个需要 Patch 的情况...

这次是因为 eventlet 并没有正确处理 WSGI environ string
导致百分号编码 (Percent-encoding) 出现在 URL 中时
可能会导致 wsgi app 崩溃的 bug

0x02 相关
-
Eventlet Issue#468
Patch 代码

0x00 前言
-
其实我也不太清楚这种操作到底该叫什么
不过跟 Monkey patch 似乎是一个用途,就是在运行时修改代码
于是我就先叫他 Dynamic patch

0x01 起因
-
在使用 Flask-SocketIO 的时候,发现其并没有完全实现所有的 socket.io 中的 transport 协议
于是想手动支持一下 JSONP Polling

看着 eventlet 提供的 monkey_patch(),发现我是不是也可以动态 patch 一下他的代码
这样可以最大限度的保持项目的干净,而不用再维护一个库甚至多个库的代码分支

0x02 实战
-
当同时使用 eventlet 和 Pycharm 的 debugger 时,需要注意不能给 thread 打 monkey patch, 否则 debugger 会坏掉。

跟着代码摸了几个小时,再看了看官方 nodejs 版的 server 代码,又给官方 demo 抓了一下包,大概摸清了协议,于是把

engineio.server.Server::_ok()
engineio.payload.Payload::decode()
engineio.payload.Payload::encode()
engineio.server.Server::handle_connect()
engineio.server.Server::_handle_connect()

这五个函数替换掉了,总体思路比较简单,socket.io 协议的 payload 不变,针对请求入口和出口为 JSONP 请求做出相应修改即可。

0x03 相关
-
Patch 代码在 Github Gist
Python-EngineIO 的 Issue