-
Notifications
You must be signed in to change notification settings - Fork 13
/
lib_http.php
173 lines (150 loc) · 5.23 KB
/
lib_http.php
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<?php
/**
* Telegram Bot Sample
* ===================
* UWiClab, University of Urbino
* ===================
* Support library. Don't change a thing here.
*/
// Map storing private data of open requests
$curl_requests_private_data = array();
/**
* Prepares an API request using cURL.
* Returns a cURL handle, ready to perform the request, or false on failure.
*
* @param string $url HTTP request URI.
* @param string $method HTTP method ('GET' or 'POST').
* @param array $parameters Query string parameters.
* @param mixed $body String or array of values to be passed as request payload.
* @return object | false cURL handle or false on failure.
*/
function prepare_curl_api_request($url, $method, $parameters = null, $body = null, $headers = null) {
// Parameter checking
if(!is_string($url)) {
Logger::error('URL must be a string', __FILE__);
return false;
}
if($method !== 'GET' && $method !== 'POST') {
Logger::error('Method must be either GET or POST', __FILE__);
return false;
}
if($method !== 'POST' && $body) {
Logger::error('Cannot send request body content without POST method', __FILE__);
return false;
}
if(!$parameters) {
$parameters = array();
}
if(!is_array($parameters)) {
Logger::error('Parameters must be an array of values', __FILE__);
return false;
}
// Complex parameters (i.e., arrays) are encoded as JSON strings
foreach ($parameters as $key => &$val) {
if (!is_numeric($val) && !is_string($val)) {
$val = json_encode($val);
}
}
// Prepare final request URL
$query_string = http_build_query($parameters);
if(!empty($query_string)) {
$url .= '?' . $query_string;
}
Logger::info("HTTP request to {$url}", __FILE__);
// Prepare cURL handle
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_USERAGENT, 'Telegram Bot client, UWiClab (https://github.com/UWiClab/TelegramBotSample)');
if($method === 'POST') {
curl_setopt($handle, CURLOPT_POST, true);
if($body) {
curl_setopt($handle, CURLOPT_POSTFIELDS, $body);
}
}
if(is_array($headers)) {
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
}
return $handle;
}
/**
* Prepares a simple raw download request using the GET method.
*
* @param $url string HTTP request URI.
* @param $output_path string Relative path to the output file.
* @return object | false cURL handle or false on failure.
*/
function prepare_curl_download_request($url, $output_path) {
global $curl_requests_private_data;
// Parameter checking
if(!is_string($url)) {
Logger::error('URL must be a string', __FILE__);
return false;
}
$file_handle = fopen(dirname(__FILE__) . '/' . $output_path, 'wb');
if($file_handle === false) {
Logger::error("Cannot write to path {$output_path}", __FILE__);
return false;
}
Logger::info("HTTP download request to {$url}", __FILE__);
// Prepare cURL handle
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_FILE, $file_handle);
curl_setopt($handle, CURLOPT_BINARYTRANSFER, true);
curl_setopt($handle, CURLOPT_AUTOREFERER, true);
curl_setopt($handle, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($handle, CURLOPT_MAXREDIRS, 1);
curl_setopt($handle, CURLOPT_USERAGENT, 'Telegram Bot client, UWiClab (https://github.com/UWiClab/TelegramBotSample)');
// Store private data
$uuid = uniqid();
curl_setopt($handle, CURLOPT_PRIVATE, $uuid);
$curl_requests_private_data[$uuid] = array(
'file_handle' => $file_handle
);
return $handle;
}
/**
* Performs a cURL request and returns the expected response as string.
*
* @param object Handle to cURL request.
* @return string | false Response as text or false on failure.
*/
function perform_curl_request($handle) {
global $curl_requests_private_data;
$response = curl_exec($handle);
if ($response === false) {
$errno = curl_errno($handle);
$error = curl_error($handle);
Logger::error("Curl returned error $errno: $error", __FILE__);
curl_close($handle);
return false;
}
$http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
// Handle private data associated to the request
$private_uuid = curl_getinfo($handle, CURLINFO_PRIVATE);
if($private_uuid !== false) {
$private_data = $curl_requests_private_data[$private_uuid];
if($private_data !== null) {
// Close file handle
if($private_data['file_handle']) {
fclose($private_data['file_handle']);
}
unset($curl_requests_private_data[$private_uuid]);
}
}
curl_close($handle);
if ($http_code >= 500) {
Logger::warning('Internal server error', __FILE__);
return false;
}
else if($http_code == 401) {
Logger::warning('Unauthorized request (check token)', __FILE__);
return false;
}
else if ($http_code != 200) {
Logger::warning("Request failure with code $http_code ($response)", __FILE__);
return false;
}
else {
return $response;
}
}