8080ポートを待ち受けてリクエストをそのまま別スクリプト(シェルスクリプト)に渡すだけ、っていうのをしたかったんですが、いいコマンドが見つからなかったので勉強がてら自作してみました。もともとはncコマンドでやろうとしていたんですが、データを出力してもresponseヘッダにcontent-lengthを書いてないとコネクションを切断してくれなかったので…

設計

  1. 8080ポートを待ち受ける
  2. リクエストが来たら、外部スクリプト(listen)を起動する
  3. 外部スクリプトを起動するとき、リクエストの内容をそのまま標準入出力経由で渡す
  4. 外部スクリプトの標準出力を取り込んでそのままレスポンスにする

実装

#!/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()
view raw server hosted with ❤ by GitHub

simple server

参考

ソケットプログラミング HOWTO — Python 2.7ja1 documentation