SimpleHTTPRequestHandlerを使うと、現在のディレクトリ以下のファイルを返す簡易Webサーバが作れます。
do_GET
をオーバーライドすることで、ふるまいを簡単に変更できます。
do_POST
を定義すれば、POSTメソッドも模擬できます。
python2とpython3のどちらでも動く簡単な実装は以下のとおりです。
dummy_server.py
try:
# python3
from http.server import HTTPServer, SimpleHTTPRequestHandler
except:
# python2
from SimpleHTTPServer import SimpleHTTPRequestHandler
from BaseHTTPServer import HTTPServer
class RequestHandler(SimpleHTTPRequestHandler, object):
def print_info(self):
self.log_message("%s %s\n%s", self.command, self.path, self.headers)
def do_GET(self):
self.print_info()
super(RequestHandler, self).do_GET()
def do_POST(self):
self.do_GET()
httpd = HTTPServer(("", 8000), RequestHandler)
httpd.serve_forever()
ルーティング、コネクション切断、タイムアウトなど
様々なふるまいの変更を簡単にできます。
- ルーティング的なことをするには
self.path
を書き換えることでできます - コネクションの切断・キャンセルを模擬するには途中でreturnするなどで
- 応答時間を長くする(タイムアウトのテストなど)にはsleepで待つなど
dummy_server.py
def do_GET(self):
self.print_info()
if self.path == "/test":
self.path = "/dummy_server.py"
elif self.path == "/test2":
return
else:
from time import sleep
sleep(5)
super(RequestHandler, self).do_GET()
2回に1回エラー、はじめの2回はエラーなどの制御
リトライ実行で成功するパターンなどのテストにも使えます。
dummy_server.py
from itertools import chain, repeat
from time import sleep
try:
# python3
from http.server import HTTPServer, SimpleHTTPRequestHandler
except:
# python2
from SimpleHTTPServer import SimpleHTTPRequestHandler
from BaseHTTPServer import HTTPServer
def close():
return True, None
def wait(time_seconds, path=None):
def f():
sleep(time_seconds)
return False, path
return f
def page(path):
return wait(0, path)
path_map = {
"/test": chain([close, wait(3, "/dummy_server.py"), None, page("/dummy_server.py")]),
"/test2": (x for seq in repeat((close, page("/dummy_server.py"))) for x in seq),
"/dummy_server.py": chain([close, close, wait(1)], repeat(None))
}
class RequestHandler(SimpleHTTPRequestHandler, object):
def print_info(self):
self.log_message("%s %s\n%s", self.command, self.path, self.headers)
def do_GET(self):
self.print_info()
iterator = path_map.get(self.path)
if iterator:
f = next(iterator, None)
if f:
ret, path = f()
if ret:
return
if path:
self.path = path
super(RequestHandler, self).do_GET()
def do_POST(self):
self.do_GET()
httpd = HTTPServer(("", 8000), RequestHandler)
httpd.serve_forever()