当社はIT技術のオンライン教育を得意としたセミナー専門会社です。 | 一戸英男

ITエンジニアの技術力UPをお約束します。

備忘録:pythonマルチスレッド pasteサーバ redirectでエラー発生の場合の対処

python bottleフレームワークでは内部のマルチスレッドhttpサーバでpasteサーバが使われるケースが多い。しかし、redirect処理を行った際にエラーが吐かれてしまうという問題に遭遇しました。処理自体は問題なく動作するのですがやはり気になります。この問題を解決するためにpasteサーバ関連で呼び出されるライブラリーのコードをトレースして原因がわかりました。この記事はその備忘録として残します。

実際に起きてるエラーはこんな感じ。

そもそも20行目の「TypeError: a bytes-like object is required, not ‘str’」これが勘違いのもとだった。よくある関数returnでHTMLテンプレートに返す際にencodeやdecode処理でutf-8に変換しないと駄目な場合があります。これが抜けているのかな!?と思いきや全く違うところに問題があった。

pasteサーバでredirect処理した場合に発生するエラー出力結果

python3になってからstringsは文字コードの扱いがUnicodeに変わりました。しかしネットワーク上での通信はbyte stringになる必要があり、よく使われるライブラリーではこのUnicodeへの対応がきっちり済んでいるため問題が生じるケースが少ないのですが稀にpython2.x時代からpython3ソースコード対応が中途半端なものがあります。つまり移行が完全にできていないケースだったようです。幸いにも原因は15行目のこれ「self.wsgi_write_chunk(”)」が原因であることにすぐに気がつけた。つまりhttpプロトコルのメッセージヘッダ項目やメッセージボディが空っぽの場合にきちんと処理ができなくて20行目のエラーになってしまうというものです。


まとめると、redirectの処理はメッセージヘッダの一部項目が空であるため、ライブラリーが誤って20行目のエラーを吐き出してしまう。これを回避するためにredirectへ具体的なレスポンスコードを指定してあげることでメッセージヘッダ項目が空になることを防ぐ。

リダイレクト レスポンスコード

  • 301 Moved Permanently
  • 302 Found(Moved Temporary
  • 303 See Other
  • 307 Temporary Redirect

redirectの際にレスポンスコード301を入れて空になるのを防いだところエラーが消えた