2020/10/27

Boost asio http request, test with served

served 的 example : handler,有印出 post request 的 body..
    // GET or POST /handlers/{id}/{number:[0-9]+}
    mux.handle("/handlers/{id}/{number:[0-9]+}")

        .post([](served::response & res, const served::request & req) {
            res << "id: ";
            res << req.params["id"];
            res << ", number: ";
            res << req.params["number"];

            std::cout << "POST: " << req.body() << std::endl;
        })
先用 curl 測試一下...
參考這個,依照上面的 url path 修改一下...
curl -X POST -H "Content-Type: text/plain" --data "this is raw data" http123/handlers/id/123
結果 served example : eg_handler 正確送出:
$ ./eg_handlers 
Try this example with:
 curl http://localhost:8123/handlers
 curl http://localhost:8123/handlers/test
 curl http://localhost:8123/handlers/test/10
 curl http://localhost:8123/handlers/test/NaN
POST: this is raw data

對應的 tcp stream code:
#include <boost/asio.hpp>

int main()
{
	boost::asio::ip::tcp::iostream s("127.0.0.1","8123");
	s << "POST /handlers/test/10 HTTP/1.1\r\n";
	s << "Host: 127.0.0.1\r\n";
	s << "Content-Type: text/plain\r\n";
	s << "Content-length: 2\r\n";
	s << "\r\n";
	s << "bb\n";
	s << "\r\n";
}
使用上面修改過的 eg_handler 作為 REST server。可以正確..
Try this example with:
 curl http://localhost:8123/handlers
 curl http://localhost:8123/handlers/test
 curl http://localhost:8123/handlers/test/10
 curl http://localhost:8123/handlers/test/NaN
POST: bb
收到 body : bb

測試 PUT 命令:
用 served example : reset_resource,修改,印出body 和 parameter
   mux.handle("/customers/{id}")
        .get([](served::response & res, const served::request & req) {
            (void) res;
            (void) req;
            // read customer req.params["id"]
            std::cout << "get" << std::endl;
        })
        .put([](served::response & res, const served::request & req) {
            (void) res;
            (void) req;
            // update customer req.params["id"]
            std::cout << "put" + req.params["id"] << std::endl;
            std::cout << "header" << req.header("Content-Length") << std::endl;
            std::cout << "version" << req.HTTP_version() << std::endl;
            std::cout << req.body() << std::endl;
        })
對應使用 asio tcp stream 的 client code:
#include <boost/asio.hpp>

int main()
{
	boost::asio::ip::tcp::iostream s("127.0.0.1","8123");
	s << "PUT /customers/abc HTTP/1.1\r\n";
	s << "Host: 127.0.0.1\r\n";
	s << "Content-Type: text/plain\r\n";
	s << "Content-length: 2\r\n";
	s << "\r\n";
	s << "bb\n";
	s << "\r\n";
}
-- 其實跟 post 一樣…只是 url path 跟 request cmd 不一樣。
節果 eg_reset_resource 一樣正確取得 parameter 跟 body
putabc
header2
versionHTTP/1.1
bb

HOST: 可以不送。
重點是 content-type,沒有這個 key 得話,收不到 body
還有每一行都要是 \r\n 結尾,不可以只用 \n


有關 RESETful client server 的 debug..
client 可以用 curl 和 postman 來發送標準的 http request
然後用 whireshark log HTTP 來比對自己寫的 client 和 postman 送的有什麼不同。

順便記一下,httpie 是 command line 的 http api client, opensource 的
-- 其實或許跟 curl 一樣。

served 的 example,如果要對所有 nic interface 都listen 的話,就用 "0.0.0.0"
這樣舊可以用外部測試了。
-- ref:boost asio tcp server bind to any

沒有留言:

張貼留言