-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAlirezaHttpClient.h
139 lines (133 loc) · 4.04 KB
/
AlirezaHttpClient.h
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
#ifndef _ALIREZA_HTTP_CLIENT_H_
#define _ALIREZA_HTTP_CLIENT_H_
#include <iostream>
#include <string>
#include <thread>
#include <unordered_map>
#include <functional>
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
#include <winsock2.h>
#include <Windows.h>
#include <ws2tcpip.h>
#include "conio.h"
using namespace std;
#pragma comment(lib,"ws2_32.lib")
class AlirezaHttpClient{
private:
unordered_map<string, string> params;
string hostName;
string requestPath;
int method = 2;
thread *requestThread;
public:
static const int POST = 1, GET = 2;
void sendAsync(string host, function<void(string,string)> onResponse) {
requestThread = new thread(&AlirezaHttpClient::_send,this,host,onResponse);
}
void sendSync(string host,function<void(string,string)> onResponse) {
return _send(host, onResponse);
}
void waitForResult() {
requestThread->join();
}
void setParam(string key, string val) {
params[key] = val;
}
void setMethod(int method) {
this->method = method;
}
void setPath(string path) {
this->requestPath = path;
}
void _send(string host,function<void(string,string)> onResponse) {
hostName = host;
WSADATA wsa;
if (WSAStartup(514, &wsa) != 0) {
throw std::runtime_error("Failed. Error Code : %d" + WSAGetLastError());
}
struct addrinfo *result = NULL, *ptr = NULL, hints;
SOCKET ConnectSocket = INVALID_SOCKET;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(host.c_str(), "80", &hints, &result) != 0) {
throw std::runtime_error("failed to resolve host!");
return;
}
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
throw std::runtime_error("creating socket failed with error: " + WSAGetLastError());
WSACleanup();
return;
}
if (connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen) == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
else {
string request;
if (method == AlirezaHttpClient::GET) {
request += "GET ";
request += requestPath;
request += '?';
for (auto r : params) {
request += r.first;
request += "=";
request += r.second;
}
request += " HTTP/1.0\r\n";
request += "Host: ";
request += hostName;
request += "\r\n\r\n";
}
else if (method == AlirezaHttpClient::POST) {
request += "POST ";
request += requestPath;
request += " HTTP/1.0\r\n";
string paramsString;
for (auto r : params) {
if (paramsString.size()) paramsString += '&';
paramsString += r.first;
paramsString += "=";
paramsString += r.second;
}
request += "Host: ";
request += hostName;
request += "\r\n";
request += "Content-Length: ";
request += to_string(paramsString.size());
request += "\r\n";
request += paramsString;
request += "\r\n";
}
else {
throw runtime_error("bad http method.");
}
::send(ConnectSocket, request.c_str(), request.size(), 0);
char *header = new char[4096];
int headerLen = ::recv(ConnectSocket, header, 4096, 0);
header[headerLen] = 0;
string headerString(header);
unsigned contentLenPos = headerString.find("Content-Length:");
if (contentLenPos == string::npos) {
throw runtime_error("response error");
return;
}
unsigned contentLenEndPos = headerString.find('\n', contentLenPos);
string ln = headerString.substr(contentLenPos + 15, contentLenEndPos - contentLenPos - 15);
int blen;
if (!(ln[0] == '"' || (ln[0] < 58 && ln[0]>47))) blen = 4096; else blen = stoi(ln);
char *body = new char[blen+1];
int bodyLen = ::recv(ConnectSocket, body, blen, 0);
body[bodyLen] = 0;
onResponse(header,body);
closesocket(ConnectSocket);
break;
}
}
}
};
#endif