2015-09-23 29 views
2

讀取JSON數據我設置簡單的服務器如在Python食譜(ch.11)描述cgi.FieldStorage不從requests.post

# server.py 

import cgi 


def notfound_404(environ, start_response): 
    start_response('404 Not found', [('Content-type', 'text-plain')]) 
    return [b'Not found'] 


class PathDispatcher: 
    def __init__(self): 
     self.pathmap = {} 

    def __call__(self, environ, start_response): 
     path = environ['PATH_INFO'] 

     post_env = environ.copy() 
     post_env['QUERY_STRING'] = '' 

     params = cgi.FieldStorage(fp=environ['wsgi.input'], environ=post_env, keep_blank_values=True) 

     environ['params'] = {key: params.getvalue(key) for key in params} 

     method = environ['REQUEST_METHOD'].lower() 

     handler = self.pathmap.get((method, path), notfound_404) 
     return handler(environ, start_response) 

    def register(self, method, path, function): 
     self.pathmap[method.lower(), path] = function 
     return function 

# app.py 

def send_json(environ, start_response): 
    start_response('200 OK', [('Content-type', 'text/plain')]) 

    params = environ['params'] 

    result = "" 

    for key, param in params.iteritems(): 
     result += str(key) + ' :: ' + str(param) + '\n' 

    yield result.encode('utf-8') 


if __name__ == '__main__': 
    from server import PathDispatcher 
    from wsgiref.simple_server import make_server 

    dispatcher = PathDispatcher() 
    dispatcher.register('POST', '/send-json', send_json) 

    httpd = make_server('', 8080, dispatcher) 
    print('Listening on 8080...') 

    httpd.handle_request() 

簡單的代理髮送一些JSON與python.requests數據

# agent.py 

import requests 
import json 

json_data = {'some': 'data', 'moredata':[{1: 'one'}, {2: 'two'}]} 

url = "http://localhost:8080/send-json" 
headers = {'Content-Type': 'application/json'} 

r = requests.post(url=url, data=json.dumps(json_data), headers=headers) 

print r.text 

不幸的是,它會產生象這樣的錯誤

Traceback (most recent call last): 
    File "/usr/lib/python2.7/wsgiref/handlers.py", line 85, in run 
    self.result = application(self.environ, self.start_response) 
    File "/home/phux/PycharmProjects/printoscope_sql_injection/server.py", line 24, in __call__ 
    environ['params'] = {key: params.getvalue(key) for key in params} 
    File "/usr/lib/python2.7/cgi.py", line 517, in __iter__ 
    return iter(self.keys()) 
    File "/usr/lib/python2.7/cgi.py", line 582, in keys 
    raise TypeError, "not indexable" 
TypeError: not indexable 
127.0.0.1 - - [23/Sep/2015 12:25:17] "POST /initial-scan HTTP/1.1" 500 59 

應用無法通過接收到的數據進行迭代,並wsgi.FieldStorage不包含MiniFieldStorage領域只是原始的JSON數據

FieldStorage(None, None, '{"moredata": [{"1": "one"}, {"2": "two"}], "some": "data"}') 

如果我嘗試發送數據這樣

r = requests.post(url=url, data=json_data) 

一切工作正常,FieldStorage看起來不錯

FieldStorage(None, None, [MiniFieldStorage('moredata', '1'), MiniFieldStorage('moredata', '2'), MiniFieldStorage('some', 'data')]) 

但我需要在最終應用接收JSON數據,所以......提前

感謝

Phux

回答

0

-------------- SOLUTION-- -----------

只需更換在server.py

post_env = environ.copy() 
post_env['QUERY_STRING'] = '' 

params = cgi.FieldStorage(fp=environ['wsgi.input'], environ=post_env, keep_blank_values=True) 

environ['params'] = {key: params.getvalue(key) for key in params} 

這些線路有了這個

try: 
    request_body_size = int(environ.get('CONTENT_LENGTH', 0)) 
except ValueError: 
    request_body_size = 0 

request_body = environ['wsgi.input'].read(request_body_size) 

params = json.loads(request_body) 

environ['params'] = {key: params[key] for key in params} 

cgi.FieldStorage期望表單,我不發送一個......這是問題的根源。 app.py中的一些細微修改也是需要的,但情況並非如此,並且可以很容易地進行調整。

相關問題