14

このサイトで、Python を使用してコマンド ライン経由で単純なサーバーを実行するためのスクリプトを見つけました。

printリクエストのコマンドラインからGETおよびPOSTパラメーターを出力したいので、いくつかの行を追加しましたが、どこにも表示されないようです。

s変数 ( pprint (vars(s))) を印刷すると、次のように表示されます。

{'client_address': ('127.0.0.1', 53373),
 'close_connection': 1,
 'command': 'GET',
 'connection': <socket._socketobject object at 0x10b6560c0>,
 'headers': <mimetools.Message instance at 0x10b689ab8>,
 'path': '/favicon.ico',
 'raw_requestline': 'GET /favicon.ico HTTP/1.1\r\n',
 'request': <socket._socketobject object at 0x10b6560c0>,
 'request_version': 'HTTP/1.1',
 'requestline': 'GET /favicon.ico HTTP/1.1',
 'rfile': <socket._fileobject object at 0x10b6538d0>,
 'server': <BaseHTTPServer.HTTPServer instance at 0x10b6893f8>,
 'wfile': <socket._fileobject object at 0x10b6536d0>}

print次に、各インデックス ( ) でコマンドを使用しようとしましたpprint (vars(s.connection))が、うまくいきません。

変更されたスクリプトは次のとおりです。

#!/usr/bin/python
import time
import BaseHTTPServer
from pprint import pprint

HOST_NAME = 'localhost' # !!!REMEMBER TO CHANGE THIS!!!
PORT_NUMBER = 9000 # Maybe set this to 9000.


class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
        def do_HEAD(s):
                s.send_response(200)
                s.send_header("Content-type", "text/html")
                s.end_headers()
        def do_GET(s):
                """Respond to a GET request."""
                s.send_response(200)
                s.send_header("Content-type", "text/html")
                s.end_headers()
                s.wfile.write("<html><head><title>Title goes here.</title></head>")
                s.wfile.write("<body><form action='.' method='POST'><input name='x' value='1' /><input type='submit' /></form><p>This is a test.</p>")
                # If someone went to "http://something.somewhere.net/foo/bar/",
                # then s.path equals "/foo/bar/".
                s.wfile.write("<p>GET: You accessed path: %s</p>" % s.path)
                s.wfile.write("</body></html>")
                pprint (vars(s))
        def do_POST(s):
                """Respond to a POST request."""
                s.send_response(200)
                s.send_header("Content-type", "text/html")
                s.end_headers()
                s.wfile.write("<html><head><title>Title goes here.</title></head>")
                s.wfile.write("<body><p>This is a test.</p>")
                s.wfile.write("<body><form action='.' method='POST'><input type='text' name='xxxxxxxxxxxx' value='0000000000000000000000' /><input type='submit' /></form><p>This is a test.</p>")
                # If someone went to "http://something.somewhere.net/foo/bar/",
                # then s.path equals "/foo/bar/".
                s.wfile.write("<p>POST: You accessed path: %s</p>" % s.path)
                s.wfile.write("</body></html>")
                pprint (vars(s))
                pprint (vars(s.connection))
                pprint (vars(s.headers))
                pprint (vars(s.request))
                pprint (vars(s.rfile))
                pprint (vars(s.server))
                pprint (vars(s.wfile))
                pprint (vars(s.fp))
                """pprint (vars(s.request))"""

if __name__ == '__main__':
        server_class = BaseHTTPServer.HTTPServer
        httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
        print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
        try:
                httpd.serve_forever()
        except KeyboardInterrupt:
                pass
        httpd.server_close()
        print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)

簡単なスクリプトを使用して POST および GET パラメータを出力するにはどうすればよいですか?

コマンド ラインからの望ましい出力は次のようになります。

1.0.0.127. - - [03/Oct/2012 16:02:05] "POST / HTTP/1.1" 200 -
foo=1
bar=2
bis=3
4

2 に答える 2

23

それほど明白ではありませんが、ハンドラーはバックグラウンドでソケットを使用しています。したがって、ソケットから生データを読み取り、それを解釈する必要があります。

モジュールを使用しurlparseます。

  • Python 2 では、urlparse.parse_qs.
  • Python 3 では、ライブラリの名前が変更されました: you want urllib.parse.parse_qs.

Importを実行してから、メソッドを次のようurlparseに変更します。do_POST

def do_POST(s):
        """Respond to a POST request."""

        # Extract and print the contents of the POST
        length = int(s.headers['Content-Length'])
        post_data = urlparse.parse_qs(s.rfile.read(length).decode('utf-8'))
        for key, value in post_data.iteritems():
            print "%s=%s" % (key, value)

        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()
        ...

簡単なテスト クライアントをセットアップします。

#!/usr/bin/env python

import urllib
import urllib2

url = 'http://localhost:9000'
post_dict = {'foo' : 1,
             'bar' : 2,
             'bis' : 3}

params = urllib.urlencode(post_dict)
post_req = urllib2.Request(url)
post_req.add_data(params)

response = urllib2.urlopen(post_req)
response_data = response.read()
response.close()
print response_data

サーバーを起動し、クライアントを実行します。

ire@localhost$ python http_server.py 
Wed Oct  3 21:38:51 2012 Server Starts - localhost:9000
foo=[u'1']
bar=[u'2']
bis=[u'3']
于 2012-10-04T04:42:37.337 に答える
5

cgiの代わりにモジュールを使用できますurlparsecgi箱から出して解析する POST パラメータを実装します。十分にテストされたライブラリを使用する方が良いようです。

import cgi

def do_POST(self):
    form = cgi.FieldStorage(
        fp=self.rfile,
        headers=self.headers,
        environ={"REQUEST_METHOD": "POST"}
    )

    for item in form.list:
        print "%s=%s" % (item.name, item.value)
于 2013-10-03T16:08:22.160 に答える