Skip to content

Commit

Permalink
Add support for pecl_http 2.0
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Schneider <jan@horde.org>
  • Loading branch information
BigMichi1 authored and yunosh committed Mar 25, 2014
1 parent 5c2832b commit 8c039ed
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 51 deletions.
2 changes: 2 additions & 0 deletions framework/Http/lib/Horde/Http/Request/Factory.php
Expand Up @@ -25,6 +25,8 @@ public function create()
{
if (class_exists('HttpRequest', false)) {
return new Horde_Http_Request_Peclhttp();
} elseif (class_exists('\http\Client', false)) {
return new Horde_Http_Request_Peclhttp2();
} elseif (extension_loaded('curl')) {
return new Horde_Http_Request_Curl();
} elseif (ini_get('allow_url_fopen')) {
Expand Down
51 changes: 2 additions & 49 deletions framework/Http/lib/Horde/Http/Request/Peclhttp.php
Expand Up @@ -14,7 +14,7 @@
* @category Horde
* @package Http
*/
class Horde_Http_Request_Peclhttp extends Horde_Http_Request_Base
class Horde_Http_Request_Peclhttp extends Horde_Http_Request_PeclhttpBase
{
/**
* Map of HTTP authentication schemes from Horde_Http constants to HTTP_AUTH constants.
Expand Down Expand Up @@ -67,39 +67,7 @@ public function send()
}
}

// Set options
$httpOptions = array('headers' => $this->headers,
'redirect' => (int)$this->redirects,
'ssl' => array('verifypeer' => $this->verifyPeer),
'timeout' => $this->timeout,
'useragent' => $this->userAgent);

// Proxy settings
if ($this->proxyServer) {
$httpOptions['proxyhost'] = $this->proxyServer;
if ($this->proxyPort) {
$httpOptions['proxyport'] = $this->proxyPort;
}
if ($this->proxyUsername && $this->proxyPassword) {
$httpOptions['proxyauth'] = $this->proxyUsername . ':' . $this->proxyPassword;
$httpOptions['proxyauthtype'] = $this->_httpAuthScheme($this->proxyAuthenticationScheme);
}
if ($this->proxyType == Horde_Http::PROXY_SOCKS4) {
$httpOptions['proxytype'] = HTTP_PROXY_SOCKS4;
} else if ($this->proxyType == Horde_Http::PROXY_SOCKS5) {
$httpOptions['proxytype'] = HTTP_PROXY_SOCKS5;
} else if ($this->proxyType != Horde_Http::PROXY_HTTP) {
throw new Horde_Http_Exception(sprintf('Proxy type %s not supported by this request type!', $this->proxyType));
}
}

// Authentication settings
if ($this->username) {
$httpOptions['httpauth'] = $this->username . ':' . $this->password;
$httpOptions['httpauthtype'] = $this->_httpAuthScheme($this->authenticationScheme);
}

$httpRequest->setOptions($httpOptions);
$httpRequest->setOptions($this->_httpOptions());

try {
$httpResponse = $httpRequest->send();
Expand All @@ -113,19 +81,4 @@ public function send()

return new Horde_Http_Response_Peclhttp($this->uri, $httpResponse);
}

/**
* Translate a Horde_Http::AUTH_* constant to HTTP_AUTH_*
*
* @param const
* @throws Horde_Http_Exception
* @return const
*/
protected function _httpAuthScheme($httpAuthScheme)
{
if (!isset($this->_httpAuthSchemes[$httpAuthScheme])) {
throw new Horde_Http_Exception('Unsupported authentication scheme (' . $httpAuthScheme . ')');
}
return $this->_httpAuthSchemes[$httpAuthScheme];
}
}
88 changes: 88 additions & 0 deletions framework/Http/lib/Horde/Http/Request/Peclhttp2.php
@@ -0,0 +1,88 @@
<?php
/**
* Copyright 2007-2014 Horde LLC (http://www.horde.org/)
*
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.horde.org/licenses/bsd BSD
* @category Horde
* @package Http
*/

/**
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.horde.org/licenses/bsd BSD
* @category Horde
* @package Http
*/
class Horde_Http_Request_Peclhttp2 extends Horde_Http_Request_PeclhttpBase
{
/**
* Map of HTTP authentication schemes from Horde_Http constants to HTTP_AUTH constants.
* @var array
*/
protected $_httpAuthSchemes = array(
Horde_Http::AUTH_ANY => \http\Client\Curl\AUTH_ANY,
Horde_Http::AUTH_BASIC => \http\Client\Curl\AUTH_BASIC,
Horde_Http::AUTH_DIGEST => \http\Client\Curl\AUTH_DIGEST,
Horde_Http::AUTH_GSSNEGOTIATE => \http\Client\Curl\AUTH_GSSNEG,
Horde_Http::AUTH_NTLM => \http\Client\Curl\AUTH_NTLM,
);

/**
* Map of proxy types from Horde_Http to implementation specific constants.
* @var array
*/
protected $_proxyTypes = array(
Horde_Http::PROXY_SOCKS4 => \http\Client\Curl\PROXY_SOCKS4,
Horde_Http::PROXY_SOCKS5 => \http\Client\Curl\PROXY_SOCKS5
);

/**
* Constructor
*
* @throws Horde_Http_Exception
*/
public function __construct($args = array())
{
if (!class_exists('\http\Client', false)) {
throw new Horde_Http_Exception('The pecl_http extension is not installed. See http://php.net/http.install');
}

parent::__construct($args);
}

/**
* Send this HTTP request
*
* @throws Horde_Http_Exception
* @return Horde_Http_Response_Base
*/
public function send()
{
// at this time only the curl driver is supported
$client = new \http\Client('curl');

$body = new \http\Message\Body();
$data = $this->data;
if (is_array($data)) {
$body->addForm($data);
} else {
$body->append($data);
}

$httpRequest = new \http\Client\Request($this->method, $this->uri, $this->headers, $body);

$client->setOptions($this->_httpOptions());

$client->enqueue($httpRequest);

try {
$client->send();
$httpResponse = $client->getResponse($httpRequest);
} catch (\http\Exception $e) {
throw new Horde_Http_Exception($e);
}

return new Horde_Http_Response_Peclhttp2($this->uri, $httpResponse);
}
}
110 changes: 110 additions & 0 deletions framework/Http/lib/Horde/Http/Request/PeclhttpBase.php
@@ -0,0 +1,110 @@
<?php
/**
* Copyright 2007-2014 Horde LLC (http://www.horde.org/)
*
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.horde.org/licenses/bsd BSD
* @category Horde
* @package Http
*/

/**
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.horde.org/licenses/bsd BSD
* @category Horde
* @package Http
*/
abstract class Horde_Http_Request_PeclhttpBase extends Horde_Http_Request_Base {
/**
* Map of HTTP authentication schemes from Horde_Http constants to implementation specific constants
* @var array
*/
protected $_httpAuthSchemes = array();

/**
* Map of proxy types from Horde_Http to implementation specific constants.
* @var array
*/
protected $_proxyTypes = array();

/**
* Constructor
*
* @throws Horde_Http_Exception
*/
public function __construct($args = array())
{
parent::__construct($args);
}

/**
* Translate a Horde_Http::AUTH_* constant to implementation specific constants.
*
* @return const
* @throws Horde_Http_Exception
*/
private function _httpAuthScheme()
{
$httpAuthScheme = $this->proxyAuthenticationScheme;
if (!isset($this->_httpAuthSchemes[$httpAuthScheme])) {
throw new Horde_Http_Exception('Unsupported authentication scheme (' . $httpAuthScheme . ')');
}
return $this->_httpAuthSchemes[$httpAuthScheme];
}

/**
* Translate a Horde_Http::PROXY_* constant to implementation specific constants.
*
* @return const
* @throws Horde_Http_Exception
*/
private function _proxyType()
{
$proxyType = $this->proxyType;
if (!isset($this->_proxyTypes[$proxyType])) {
throw new Horde_Http_Exception('Unsupported proxy type (' . $httpAuthScheme . ')');
}
return $this->_proxyTypes[$proxyType];
}

/**
* Generate the http options for the request.
*
* @return array array with options
* @throws Horde_Http_Exception
*/
protected function _httpOptions()
{
// Set options
$httpOptions = array('headers' => $this->headers,
'redirect' => (int)$this->redirects,
'ssl' => array('verifypeer' => $this->verifyPeer),
'timeout' => $this->timeout,
'useragent' => $this->userAgent);

// Proxy settings
if ($this->proxyServer) {
$httpOptions['proxyhost'] = $this->proxyServer;
if ($this->proxyPort) {
$httpOptions['proxyport'] = $this->proxyPort;
}
if ($this->proxyUsername && $this->proxyPassword) {
$httpOptions['proxyauth'] = $this->proxyUsername . ':' . $this->proxyPassword;
$httpOptions['proxyauthtype'] = $this->_httpAuthScheme();
}
if ($this->proxyType == Horde_Http::PROXY_SOCKS4 || $this->proxyType == Horde_Http::PROXY_SOCKS5) {
$httpOptions['proxytype'] = $this->_proxyType();
} else if ($this->proxyType != Horde_Http::PROXY_HTTP) {
throw new Horde_Http_Exception(sprintf('Proxy type %s not supported by this request type!', $this->proxyType));
}
}

// Authentication settings
if ($this->username) {
$httpOptions['httpauth'] = $this->username . ':' . $this->password;
$httpOptions['httpauthtype'] = $this->_httpAuthScheme($this->authenticationScheme);
}

return $httpOptions;
}
}
54 changes: 54 additions & 0 deletions framework/Http/lib/Horde/Http/Response/Peclhttp2.php
@@ -0,0 +1,54 @@
<?php
/**
* Copyright 2007-2014 Horde LLC (http://www.horde.org/)
*
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.horde.org/licenses/bsd BSD
* @category Horde
* @package Http
*/

/**
* @author Michael Cramer <michael@bigmichi1.de>
* @license http://www.horde.org/licenses/bsd BSD
* @category Horde
* @package Http
*/
class Horde_Http_Response_Peclhttp2 extends Horde_Http_Response_Base
{
/**
* HttpMessage object.
*
* @var \http\Client\Response
*/
protected $_response;

/**
* Constructor.
*
* @param string $uri
* @param \http\Client\Response $response
*/
public function __construct($uri, \http\Client\Response $response)
{
try {
$parent = $response->getParentMessage();
$location = $parent->getHeader('Location');
$this->uri = $location;
} catch (HttpRuntimeException $e) {
$this->uri = $uri;
}

$this->httpVersion = $response->getHttpVersion();
$this->code = $response->getResponseCode();
$this->_response = $response;
foreach ($response->getHeaders() as $k => $v) {
$this->headers[strtolower($k)] = $v;
}
}

public function getBody()
{
return $this->_response->getBody();
}
}
10 changes: 8 additions & 2 deletions framework/Http/package.xml
Expand Up @@ -53,14 +53,17 @@
<file name="Factory.php" role="php" />
<file name="Fopen.php" role="php" />
<file name="Mock.php" role="php" />
<file name="PeclhttpBase.php" role="php" />
<file name="Peclhttp.php" role="php" />
<file name="Peclhttp2.php" role="php" />
</dir> <!-- /lib/Horde/Http/Request -->
<dir name="Response">
<file name="Base.php" role="php" />
<file name="Curl.php" role="php" />
<file name="Fopen.php" role="php" />
<file name="Mock.php" role="php" />
<file name="Peclhttp.php" role="php" />
<file name="Peclhttp2.php" role="php" />
</dir> <!-- /lib/Horde/Http/Response -->
<file name="Client.php" role="php" />
<file name="Exception.php" role="php" />
Expand Down Expand Up @@ -119,8 +122,8 @@
<name>pecl_http</name>
<channel>pecl.php.net</channel>
<min>1.7.0</min>
<max>2.0.0alpha1</max>
<exclude>2.0.0alpha1</exclude>
<max>3.0.0alpha1</max>
<exclude>3.0.0alpha1</exclude>
<providesextension>http</providesextension>
</package>
<extension>
Expand All @@ -140,12 +143,15 @@
<install as="Horde/Http/Request/Factory.php" name="lib/Horde/Http/Request/Factory.php" />
<install as="Horde/Http/Request/Fopen.php" name="lib/Horde/Http/Request/Fopen.php" />
<install as="Horde/Http/Request/Mock.php" name="lib/Horde/Http/Request/Mock.php" />
<install as="Horde/Http/Request/PeclhttpBase.php" name="lib/Horde/Http/Request/PeclhttpBase.php" />
<install as="Horde/Http/Request/Peclhttp.php" name="lib/Horde/Http/Request/Peclhttp.php" />
<install as="Horde/Http/Request/Peclhttp2.php" name="lib/Horde/Http/Request/Peclhttp2.php" />
<install as="Horde/Http/Response/Base.php" name="lib/Horde/Http/Response/Base.php" />
<install as="Horde/Http/Response/Curl.php" name="lib/Horde/Http/Response/Curl.php" />
<install as="Horde/Http/Response/Fopen.php" name="lib/Horde/Http/Response/Fopen.php" />
<install as="Horde/Http/Response/Mock.php" name="lib/Horde/Http/Response/Mock.php" />
<install as="Horde/Http/Response/Peclhttp.php" name="lib/Horde/Http/Response/Peclhttp.php" />
<install as="Horde/Http/Response/Peclhttp2.php" name="lib/Horde/Http/Response/Peclhttp2.php" />
<install as="Horde/Http/AllTests.php" name="test/Horde/Http/AllTests.php" />
<install as="Horde/Http/bootstrap.php" name="test/Horde/Http/bootstrap.php" />
<install as="Horde/Http/ClientTest.php" name="test/Horde/Http/ClientTest.php" />
Expand Down

0 comments on commit 8c039ed

Please sign in to comment.