1
|
|
|
<?php |
2
|
|
|
namespace QiniuRtc; |
3
|
|
|
|
4
|
|
|
use \QiniuRtc\HttpResponse; |
5
|
|
|
|
6
|
|
|
class HttpRequest |
7
|
|
|
{ |
8
|
|
|
const DELETE = "DELETE"; |
9
|
|
|
const GET = "GET"; |
10
|
|
|
const POST = "POST"; |
11
|
|
|
|
12
|
|
|
private static $verifyPeer = false; |
13
|
|
|
private static $socketTimeout = null; |
14
|
|
|
private static $defaultHeaders = array(); |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Verify SSL peer |
18
|
|
|
* @param bool $enabled enable SSL verification, by default is false |
19
|
|
|
*/ |
20
|
|
|
public static function verifyPeer($enabled) |
21
|
|
|
{ |
22
|
|
|
self::$verifyPeer = $enabled; |
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Set a timeout |
27
|
|
|
* @param integer $seconds timeout value in seconds |
28
|
|
|
*/ |
29
|
|
|
public static function timeout($seconds) |
30
|
|
|
{ |
31
|
|
|
self::$socketTimeout = $seconds; |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Set a new default header to send on every request |
36
|
|
|
* @param string $name header name |
37
|
|
|
* @param string $value header value |
38
|
|
|
*/ |
39
|
|
|
public static function defaultHeader($name, $value) |
40
|
|
|
{ |
41
|
|
|
self::$defaultHeaders[$name] = $value; |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Clear all the default headers |
46
|
|
|
*/ |
47
|
|
|
public static function clearDefaultHeaders() |
48
|
|
|
{ |
49
|
|
|
self::$defaultHeaders = array(); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* This function is useful for serializing multidimensional arrays, and avoid getting |
54
|
|
|
* the "Array to string conversion" notice |
55
|
|
|
*/ |
56
|
|
|
public static function http_build_query_for_curl($arrays, &$new = array(), $prefix = null) |
57
|
|
|
{ |
58
|
|
|
if (is_object($arrays)) { |
59
|
|
|
$arrays = get_object_vars($arrays); |
60
|
|
|
} |
61
|
|
|
foreach ($arrays as $key => $value) { |
62
|
|
|
$k = isset($prefix) ? $prefix . '[' . $key . ']' : $key; |
63
|
|
|
if (!$value instanceof \CURLFile and (is_array($value) or is_object($value))) { |
|
|
|
|
64
|
|
|
self::http_build_query_for_curl($value, $new, $k); |
65
|
|
|
} else { |
66
|
|
|
$new[$k] = $value; |
67
|
|
|
} |
68
|
|
|
} |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
private static function getArrayFromQuerystring($querystring) |
72
|
|
|
{ |
73
|
|
|
$pairs = explode("&", $querystring); |
74
|
|
|
$vars = array(); |
75
|
|
|
foreach ($pairs as $pair) { |
76
|
|
|
$nv = explode("=", $pair, 2); |
77
|
|
|
$name = $nv[0]; |
78
|
|
|
$value = $nv[1]; |
79
|
|
|
$vars[$name] = $value; |
80
|
|
|
} |
81
|
|
|
return $vars; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Ensure that a URL is encoded and safe to use with cURL |
86
|
|
|
* @param string $url URL to encode |
87
|
|
|
* @return string |
88
|
|
|
*/ |
89
|
|
|
private static function encodeUrl($url) |
90
|
|
|
{ |
91
|
|
|
$url_parsed = parse_url($url); |
92
|
|
|
$scheme = $url_parsed['scheme'] . '://'; |
93
|
|
|
$host = $url_parsed['host']; |
94
|
|
|
$port = (isset($url_parsed['port']) ? $url_parsed['port'] : null); |
95
|
|
|
$path = (isset($url_parsed['path']) ? $url_parsed['path'] : null); |
96
|
|
|
$query = (isset($url_parsed['query']) ? $url_parsed['query'] : null); |
97
|
|
|
if ($query != null) { |
98
|
|
|
$query = '?' . http_build_query(self::getArrayFromQuerystring($url_parsed['query'])); |
99
|
|
|
} |
100
|
|
|
if ($port && $port[0] != ":") { |
101
|
|
|
$port = ":" . $port; |
102
|
|
|
} |
103
|
|
|
$result = $scheme . $host . $port . $path . $query; |
104
|
|
|
return $result; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
private static function getHeader($key, $val) |
108
|
|
|
{ |
109
|
|
|
$key = trim($key); |
110
|
|
|
return $key . ": " . $val; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Send a cURL request |
115
|
|
|
* @param string $httpMethod HTTP method to use |
116
|
|
|
* @param string $url URL to send the request to |
117
|
|
|
* @param mixed $body request body |
118
|
|
|
* @param array $headers additional headers to send |
119
|
|
|
* @throws Exception if a cURL error occurs |
120
|
|
|
* @return HttpResponse |
121
|
|
|
*/ |
122
|
|
|
public static function send($httpMethod, $url, $body = null, $headers = array()) |
123
|
|
|
{ |
124
|
|
|
if ($headers == null) { |
125
|
|
|
$headers = array(); |
126
|
|
|
} |
127
|
|
|
$annexHeaders = array(); |
128
|
|
|
$finalHeaders = array_merge($headers, self::$defaultHeaders); |
129
|
|
|
foreach ($finalHeaders as $key => $val) { |
130
|
|
|
$annexHeaders[] = self::getHeader($key, $val); |
131
|
|
|
} |
132
|
|
|
$ch = curl_init(); |
133
|
|
|
if ($httpMethod != self::GET) { |
134
|
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $httpMethod); |
135
|
|
|
if (is_array($body) || $body instanceof Traversable) { |
|
|
|
|
136
|
|
|
self::http_build_query_for_curl($body, $postBody); |
137
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody); |
138
|
|
|
} else { |
139
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body); |
140
|
|
|
} |
141
|
|
|
} elseif (is_array($body)) { |
142
|
|
|
if (strpos($url, '?') !== false) { |
143
|
|
|
$url .= "&"; |
144
|
|
|
} else { |
145
|
|
|
$url .= "?"; |
146
|
|
|
} |
147
|
|
|
self::http_build_query_for_curl($body, $postBody); |
148
|
|
|
$url .= urldecode(http_build_query($postBody)); |
149
|
|
|
} |
150
|
|
|
curl_setopt($ch, CURLOPT_URL, self::encodeUrl($url)); |
151
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
152
|
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); |
153
|
|
|
curl_setopt($ch, CURLOPT_MAXREDIRS, 10); |
154
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $annexHeaders); |
155
|
|
|
curl_setopt($ch, CURLOPT_HEADER, true); |
156
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, self::$verifyPeer); |
157
|
|
|
curl_setopt($ch, CURLOPT_ENCODING, ""); // If an empty string, "", is set, a header containing all supported encoding types is sent. |
158
|
|
|
if (self::$socketTimeout != null) { |
159
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, self::$socketTimeout); |
160
|
|
|
} |
161
|
|
|
$response = curl_exec($ch); |
162
|
|
|
$error = curl_error($ch); |
163
|
|
|
if ($error) { |
164
|
|
|
throw new \Exception($error); |
165
|
|
|
} |
166
|
|
|
// Split the full response in its headers and body |
167
|
|
|
$curl_info = curl_getinfo($ch); |
168
|
|
|
$header_size = $curl_info["header_size"]; |
169
|
|
|
$header = substr($response, 0, $header_size); |
170
|
|
|
$body = substr($response, $header_size); |
171
|
|
|
$httpCode = $curl_info["http_code"]; |
172
|
|
|
if ($httpCode >= 400) { |
173
|
|
|
throw new \Exception($body); |
174
|
|
|
} |
175
|
|
|
return new HttpResponse($httpCode, $body, $header); |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.