閱讀628 返回首頁    go 技術社區[雲棲]


evhttp處理POST請求的技巧

evhttp處理POST請求的技巧

evhttplibevent提供的一個輕量級的基於消息驅動的HTTP Server,詳細的資料可以參考libevent的主頁:https://monkey.org/~provos/libevent/ ,本文主要描述如何處理POST請求。

 

美中不足:evhttp不支持POST

evhttpevhttp_request接口中包含一個請求類型type,用來表示HTTP的操作(EVHTTP_REQ_GETEVHTTP_REQ_POST),但evhttp接口並沒有區分GETPOST操作,我們來看具體的接口實現:

evhttp_request_uri: 解析HTTP請求中的ur

evhttp_parse_query: 解析名值對;

 

對於GET操作來說,這兩個函數已經滿足要求,例如:處理如下GET請求:

https://foo.com/?q=test&s=some+thing

evhttp_request_uri: 解析HTTP請求中的ur,得到/?q=test&s=some+thing

evhttp_parse_query: 解析名值對,得到一個evkeyvalq結構,裏麵包含了key/value

的數組.

 

但如果這個請求是用POST發送的,那麼這兩個函數就不適應了:

evhttp_request_uri: 解析HTTP請求中的ur,得到/

evhttp_parse_query: 解析名值對,q=test&s=some+thing是保存在消息體中而不是uri中,因此解析後是一個空的結構。

 

除此之外,evhttp並沒有提供接口訪問POST的消息體中的數據。

 

曲徑通幽:如何處理POST請求?

既然這樣,難道用evhttp就不能使用POST請求了麼?當然不是,隻不過相對GET來說,我們要多費一些周折。下麵就介紹如何在evhttp中處理POST請求。

 

1.       訪問緩衝區獲取POST消息體數據

evhttp_request結構中包含input_buf結構,input_buffer中的buffer就是存放消息體數據的緩衝區,input_buffer還有一個orig_buffer,實際上和buffer指向的是同一塊內存空間,不知道為什麼這樣設計,但我們用的時候直接用buffer就可以了。

 

但這裏的buffer並不是全部存放消息體中的數據,buffer的大小是2N次方,而且總是和實際數據長度最接近的2N次方,個人猜測evhttp可能使用了slab之類的內存預分配機製,所以這樣處理。

那麼我們如何取到真正的數據呢?其實很簡單:input_buffer有一個offset字段,就是用來指明具體的數據長度的。實際使用的時候,你隻要memcpy一把就可以了。

 

2.       模擬GET請求參數

如果你的POST請求消息體中存放的是標準的key=value&key=value.....這種格式的數據,你當然可以自己去解析它,但更聰明的辦法是模擬GET請求,再調用evhttp_parse_query函數來幫你解析。

 

具體步驟如下:

1)      參照“訪問緩衝區獲取POST消息體數據”的指導獲取數據;

2)      將第一步獲取的數據解碼成普通的字符串;

3)      evhttp_request_uri解析出uri

4)      組裝成/?q=test&s=some+thing格式的字符串,注意要自己加上問號”?”

5)      調用evhttp_parse_query解析組裝的字符串

 

需要注意的是:如果你的POST請求消息體中的數據不是這種key=value&key=value.....的格式,那麼就隻能自己處理了,這應該也是evhttp不提供POST請求通用處理的原因吧。

 

 

 

最後更新:2017-04-02 06:51:27

  上一篇:go Windows 映射模式
  下一篇:go VC++技術內幕(第四版)筆記--SetWindowExt和SetViewportExt