forked from chunyi1994/cppevent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhttpclient.cpp
144 lines (119 loc) · 3.56 KB
/
httpclient.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <functional>
#include "httpclient.h"
#include "utils.h"
namespace cppevent{
void parseUrl(const std::string& url, std::string& host, std::string& path);
HttpClient::HttpClient(EventLoop *loop) : tcpClient_(loop), request_(), response_()
{
tcpClient_.setMessageCallback(std::bind(&HttpClient::handleMessage, this, std::placeholders::_1));
}
void HttpClient::addHeader(const std::string &name, const std::string &value)
{
request_[name] = value;
}
void HttpClient::setMessageCallback(const HttpMessageCallback &cb)
{
httpMessageCallback_ = cb;
}
void HttpClient::setHttpMessage(const HttpMessage &msg)
{
request_ = msg;
}
int HttpClient::get(const std::string &url, size_t port)
{
std::string data;
return get(url, data, port);
}
int HttpClient::post(const std::string &url, size_t port)
{
std::string data;
return post(url, data, port);
}
int HttpClient::get(const std::string &url, const std::string& data, size_t port)
{
std::string host;
std::string path;
std::string ip;
parseUrl(url, host, path);
int code = getHostByName(host,ip);
if(code < 0)
{
log("gethostbyname error.");
return code;
}
if(!data.empty())
{
path = path + "?" + data;
}
request_.setRequestLine("GET", path, "HTTP/1.1");
request_["Host"] = host;
setDefaultHeaders(host);
tcpClient_.setConnectionCallback([this](const ConnectionPtr& conn){
if(conn->connecting())
{
std::string str = request_.toString();
//std::cout<<str<<std::endl;
conn->send(str);
}
});
code = tcpClient_.connect(ip, port);
return code;
}
int HttpClient::post(const std::string &url, const std::string& data, size_t port)
{
std::string host;
std::string path;
std::string ip;
parseUrl(url, host, path);
int code = getHostByName(host,ip);
if(code < 0)
{
log("gethostbyname error.");
return code;
}
request_.setRequestLine("POST", path, "HTTP/1.1");
setDefaultHeaders(host);
request_["Host"] = host;
tcpClient_.setConnectionCallback([this, data](const ConnectionPtr& conn){
if(conn->connecting()){
conn->send(request_.toString());
conn->send(data);
}
});
code = tcpClient_.connect(ip, port);
return code;
}
void HttpClient::setDefaultHeaders(const std::string& host)
{
request_["Host"] = host;
request_["Connection"] = "keep-alive";
request_["Accept-Language"] = "zh-CN,zh;q=0.8";
request_["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request_["User-Agent"] = "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36";
request_["Cache-Control"] = "max-age=0";
}
void HttpClient::handleMessage(const ConnectionPtr &conn)
{
std::string msgStr = conn->readAll();
if(msgStr.length() > 11 && beginWith(msgStr, "HTTP/1.")) //11随便打的
{
size_t pos = msgStr.find("\r\n\r\n");
if(pos != std::string::npos)
{
pos += 4;
std::string httpResponseStr = msgStr.substr(0, pos);
msgStr = msgStr.substr(pos, msgStr.length());
response_.parse(httpResponseStr, TYPE_HTTP_RESPONSE);
}
}
if(httpMessageCallback_)
{
httpMessageCallback_(response_, msgStr);
}
auto iterFind = response_.find("Connection");
if(iterFind != response_.end() && iterFind->second == "close")
{
tcpClient_.shutdown();
}
}
}