PluginProbe ʕ •ᴥ•ʔ
Brevo – Email, SMS, Web Push, Chat, and more. / 3.2.0
Brevo – Email, SMS, Web Push, Chat, and more. v3.2.0
2.9.13 2.9.14 2.9.15 2.9.16 2.9.17 2.9.18 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.9 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.2 3.1.20 3.1.21 3.1.22 3.1.23 3.1.24 3.1.25 3.1.26 3.1.27 3.1.28 3.1.29 3.1.3 3.1.30 3.1.31 3.1.32 3.1.33 3.1.34 3.1.35 3.1.36 3.1.37 3.1.38 3.1.39 3.1.4 3.1.40 3.1.41 3.1.42 3.1.43 3.1.44 3.1.45 3.1.46 3.1.47 3.1.48 3.1.49 3.1.5 3.1.50 3.1.51 3.1.52 3.1.53 3.1.54 3.1.55 3.1.56 3.1.57 3.1.58 3.1.59 3.1.6 3.1.60 3.1.61 3.1.62 3.1.63 3.1.64 3.1.65 3.1.66 3.1.67 3.1.68 3.1.69 3.1.7 3.1.70 3.1.71 3.1.72 3.1.73 3.1.74 3.1.75 3.1.76 3.1.77 3.1.78 3.1.79 3.1.8 3.1.80 3.1.81 3.1.82 3.1.83 3.1.84 3.1.85 3.1.86 3.1.87 3.1.88 3.1.89 3.1.9 3.1.90 3.1.91 3.1.92 3.1.93 3.1.94 3.1.95 3.1.96 3.1.97 3.1.98 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 trunk 1.0 1.5 2.0.8 2.9.10 2.9.11 2.9.12
mailin / wonderpush-php-lib / lib / Net / CurlHttpClient.php
mailin / wonderpush-php-lib / lib / Net Last commit date
CurlHttpClient.php 1 year ago HttpClientInterface.php 1 year ago Request.php 1 year ago Response.php 1 year ago
CurlHttpClient.php
181 lines
1 <?php
2
3 namespace WonderPush\Net;
4
5 if (count(get_included_files()) === 1) { http_response_code(403); exit(); } // Prevent direct access
6
7 /**
8 * An HTTP client using PHP's cURL extension
9 */
10 class CurlHttpClient implements HttpClientInterface {
11
12 public static $logging = false;
13 public static $loggingResponses = false;
14
15 /**
16 * The fake HTTP header that will hold the output of `curl_errno()`.
17 */
18 const HEADER_CURL_ERRNO = 'curl_errno';
19
20 /**
21 * The fake HTTP header that will hold the output of `curl_error()`.
22 */
23 const HEADER_CURL_ERROR = 'curl_error';
24
25 /**
26 * Instance of the library for logging purposes.
27 * @var \WonderPush\WonderPush
28 */
29 private $wp;
30
31 /** @var array */
32 private $options;
33 /**
34 * @param \WonderPush\WonderPush $wonderPush WonderPush instance whose credentials are to be used.
35 */
36 public function __construct(\WonderPush\WonderPush $wonderPush, $options = array()) {
37 $this->wp = $wonderPush;
38 $this->options = $options ?: array();
39 }
40
41 public function execute(Request $request) {
42 // Construct absolute URL
43 $root = $request->getRoot() ?: $this->wp->getApiRoot();
44 $path = $request->getPath();
45 if (!\WonderPush\Util\StringUtil::beginsWith($path, '/')) {
46 $path = '/' . $path;
47 }
48 $url = $root . $path;
49
50 $qsParams = $request->getQsParams();
51 $headers = $request->getHeaders();
52 $body = null;
53
54 // Construct $qsParams and $body, and honors $request->getParams() too
55 switch ($request->getMethod()) {
56 case Request::GET:
57 case Request::DELETE:
58 $qsParams = array_merge($qsParams ?: array(), $request->getParams());
59 break;
60 case Request::PUT:
61 case Request::POST:
62 case Request::PATCH:
63 $body = $request->getParams();
64 $files = $request->getFiles();
65 if (count($files)) {
66 $body = $request->getParams() ?: array();
67 foreach ($files as $name => $file) {
68 $body[$name] = new \CURLFile($file['tmp_name'], $file['type'], $file['name']);
69 }
70 } else if (empty($body)) {
71 $body = null;
72 } else {
73 $headers['Content-Type'] = 'application/json';
74 $options = 0;
75 if (defined('JSON_UNESCAPED_SLASHES')) {
76 $options |= JSON_UNESCAPED_SLASHES;
77 }
78 if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) {
79 $options |= JSON_INVALID_UTF8_SUBSTITUTE;
80 } else if (defined('JSON_PARTIAL_OUTPUT_ON_ERROR')) {
81 $options |= JSON_PARTIAL_OUTPUT_ON_ERROR;
82 }
83 $body = json_encode($body, $options);
84 }
85 break;
86 }
87
88 // Incorporate query string into URL
89 if (!empty($qsParams)) {
90 $prevQs = \WonderPush\Util\UrlUtil::parseQueryString(parse_url($url, PHP_URL_QUERY));
91 $qsParams = array_merge($prevQs, $qsParams);
92 $url = \WonderPush\Util\UrlUtil::replaceQueryStringInUrl($url, $qsParams);
93 }
94
95 if (!isset($headers['User-Agent'])) {
96 $curlVersion = curl_version();
97 $headers['User-Agent'] = 'WonderPushApi/' . \WonderPush\WonderPush::API_VERSION
98 . ' WonderPushPhpLib/' . \WonderPush\WonderPush::VERSION
99 . ' curl/' . \WonderPush\Util\ArrayUtil::getIfSet($curlVersion, 'version', 'na')
100 . ' ' . \WonderPush\Util\ArrayUtil::getIfSet($curlVersion, 'ssl_version', 'curlssl/na')
101 ;
102 }
103
104 // Serialize headers for cURL
105 if (empty($headers)) {
106 $headers = null;
107 } else {
108 $headers = array_map(function($key, $value) {
109 if (is_int($key)) {
110 return $value;
111 }
112 return $key . ': ' . $value;
113 }, array_keys($headers), $headers);
114 }
115
116 // Prepare other cURL options: Response headers reader
117 $responseHeaders = array();
118 $readHeaderCallback = function (/** @noinspection PhpUnusedParameterInspection */ $ch, $headerLine) use (&$responseHeaders) {
119 if (\WonderPush\Util\StringUtil::contains($headerLine, ':')) {
120 list($key, $value) = explode(':', trim($headerLine), 2);
121 $responseHeaders[trim($key)] = trim($value);
122 } // else, we're reading the HTTP status line
123 return strlen($headerLine);
124 };
125
126 // Configure cURL
127 $ch = curl_init();
128 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getMethod());
129 curl_setopt($ch, CURLOPT_URL, $url);
130 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
131 curl_setopt($ch, CURLOPT_HEADERFUNCTION, $readHeaderCallback);
132 curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
133 if (array_key_exists('ipv4', $this->options)
134 && $this->options['ipv4']
135 && defined('CURLOPT_IPRESOLVE')
136 && defined('CURL_IPRESOLVE_V4')){
137 curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
138 }
139 if ($headers !== null) {
140 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
141 }
142
143 // Execute cURL request
144 $start = microtime(true);
145 $rawResponse = curl_exec($ch);
146 if (self::$logging) {
147 error_log('--> ' . $request->getMethod() . ' ' . $url . ' ' . $body . (empty($headers) ? '' : ' ' . json_encode($headers)) . ' (' . intval(1000 * (microtime(true) - $start)) . 'ms)');
148 }
149
150 // Parse response
151 $response = new Response();
152 $response->setRequest($request);
153 $response->setRawBody($rawResponse);
154
155 if (curl_errno($ch)) {
156
157 $response->setStatusCode(0);
158 $response->setHeaders(array(
159 self::HEADER_CURL_ERRNO => curl_errno($ch),
160 self::HEADER_CURL_ERROR => curl_error($ch),
161 ));
162
163 } else {
164
165 $response->setStatusCode(curl_getinfo($ch, CURLINFO_HTTP_CODE));
166 $response->setHeaders($responseHeaders);
167
168 }
169
170 if (self::$logging && self::$loggingResponses) {
171 error_log('<-- (' . $response->getStatusCode() . ') ' . ($response->getRawBody() ?: '<no body>') . (empty($response->getHeaders()) ? '' : ' ' . json_encode($response->getHeaders())));
172 }
173
174 // Cleanup
175 curl_close($ch);
176
177 return $response;
178 }
179
180 }
181