基於boost asio的http server | coolEx
基於boost asio的http server
上次在CSDN上看見一篇部落格,上面有一個建議非常好:給應用增加一個http遠端存取介面,用於查詢應用當前的狀態。這也是為什麼會要搞這個東西的原因之一。另外還有個原因,就是要通過標準的http協議,方便應用的分布式部署。
這個http server,完全是參照asio的example搞的,地址在這裡。惟一的改動,就是在request_handler類中,增加了一個註冊url的介面。通過uri和對應的functor組成一對映射,在請求對應uri的時候,調用映射的functor。代碼:
1 2 3 4 5 6 7 |
void http::RequestHandler::registerPath(std::string path, RequestHandleFunc f) { pathToRequestHandle.insert(std::pair<std::string, RequestHandleFunc>(path, f)); } |
其中,RequestHandleFunc的定義為:
| 1 |
typedef boost::function<void (const Request &req, Reply &rep)> RequestHandleFunc; |
這樣,在原來RequestHandler::handleRequest的地方,就可以直接通過這個map中的值,獲得真正處理請求的函數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
std::map<std::string, RequestHandleFunc>::iterator funcIter = pathToRequestHandle.find(request_path); if(funcIter == pathToRequestHandle.end()) { rep = Reply::stock_reply(Reply::not_found); return; } RequestHandleFunc f = funcIter->second; f(req, rep); |
當然,這裡還可以擴充下,不直接儲存uri,而是儲存匹配uri的Regex。不過這樣處理起來會比較麻煩,也有效能上的損耗,針對這種簡單的應用,就暫時不加上這個功能了。
除了增加了註冊處理函數,還對parse http請求進行了一些擴充:
- 將query string從url中分離。這個功能主要是針對註冊處理函數而修改的。原來的parse函數,將整個請求url都放在一個string中,導致後面的querystring不同,都需要重新註冊。現在在Request類中增加了querystring這個變數,並將url中問號(‘?’)以後的字元放到這個變數中。
- 增加了對body部分的儲存。這個功能主要是後期可能會用來接收http put請求,接受遠端檔案傳輸。
除了這寫擴充,以後可能還要對http頭的Authorization進行擴充,增加http server的安全性。目前這樣可以基本實現http 1.0協議,應該已經差不多了,就最初的目的而言,短串連已經可以滿足需求了。
抄了這麼多代碼,對boost的bind有了一定的瞭解,不過對share_ptr還是不太清楚。boost庫裡面很多的設計,都非常值得學習。