Skip to content
This repository has been archived by the owner on Mar 19, 2020. It is now read-only.

Commit

Permalink
Merge branch 'curl_cleanup' into 'master'
Browse files Browse the repository at this point in the history
Add php curl as default connection, cleanup

See merge request klatys/papi!1
  • Loading branch information
Jan Klat committed Jan 5, 2018
2 parents a64ec88 + 25a2ee9 commit 03c6db6
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 20 deletions.
32 changes: 18 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Supports Prometheus 1.x and 2.x `/api/v1` [endpoints](https://prometheus.io/docs
## Instalation
Use composer to add PApi as dependency:

$ composer install cdn77/papi
$ composer install cdn77/papi

## Usage

Expand All @@ -25,19 +25,23 @@ Use composer to add PApi as dependency:
'host' => 'my-prometheus.com',
]);

#### available options

| Name | Default value |
| ----------------- | ----------------------- |
| scheme | http |
| host | localhost |
| port | 9090 |
| path | /api/v1/ |
| timeout | 30 |
| username | `null` |
| password | `null` |
| connectionHeaders | `[]` |
| connectionType | GuzzleConnection::class |
#### Available options

| Name | Default value | Description |
| ----------------- | --------------------- | -------------------------------------- |
| scheme | http | Host scheme |
| host | localhost | Host address |
| port | 9090 | Host port |
| path | /api/v1/ | Path to base API endpoint |
| timeout | 30 | Timeout for requests |
| username | `null` | HTTP Auth username |
| password | `null` | HTTP Auth password |
| connectionHeaders | `[]` | Connection headers |
| connectionType | CurlConnection::class | Class to use for connection. See below |

#### Available connection classes
- `CurlConnection` - pure php curl implementation. Used by default.
- `GuzzleConnection` - using [guzzle](https://github.com/guzzle/guzzle) 6.3+ library.

### Available calls
PApi currently has methods for all available endpoints provided by Prometheus.
Expand Down
8 changes: 6 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
"type": "library",
"require": {
"php": ">=7.1",
"guzzlehttp/guzzle": "^6.3",
"skrz/meta": "^3.1"
"ext-curl": "*",
"skrz/meta": "^3.1",
"symfony/finder": "~2.7|~3.0|~4.0"
},
"require-dev": {
"cdn77/coding-standard": "^0.5",
Expand All @@ -16,6 +17,9 @@
"phpunit/phpunit": "^6.3",
"slevomat/coding-standard": "^4.0"
},
"suggest": {
"guzzlehttp/guzzle": "^6.3"
},
"autoload": {
"psr-4": {"PApi\\": ["src/"]}
},
Expand Down
3 changes: 2 additions & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace PApi;

use PApi\Connection\ConnectionInterface;
use PApi\Connection\CurlConnection;
use PApi\Connection\GuzzleConnection;
use PApi\Response\ArrayValuesResponse;
use PApi\Response\DataResponse;
Expand All @@ -28,7 +29,7 @@ class Client
'username' => null,
'password' => null,
'connectionHeaders' => [],
'connectionType' => GuzzleConnection::class,
'connectionType' => CurlConnection::class,
];

/**
Expand Down
3 changes: 0 additions & 3 deletions src/Connection/AbstractConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ abstract class AbstractConnection implements ConnectionInterface
public function __construct(array $config)
{
$this->config = $config;
$this->connect();
}

abstract protected function getBaseUri() : string;

abstract protected function connect() : void;
}
2 changes: 2 additions & 0 deletions src/Connection/ConnectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

interface ConnectionInterface
{
public function __construct(array $config);

/**
* @param mixed[] $config
*/
Expand Down
120 changes: 120 additions & 0 deletions src/Connection/CurlConnection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

declare (strict_types=1);

namespace PApi\Connection;

use PApi\Exception\ConnectionException;

class CurlConnection extends AbstractConnection
{
/** @var resource|null */
private $connection;

public function __destruct()
{
if ($this->connection !== null) {
curl_close($this->connection);
}
}

protected function connect() : void
{
$this->connection = curl_init();
}

/**
* @param mixed[] $config
*/
public function create(array $config) : ConnectionInterface
{
return new self($config);
}

/**
* @param mixed[] $query
*/
public function execute(string $endPoint, array $query = []) : string
{
if ($this->connection === null) {
$this->connect();
}
curl_reset($this->connection);

$queryParameters = http_build_query($query);
$queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $queryParameters);
$uriParts = $this->getBaseUriParts();
$uriParts['path'] .= $endPoint;
$uriParts['query'] = $queryString;
$url = $this->buildUrl($uriParts);

curl_setopt($this->connection, CURLOPT_URL, $url);
curl_setopt($this->connection, CURLOPT_TIMEOUT, $this->config['timeout']);
curl_setopt($this->connection, CURLOPT_RETURNTRANSFER, true);
$curlHeaders = array_map(function ($key, $value) {
return $key . ':' . $value;
}, $this->config['connectionHeaders']);
curl_setopt($this->connection, CURLOPT_HTTPHEADER, $curlHeaders);

$response = curl_exec($this->connection);
if ($response === false) {
throw new ConnectionException(
sprintf(
'Request GET %s returned with code %d and message `%s`',
$url,
curl_getinfo($this->connection, CURLINFO_RESPONSE_CODE),
curl_error($this->connection)
)
);
}

return $response;
}

/**
* @param string[] $parts
*/
private function buildUrl(array $parts) : string
{
$url = $parts['scheme'] . '://';

if (isset($parts['user'])) {
$url .= $parts['user'];
if (isset($parts['pass'])) {
$url .= ':' . $parts['pass'];
}
$url .= '@';
}

$url .= $parts['host'];

if (isset($parts['port'])) {
$url .= ':' . $parts['port'];
}

if (isset($parts['path'])) {
$url .= $parts['path'];
}

if (isset($parts['query'])) {
$url .= '?' . $parts['query'];
}

return $url;
}

/**
* @return string[]
*/
private function getBaseUriParts() : array
{
return [
'scheme' => $this->config['scheme'],
'host' => $this->config['host'],
'port' => $this->config['port'],
'path' => $this->config['path'],
'user' => $this->config['username'],
'pass' => $this->config['password'],
];
}
}
4 changes: 4 additions & 0 deletions src/Connection/GuzzleConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public function create(array $config) : ConnectionInterface
*/
public function execute(string $endPoint, array $query = []) : string
{
if ($this->client === null) {
$this->connect();
}

//for nested arrays, numeric keys are used (e.g. matches => [a,b] produces ?matches[0]=a&matches[1]=b) which is undesired
$queryParameters = http_build_query($query);
$queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $queryParameters);
Expand Down

0 comments on commit 03c6db6

Please sign in to comment.