2011-12-08 64 views
2

我想實現一個簡單的扭曲HTTP服務器,將響應請求從數據庫加載瓷磚並返回它們。但是我發現它解釋請求字符串的方式很奇怪。如何正確解析請求字符串與扭曲(python)

這是我發送到服務器:

curl -d "request=loadTiles&grid[0][x]=17&grid[0][y]=185&grid[1][x]=18&grid[1][y]=184" http://localhost:8080/fetch/ 

我想到什麼request.args是:

{'request': 'loadTiles', 'grid': [{'x': 17, 'y': 185}, {'x': 18, 'y': 184}]} 

如何扭曲的解釋request.args

{'grid[1][y]': ['184'], 'grid[0][y]': ['185'], 'grid[1][x]': ['18'], 'request': ['loadTiles'], 'grid[0][x]': ['17']} 

是否有可能讓它自動分析請求字符串併爲gr創建一個列表ID參數還是我必須手動執行?

我可以json編碼的網格參數,然後解碼它的服務器端,但它似乎是一個不必要的破解。

回答

1

也許不是解析器,如何處理request.args後續處理?

from pyparsing import Suppress, alphas, alphanums, nums, Word 
from itertools import groupby 

# you could do this with regular expressions too, if you prefer 
LBRACK,RBRACK = map(Suppress, '[]') 
ident = Word('_' + alphas, '_' + alphanums) 
integer = Word(nums).setParseAction(lambda t : int(t[0])) 
subscriptedRef = ident + 2*(LBRACK + (ident | integer) + RBRACK) 


def simplify_value(v): 
    if isinstance(v,list) and len(v)==1: 
     return simplify_value(v[0]) 
    if v == integer: 
     return int(v) 
    return v 

def regroup_args(dd): 
    ret = {} 
    subscripts = [] 
    for k,v in dd.items(): 
     # this is a pyparsing short-cut to see if a string matches a pattern 
     # I also used it above in simplify_value to test for integerness of a string 
     if k == subscriptedRef: 
      subscripts.append(tuple(subscriptedRef.parseString(k))+ 
            (simplify_value(v),)) 
     else: 
      ret[k] = simplify_value(v) 

    # sort all the matched subscripted args, and then use groupby to 
    # group by name and list index 
    # this assumes all indexes 0-n are present in the parsed arguments 
    subscripts.sort() 
    for name,nameitems in groupby(subscripts, key=lambda x:x[0]): 
     ret[name] = [] 
     for idx,idxitems in groupby(nameitems, key=lambda x:x[1]): 
      idd = {} 
      for item in idxitems: 
       name, i, attr, val = item 
       idd[attr] = val 
      ret[name].append(idd) 

    return ret 

request_args = {'grid[1][y]': ['184'], 'grid[0][y]': ['185'], 'grid[1][x]': ['18'], 'request': ['loadTiles'], 'grid[0][x]': ['17']} 
print regroup_args(request_args) 

打印

{'grid': [{'y': 185, 'x': 17}, {'y': 184, 'x': 18}], 'request': 'loadTiles'} 

注意,這也簡化了單元素名單只是第0元素值,以及數字字符串轉換爲實際的整數。

+0

謝謝你,這正是我需要的。 – element

4

我不知道爲什麼你會希望你的urlencoded數據根據一些臨時的非標準規則進行解碼,或者你爲什麼會認爲標準治療是「奇怪」的; [在查詢字符串中並不特殊。什麼軟件以這種方式解碼它們?

無論如何,這並不是真的Twisted,而是Python(更一般地說,解析這個數據的方法是web-standard)。您可以通過交互方式通過cgi.parse_qs函數查看您將返回的數據類型。例如:

>>> import cgi 
>>> cgi.parse_qs("") 
{} 
>>> cgi.parse_qs("x=1") 
{'x': ['1']} 
>>> cgi.parse_qs("x[something]=1") 
{'x[something]': ['1']} 
>>> cgi.parse_qs("x=1&y=2") 
{'y': ['2'], 'x': ['1']} 
>>> cgi.parse_qs("x=1&y=2&x=3") 
{'y': ['2'], 'x': ['1', '3']} 

我希望能爲您解決問題。

+0

謝謝你清除它。我來自PHP,它以Paul McGuire自動處理後處理的方式處理GET和POST請求。 – element