//
// NetworkRequest.cpp
//
// Created by duzixi.com on 15/8/25.
//
#include "NetworkRequest.h"
#include <boost/bind.hpp>
using namespace std;
using boost::asio::ip::tcp;
/// POST请求
string PostRequest(char* host, char* path, string form)
{
long length = form.length();
// 声明Asio基础: io_service(任务调度机)
boost::asio::io_service io_service;
// 获取服务器终端列表
tcp::resolver resolver(io_service);
tcp::resolver::query query(host,"8080");
tcp::resolver::iterator iter = resolver.resolve(query);
// 尝试连接每一个终端,直到成功建立socket连接
tcp::socket socket(io_service);
boost::asio::connect(socket, iter);
// 构建网络请求头
// 指定 "Connection: close" 在获取应答后断开连接,确保获文件全部数据。
boost::asio::streambuf request;
ostream request_stream(&request);
request_stream << "POST " << path << " HTTP/1.1\r\n";
request_stream << "Host: " << host << "\r\n";
request_stream << "Accept:application/json\r\n";
request_stream << "Content-Type:application/json\r\n";
request_stream << "charset:utf-8" << "\r\n";
request_stream << "x-requested-custom-flag:cctin" << "\r\n";
request_stream << "Content-Length: " << length << "\r\n";
request_stream << "Connection: close\r\n\r\n"; // 注意这里是两个空行
//request_stream << "Expect:"<<"\r\n";
request_stream << form; //POST 发送的数据本身不包含多于空行
// 发送请求
boost::asio::write(socket, request);
// 读取应答状态. 应答缓冲流 streambuf 会自动增长至完整的行
// 该增长可以在构造缓冲流时通过设置最大值限制
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n\r\n");
// boost::asio::streambuf::const_buffers_type cbt = response.data();
// string ss(boost::asio::buffers_begin(cbt), boost::asio::buffers_end(cbt));
// ss = ParseChunk(ss);
// ss >> response;
// 检查应答是否OK.
istream response_stream(&response);// 应答流
string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
string status_message;
getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
printf("无效响应\n");
return "";
}
if (status_code != 200)
{
printf("响应返回 status code %d\n", status_code);
}
// 读取应答头部,遇到空行后停止
boost::system::error_code err;
std::string ss;
while (true)
{
boost::asio::read_until(socket, response, "\r\n", err);
if (err)
{
break;
}
std::string s(boost::asio::buffer_cast<const char*>(response.data()),response.size());
ss.append(s);
response.consume(response.size());
}
string szc;
szc = ParseChunk(ss);
return szc;
}
string ParseChunk(string& input)
{
char* pdata = (char*)input.c_str();
int pDataLeng = input.size();
char* pdataend = pdata + pDataLeng;
char* pchunkflag = strstr(pdata, "Transfer-Encoding: chunked");
if (!pchunkflag) return input;
char* pStart = strstr(pdata, "\r\n\r\n");
string result;
if (pStart && (pStart += 4) < pdataend)
{
char* pEnd = 0;
do{
pEnd = strstr(pStart, "\r\n");
if (pEnd)
{
string hexsize(pStart);
hexsize = hexsize.substr(0, pEnd - pStart);
char* str;
long lSize = strtol(hexsize.c_str(), &str, 16);
if (!lSize) break;
if (pEnd + 2 + lSize < pdataend)
{
pEnd += 2;
result.append(input.substr(pEnd - pdata, lSize));
pStart = pEnd + lSize;
if (pStart == strstr(pStart,"\r\n"))
{
pStart += 2;
}
}
else{
break;
}
}
else{ break; }
} while (pStart && pEnd);
}
return result;
}
/// GET请求
string GetRequest(char* host, char* path)
{
// 声明Asio基础: io_service(任务调度机)
boost::asio::io_service io_service;
// 获取服务器终端列表
tcp::resolver resolver(io_service);
tcp::resolver::query query(host,"http");
tcp::resolver::iterator iter = resolver.resolve(query);
// 尝试连接每一个终端,直到成功建立socket连接
tcp::socket socket(io_service);
boost::asio::connect(socket, iter);
// 构建网络请求头.
// 指定 "Connection: close" 在获取应答后断开连接,确保获文件全部数据。
boost::asio::streambuf request;
ostream request_stream(&request);
request_stream << "GET " << path << " HTTP/1.1\r\n";
request_stream << "Host: " << host << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// 发送请求
boost::asio::write(socket, request);
// 读取应答状态. 应答缓冲流 streambuf 会自动增长至完整的行
// 该增长可以在构造缓冲流时通过设置最大值限制
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n\r\n");
// 检查应答是否OK.
istream response_stream(&response);
string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
string status_message;
getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
printf("响应无效\n");
}
if (status_code != 200)
{
printf("响应返回 status code %d\n", status_code);
}
// 读取应答头部,遇到空行后停止
boost::asio::read_until(socket, response, "\r\n");
// 显示应答头部
string header;
int len = 0;
while (getline(response_stream, header) && header != "\r")
{
if (header.find("Content-Length: ") == 0) {
stringstream stream;
stream << header.substr(16);
stream >> len;
}
}
long size = response.size();
if (size > 0) {
// ... do nothing ...
}
boost::system::error_code error; // 读取错误
// 循环读取数据流,直到文件结束
while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error))
{
// 获取应答长度
size = response.size();
if (len != 0) {
cout << size << " Byte " << (size * 100) / len << "%" << endl;
}
}
// 如果没有读到文件尾,抛出异常
if (error != boost::asio::error::eof)
{
throw boost::system::system_error(error);
}
cout << size << " Byte 内容已下载完毕." << endl;
// 将streambuf类型转换为string类型,并返回
istream is(&response);
is.unsetf(ios_base::skipws);
string sz;
sz.append(istream_iterator<char>(is), istream_iterator<char>());
return sz;
}
/// GET请求(重载)
string GetRequest(string url)
{
size_t index;
// 去掉url中的协议头
if (url.find("http://") != string::npos ) {
url = url.substr(7);
}
printf("url:%s\n", url.c_str());
// 截取host字符串
index = url.find("/");
char* host = new char[index];
strcpy(host, url.substr(0, index).c_str());
// 截取urlPath字符串
char* urlPath = new char[url.length() - index + 1];
strcpy(urlPath, url.substr(index, url.length() - index).c_str());
return GetRequest(host, urlPath);
}
没有合适的资源?快使用搜索试试~ 我知道了~
boost之http请求及chunked解析
共2个文件
h:1个
cpp:1个
5星 · 超过95%的资源 需积分: 50 25 下载量 126 浏览量
2018-10-13
12:09:38
上传
评论
收藏 3KB RAR 举报
温馨提示
boost:asio请求类,以及chunked解析,亲测可以使用,大家可以根据需要自己修改
资源推荐
资源详情
资源评论
收起资源包目录
boost之http请求及chunked解析.rar (2个子文件)
boost之http请求及chunked解析
NetworkRequest.h 413B
NetworkRequest.cpp 8KB
共 2 条
- 1
资源评论
- 橘子吃汽水2020-03-24可以的 赞一下
lzc1205252122
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功