Skip to content

Commit cf80048

Browse files
Merge pull request influxdata#112 from aldas/unix_domain_socket_client
add Curl driver and in it support Unix Domain Socket connection
2 parents 7a1ab9e + 0a3cf29 commit cf80048

File tree

3 files changed

+444
-1
lines changed

3 files changed

+444
-1
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
}
4444
},
4545
"suggest": {
46-
"stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP."
46+
"stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP.",
47+
"ext-curl": "Curl extension, needed for Curl driver"
4748
},
4849
"scripts": {
4950
"test": "vendor/bin/phpunit",

src/InfluxDB/Driver/Curl.php

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
<?php
2+
3+
namespace InfluxDB\Driver;
4+
5+
6+
use InfluxDB\ResultSet;
7+
8+
class Curl implements DriverInterface, QueryDriverInterface
9+
{
10+
/**
11+
* request parameters
12+
*
13+
* @var array
14+
*/
15+
private $parameters;
16+
17+
/**
18+
* @var string
19+
*/
20+
private $dsn;
21+
22+
/**
23+
* Array of curl options
24+
*
25+
* @var array
26+
*/
27+
private $options;
28+
29+
/** @var array */
30+
protected $lastRequestInfo;
31+
32+
/**
33+
* Build the Curl driver from a dsn
34+
* Examples:
35+
*
36+
* http://localhost:8086
37+
* https://localhost:8086
38+
* unix:///var/run/influxdb/influxdb.sock
39+
*
40+
* @param string $dsn
41+
* @param array $options options for curl requests. See http://php.net/manual/en/function.curl-setopt.php for available options
42+
* @throws Exception
43+
*/
44+
public function __construct($dsn, $options = [])
45+
{
46+
if (!extension_loaded('curl')) {
47+
throw new Exception('Curl extension is not enabled!');
48+
}
49+
50+
$this->dsn = $dsn;
51+
if (strpos($dsn, 'unix://') === 0) {
52+
if (PHP_VERSION_ID < 70007) {
53+
throw new Exception('Unix domain sockets are supported since PHP version PHP 7.0.7. Current version: ' . PHP_VERSION);
54+
}
55+
$curlVersion = curl_version()['version'];
56+
if (version_compare($curlVersion, '7.40.0', '<')) {
57+
throw new Exception('Unix domain sockets are supported since curl version 7.40.0! Current curl version: ' . $curlVersion);
58+
}
59+
$options[CURLOPT_UNIX_SOCKET_PATH] = substr($dsn, 7);
60+
61+
$this->dsn = 'http://localhost';
62+
}
63+
64+
$this->options = $options;
65+
}
66+
67+
/**
68+
* Called by the client write() method, will pass an array of required parameters such as db name
69+
*
70+
* will contain the following parameters:
71+
*
72+
* [
73+
* 'database' => 'name of the database',
74+
* 'url' => 'URL to the resource',
75+
* 'method' => 'HTTP method used'
76+
* ]
77+
*
78+
* @param array $parameters
79+
*
80+
* @return mixed
81+
*/
82+
public function setParameters(array $parameters)
83+
{
84+
$this->parameters = $parameters;
85+
}
86+
87+
/**
88+
* @return array
89+
*/
90+
public function getParameters()
91+
{
92+
return $this->parameters;
93+
}
94+
95+
/**
96+
* Send the data
97+
*
98+
* @param $data
99+
* @throws Exception
100+
*
101+
* @return mixed
102+
*/
103+
public function write($data = null)
104+
{
105+
$options = $this->getCurlOptions();
106+
$options[CURLOPT_POST] = 1;
107+
$options[CURLOPT_POSTFIELDS] = $data;
108+
109+
110+
$this->execute($this->parameters['url'], $options);
111+
}
112+
113+
/**
114+
* Should return if sending the data was successful
115+
*
116+
* @return bool
117+
* @throws Exception
118+
*/
119+
public function isSuccess()
120+
{
121+
if (empty($this->lastRequestInfo)) {
122+
return false;
123+
}
124+
$statusCode = $this->lastRequestInfo['http_code'];
125+
126+
if (!in_array($statusCode, [200, 204], true)) {
127+
throw new Exception('Request failed with HTTP Code ' . $statusCode);
128+
}
129+
130+
return true;
131+
}
132+
133+
/**
134+
* @return ResultSet
135+
* @throws \InfluxDB\Client\Exception
136+
*/
137+
public function query()
138+
{
139+
$response = $this->execute($this->parameters['url'], $this->getCurlOptions());
140+
return new ResultSet($response);
141+
}
142+
143+
protected function execute($url, $curlOptions = [])
144+
{
145+
$this->lastRequestInfo = null;
146+
$ch = curl_init();
147+
148+
foreach ($curlOptions as $option => $value) {
149+
curl_setopt($ch, $option, $value);
150+
}
151+
152+
curl_setopt($ch, CURLOPT_URL, $this->dsn . '/' . $url);
153+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
154+
155+
$result = curl_exec($ch);
156+
$this->lastRequestInfo = curl_getinfo($ch);
157+
158+
if ($result === false) {
159+
// in case of total failure - socket/port is closed etc
160+
throw new Exception('Request failed! curl_errno: ' . curl_errno($ch));
161+
}
162+
163+
164+
curl_close($ch);
165+
166+
return $result;
167+
}
168+
169+
/**
170+
* Returns curl options
171+
*
172+
* @return array
173+
*/
174+
public function getCurlOptions()
175+
{
176+
$opts = $this->options + [
177+
CURLOPT_CONNECTTIMEOUT => 5, // 5 seconds
178+
CURLOPT_TIMEOUT => 10, // 30 seconds
179+
];
180+
181+
if (isset($this->parameters['auth'])) {
182+
list($username, $password) = $this->parameters['auth'];
183+
$opts[CURLOPT_USERPWD] = $username . ':' . $password;
184+
}
185+
186+
return $opts;
187+
}
188+
189+
/**
190+
* Last curl request info
191+
*
192+
* @return array
193+
*/
194+
public function getLastRequestInfo()
195+
{
196+
return $this->lastRequestInfo;
197+
}
198+
199+
/**
200+
* @return string
201+
*/
202+
public function getDsn()
203+
{
204+
return $this->dsn;
205+
}
206+
}

0 commit comments

Comments
 (0)