【Python】シンプルなサーバーを自作してみた
8080ポートを待ち受けてリクエストをそのまま別スクリプト(シェルスクリプト)に渡すだけ、っていうのをしたかったんですが、いいコマンドが見つからなかったので勉強がてら自作してみました。もともとはncコマンドでやろうとしていたんですが、データを出力してもresponseヘッダにcontent-lengthを書いてないとコネクションを切断してくれなかったので…
設計
- 8080ポートを待ち受ける
- リクエストが来たら、外部スクリプト(listen)を起動する
- 外部スクリプトを起動するとき、リクエストの内容をそのまま標準入出力経由で渡す
- 外部スクリプトの標準出力を取り込んでそのままレスポンスにする
実装
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python | |
import socket | |
import os | |
from subprocess import Popen, PIPE | |
PORT_NO = 8080 | |
HOSTNAME = '' | |
SCRIPT = "listen" | |
def main(): | |
# Server Socket | |
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
server.bind((HOSTNAME, PORT_NO)) | |
server.listen(1) | |
print 'listenning...' | |
# Client Socket | |
connection = None | |
try: | |
next_script = os.path.abspath(os.path.dirname(__file__) + "/" + SCRIPT) | |
while True: | |
(connection, address) = server.accept() | |
data = connection.recv(1024) | |
if data: | |
# I/O with PIPE | |
process = Popen(next_script, stdin=PIPE, stdout=PIPE) | |
process.stdin.write(data) | |
process.stdin.close() | |
result = process.stdout.read() | |
ret = process.wait() | |
connection.send(result) | |
connection.close() | |
except socket.error, msg: | |
print msg | |
except KeyboardInterrupt: | |
print '' | |
finally: | |
print 'stop' | |
if not connection is None: | |
connection.close() | |
server.close() | |
if __name__ == '__main__': | |
main() |