From b080b181ac3c4f3c3e31dff028af5b03b409fd08 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Sat, 3 Oct 2015 20:01:58 +0200 Subject: [PATCH] Make sure we do not depend on any http transport library --- composer.json | 6 +- src/Mailgun/Connection/RestClient.php | 115 ++++++++++-------- .../Tests/Mock/Connection/TestBroker.php | 4 +- 3 files changed, 73 insertions(+), 52 deletions(-) diff --git a/composer.json b/composer.json index d0d55fc..091add5 100644 --- a/composer.json +++ b/composer.json @@ -2,11 +2,13 @@ "name": "mailgun/mailgun-php", "description": "The Mailgun SDK provides methods for all API functions.", "require": { - "guzzlehttp/guzzle": "~6.0" + "guzzlehttp/psr7": "~1.2", + "happyr/http-auto-discovery": "0.1.*" }, "require-dev": { "php": ">=5.4.0", - "phpunit/phpunit": "~4.6" + "phpunit/phpunit": "~4.6", + "php-http/guzzle6-adapter": "^0.1.0" }, "autoload": { "psr-0": { diff --git a/src/Mailgun/Connection/RestClient.php b/src/Mailgun/Connection/RestClient.php index 9ea695d..75523bf 100644 --- a/src/Mailgun/Connection/RestClient.php +++ b/src/Mailgun/Connection/RestClient.php @@ -2,15 +2,15 @@ namespace Mailgun\Connection; -use GuzzleHttp\Client as Guzzle; +use GuzzleHttp\Psr7\MultipartStream; use GuzzleHttp\Psr7\Request; -use GuzzleHttp\Psr7\Response; use Mailgun\Connection\Exceptions\GenericHTTPError; use Mailgun\Connection\Exceptions\InvalidCredentials; use Mailgun\Connection\Exceptions\MissingRequiredParameters; use Mailgun\Connection\Exceptions\MissingEndpoint; use Mailgun\Constants\Api; use Mailgun\Constants\ExceptionMessages; +use Happyr\HttpAutoDiscovery\Client as HttpClient; use Psr\Http\Message\ResponseInterface; /** @@ -24,28 +24,48 @@ class RestClient private $apiKey; /** - * @var Guzzle + * @var HttpClient */ - protected $mgClient; + protected $httpClient; + + /** + * @var string + */ + protected $apiEndpoint; /** * @param string $apiKey - * @param string $apiEndpoint + * @param string $apiHost * @param string $apiVersion * @param bool $ssl */ - public function __construct($apiKey, $apiEndpoint, $apiVersion, $ssl) + public function __construct($apiKey, $apiHost, $apiVersion, $ssl) { $this->apiKey = $apiKey; - $this->mgClient = new Guzzle([ - 'base_uri'=>$this->generateEndpoint($apiEndpoint, $apiVersion, $ssl), - 'auth' => array(Api::API_USER, $this->apiKey), - 'exceptions' => false, - 'config' => ['curl' => [ CURLOPT_FORBID_REUSE => true ]], - 'headers' => [ - 'User-Agent' => Api::SDK_USER_AGENT.'/'.Api::SDK_VERSION, - ], - ]); + $this->apiEndpoint = $this->generateEndpoint($apiHost, $apiVersion, $ssl); + } + + /** + * Get a HttpClient. + * + * @return HttpClient + */ + protected function send($method, $uri, array $headers = [], $body = [], $files = []) + { + if ($this->httpClient === null) { + $this->httpClient = new HttpClient(); + } + + $headers['User-Agent'] = Api::SDK_USER_AGENT.'/'.Api::SDK_VERSION; + $headers['Authorization'] = 'Basic '. base64_encode(sprintf("%s:%s",Api::API_USER, $this->apiKey)); + + if (!empty($files)) { + $body = new MultipartStream($files); + $headers['Content-Type'] = 'multipart/form-data; boundary='.$body->getBoundary(); + } + $request = new Request($method, $this->apiEndpoint.$uri, $headers, $body); + + return $this->httpClient->sendRequest($request); } /** @@ -62,7 +82,6 @@ class RestClient */ public function post($endpointUrl, $postData = array(), $files = array()) { - $request = new Request('post', $endpointUrl); $postFiles = []; $fields = ['message', 'attachment', 'inline']; @@ -70,39 +89,37 @@ class RestClient if (isset($files[$fieldName])) { if (is_array($files[$fieldName])) { foreach ($files[$fieldName] as $file) { - $postFiles[] = $this->addFile($fieldName, $file); + $postFiles[] = $this->prepareFile($fieldName, $file); } } else { - $postFiles[] = $this->addFile($fieldName, $files[$fieldName]); + $postFiles[] = $this->prepareFile($fieldName, $files[$fieldName]); } } } $postDataMultipart = []; - foreach($postData AS $key => $value) - { - if (is_array($value)) - { - foreach($value AS $subValue) - { + foreach ($postData as $key => $value) { + if (is_array($value)) { + foreach ($value as $subValue) { $postDataMultipart[] = [ 'name' => $key, - 'contents' => $subValue + 'contents' => $subValue, ]; } - } - else - { + } else { $postDataMultipart[] = [ 'name' => $key, - 'contents' => $value + 'contents' => $value, ]; } } - $response = $this->mgClient->send($request, [ - 'multipart' => array_merge($postDataMultipart, $postFiles) - ]); + $response = $this->send('POST', $endpointUrl, + [], + [], + array_merge($postDataMultipart, $postFiles) + ); + return $this->responseHandler($response); } @@ -119,7 +136,8 @@ class RestClient */ public function get($endpointUrl, $queryString = array()) { - $response = $this->mgClient->get($endpointUrl, ['query' => $queryString]); + $response = $this->send('GET', $endpointUrl.'?'.http_build_query($queryString)); + return $this->responseHandler($response); } @@ -135,7 +153,8 @@ class RestClient */ public function delete($endpointUrl) { - $response = $this->mgClient->delete($endpointUrl); + $response = $this->send('DELETE', $endpointUrl); + return $this->responseHandler($response); } @@ -152,12 +171,13 @@ class RestClient */ public function put($endpointUrl, $putData) { - $response = $this->mgClient->request('PUT', $endpointUrl, ['body' => $putData]); + $response = $this->send('PUT', $endpointUrl, [], $putData); + return $this->responseHandler($response); } /** - * @param Response $responseObj + * @param ResponseInterface $responseObj * * @return \stdClass * @@ -166,7 +186,7 @@ class RestClient * @throws MissingEndpoint * @throws MissingRequiredParameters */ - public function responseHandler($responseObj) + public function responseHandler(ResponseInterface $responseObj) { $httpResponseCode = $responseObj->getStatusCode(); if ($httpResponseCode === 200) { @@ -190,16 +210,16 @@ class RestClient } /** - * @param Response $responseObj + * @param ResponseInterface $responseObj * * @return string */ - protected function getResponseExceptionMessage(Response $responseObj) + protected function getResponseExceptionMessage(ResponseInterface $responseObj) { $body = (string) $responseObj->getBody(); $response = json_decode($body); if (json_last_error() == JSON_ERROR_NONE && isset($response->message)) { - return " ".$response->message; + return ' '.$response->message; } } @@ -213,20 +233,19 @@ class RestClient protected function generateEndpoint($apiEndpoint, $apiVersion, $ssl) { if (!$ssl) { - return "http://".$apiEndpoint."/".$apiVersion."/"; + return 'http://'.$apiEndpoint.'/'.$apiVersion.'/'; } else { - return "https://".$apiEndpoint."/".$apiVersion."/"; + return 'https://'.$apiEndpoint.'/'.$apiVersion.'/'; } } /** - * Add a file to the postBody. + * Prepare a file for the postBody. * - * @param \GuzzleHttp\Psr7\Stream $postBody - * @param string $fieldName - * @param string|array $filePath + * @param string $fieldName + * @param string|array $filePath */ - protected function addFile($fieldName, $filePath) + protected function prepareFile($fieldName, $filePath) { $filename = null; // Backward compatibility code @@ -243,7 +262,7 @@ class RestClient return [ 'name' => $fieldName, 'contents' => fopen($filePath, 'r'), - 'filename' => $filename + 'filename' => $filename, ]; } } diff --git a/tests/Mailgun/Tests/Mock/Connection/TestBroker.php b/tests/Mailgun/Tests/Mock/Connection/TestBroker.php index a9ee3b0..6652aa5 100644 --- a/tests/Mailgun/Tests/Mock/Connection/TestBroker.php +++ b/tests/Mailgun/Tests/Mock/Connection/TestBroker.php @@ -13,10 +13,10 @@ class TestBroker extends RestClient protected $apiEndpoint; - public function __construct($apiKey = null, $apiEndpoint = "api.mailgun.net", $apiVersion = "v3") + public function __construct($apiKey = null, $apiHost = "api.mailgun.net", $apiVersion = "v3") { $this->apiKey = $apiKey; - $this->apiEndpoint = $apiEndpoint; + $this->apiEndpoint = $apiHost; } public function post($endpointUrl, $postData = array(), $files = array())