0x00 概述
我们使用Poco库的 Poco::Net::HTMLForm 类可以轻松实现表单数据的提交。
0x01 ApiPost提交表单数据
0x02 HttpClient类
#ifndef HTTPCLIENT_H
#define HTTPCLIENT_H
#include <string>
#include <map>
#include <Poco/URI.h>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPCredentials.h>
#include <Poco/Net/HTMLForm.h>
#include <Poco/StreamCopier.h>
#include <Poco/NullStream.h>
#include <Poco/Exception.h>
class HttpClient
{
public:
HttpClient(const std::string &host, const std::string &port = "80");
std::string Get(const std::string &path,
const std::map<std::string, std::string> &header = std::map<std::string, std::string>());
// 在Query中添加表单数据
std::string Post(const std::string &path,
const std::map<std::string, std::string> &query = std::map<std::string, std::string>(),
const std::map<std::string, std::string> &header = std::map<std::string, std::string>());
// 在Body中使用JSON或XML数据
std::string Post(const std::string &path,
const std::string &body,
const std::map<std::string, std::string> &header = std::map<std::string, std::string>());
bool DoRequest(Poco::Net::HTTPClientSession &session,
Poco::Net::HTTPRequest &request,
Poco::Net::HTTPResponse &response,
std::string &responseMsg);
bool DoRequest(Poco::Net::HTTPClientSession &session,
Poco::Net::HTTPRequest &request,
Poco::Net::HTTPResponse &response,
Poco::Net::HTMLForm &Query,
std::string &responseMsg);
bool DoRequest(Poco::Net::HTTPClientSession &session,
Poco::Net::HTTPRequest &request,
Poco::Net::HTTPResponse &response,
const std::string &Body,
std::string &responseMsg);
private:
std::string m_host;
std::string m_port;
};
#endif // HTTPCLIENT_H
#include "httpclient.h"
#include <sstream>
HttpClient::HttpClient(const std::string &host, const std::string &port)
: m_host(host), m_port(port)
{
}
std::string HttpClient::Get(const std::string &path,
const std::map<std::string, std::string> &header)
{
try
{
Poco::Net::HTTPClientSession session(m_host, std::stoi(m_port));
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
// 设置请求头
request.set("User-Agent", "PocoRuntime-PocoRuntime/1.1.0");
for (auto item : header)
{
request.set(item.first, item.second);
}
Poco::Net::HTTPResponse response;
std::string retMsg;
if (DoRequest(session, request, response, retMsg))
{
printf("%s\n", retMsg.c_str());
}
return retMsg;
}
catch (const Poco::Exception &ex)
{
printf("%s\n", ex.displayText().c_str());
}
return "";
}
std::string HttpClient::Post(const std::string &path,
const std::map<std::string, std::string> &query,
const std::map<std::string, std::string> &header)
{
try
{
Poco::Net::HTTPClientSession session(m_host, std::stoi(m_port));
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPMessage::HTTP_1_1);
// 设置请求头
request.set("User-Agent", "PocoRuntime-PocoRuntime/1.1.0");
for (auto item : header)
{
request.set(item.first, item.second);
}
// 设置请求参数
Poco::Net::HTMLForm formQuery;
for (auto item : query)
{
formQuery.add(item.first, item.second);
}
formQuery.prepareSubmit(request);
Poco::Net::HTTPResponse response;
std::string retMsg;
if (DoRequest(session, request, response, formQuery, retMsg))
{
printf("%s\n", retMsg.c_str());
}
return retMsg;
}
catch (const Poco::Exception &ex)
{
printf("[%s:%d] %s\n", __FILE__, __LINE__, ex.displayText().c_str());
}
return "";
}
std::string HttpClient::Post(const std::string &path,
const std::string &body,
const std::map<std::string, std::string> &header)
{
try
{
Poco::Net::HTTPClientSession session(m_host, std::stoi(m_port));
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPMessage::HTTP_1_1);
// 设置请求头
request.set("User-Agent", "PocoRuntime-PocoRuntime/1.1.0");
for (auto item : header)
{
request.set(item.first, item.second);
}
// XML类型的请求体
// request.setContentType("application/xml");
// request.setContentLength(body.length());
Poco::Net::HTTPResponse response;
std::string retMsg;
if (DoRequest(session, request, response, body, retMsg))
{
printf("%s\n", retMsg.c_str());
}
return retMsg;
}
catch (const Poco::Exception &ex)
{
printf("[%s:%d] %s\n", __FILE__, __LINE__, ex.displayText().c_str());
}
return "";
}
bool HttpClient::DoRequest(Poco::Net::HTTPClientSession &session,
Poco::Net::HTTPRequest &request,
Poco::Net::HTTPResponse &response,
std::string &repMsg)
{
session.sendRequest(request); // 发送请求
std::istream &is = session.receiveResponse(response); // 接收响应
std::ostringstream oss;
printf("[%s:%d] %d %s\n", __FILE__, __LINE__, response.getStatus(), response.getReason().c_str());
if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
{
// Poco::StreamCopier::copyStream(rs, std::cout);
Poco::StreamCopier::copyStream(is, oss);
if (!oss.str().empty())
{
// printf("[%s:%d] %s\n", __FILE__, __LINE__, oss.str().c_str());
repMsg = oss.str();
}
return true;
}
else
{
printf("[%s:%d] -----HTTPResponse error-----\n", __FILE__, __LINE__);
Poco::NullOutputStream null;
Poco::StreamCopier::copyStream(is, null);
return false;
}
}
bool HttpClient::DoRequest(Poco::Net::HTTPClientSession &session,
Poco::Net::HTTPRequest &request,
Poco::Net::HTTPResponse &response,
Poco::Net::HTMLForm &Query,
std::string &responseMsg)
{
std::ostream &os = session.sendRequest(request); // 发送请求
// 添加请求参数
Query.write(os);
os.flush();
std::istream &is = session.receiveResponse(response); // 接收响应
std::ostringstream oss;
printf("[%s:%d] %d %s\n", __FILE__, __LINE__, response.getStatus(), response.getReason().c_str());
if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
{
// Poco::StreamCopier::copyStream(rs, std::cout);
Poco::StreamCopier::copyStream(is, oss);
if (!oss.str().empty())
{
// printf("[%s:%d] %s\n", __FILE__, __LINE__, oss.str().c_str());
responseMsg = oss.str();
}
return true;
}
else
{
printf("[%s:%d] -----HTTPResponse error-----\n", __FILE__, __LINE__);
Poco::NullOutputStream null;
Poco::StreamCopier::copyStream(is, null);
return false;
}
}
bool HttpClient::DoRequest(Poco::Net::HTTPClientSession &session,
Poco::Net::HTTPRequest &request,
Poco::Net::HTTPResponse &response,
const std::string &Body,
std::string &responseMsg)
{
std::ostream &os = session.sendRequest(request); // 发送请求
// 添加请求体
os << Body;
os.flush();
std::istream &is = session.receiveResponse(response); // 接收响应
std::ostringstream oss;
printf("[%s:%d] %d %s\n", __FILE__, __LINE__, response.getStatus(), response.getReason().c_str());
if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
{
// Poco::StreamCopier::copyStream(rs, std::cout);
Poco::StreamCopier::copyStream(is, oss);
if (!oss.str().empty())
{
// printf("[%s:%d] %s\n", __FILE__, __LINE__, oss.str().c_str());
responseMsg = oss.str();
}
return true;
}
else
{
printf("[%s:%d] -----HTTPResponse error-----\n", __FILE__, __LINE__);
Poco::NullOutputStream null;
Poco::StreamCopier::copyStream(is, null);
return false;
}
}
0x03 使用方法
#include <iostream>
#include <memory>
#include "httpclient.h"
using namespace std;
int main()
{
std::unique_ptr<HttpClient> httpCli(new HttpClient("localhost", "18080"));
std::map<std::string, std::string> header{{"content-type", "application/x-www-form-urlencoded"}};
// localhost:18080?name=admin&password=admin&gender=male&subscribe=on
std::map<std::string, std::string> query{{"name", "admin"},
{"password", "admin"},
{"gender", "male"},
{"subscribe", "on"}};
// 提交表单数据
httpCli->Post("/", query, header);
cout << "==Over==" << endl;
return 0;
}