diff --git a/src/conduit/ConduitClient.php b/src/conduit/ConduitClient.php --- a/src/conduit/ConduitClient.php +++ b/src/conduit/ConduitClient.php @@ -13,6 +13,7 @@ private $privateKey; private $conduitToken; private $oauthToken; + private $capabilities = array(); const AUTH_ASYMMETRIC = 'asymmetric'; @@ -86,6 +87,11 @@ return $this; } + public function enableCapabilities(array $capabilities) { + $this->capabilities += array_fuse($capabilities); + return $this; + } + public function callMethod($method, array $params) { $meta = array(); @@ -143,12 +149,28 @@ // Always use the cURL-based HTTPSFuture, for proxy support and other // protocol edge cases that HTTPFuture does not support. - $core_future = new HTTPSFuture($uri, $data); + $core_future = new HTTPSFuture($uri); $core_future->addHeader('Host', $this->getHostStringForHeader()); $core_future->setMethod('POST'); $core_future->setTimeout($this->timeout); + // See T13507. If possible, try to compress requests. To compress requests, + // we must have "gzencode()" available and the server needs to have + // asserted it has the "gzip" capability. + $can_gzip = + (function_exists('gzencode')) && + (isset($this->capabilities['gzip'])); + if ($can_gzip) { + $gzip_data = phutil_build_http_querystring($data); + $gzip_data = gzencode($gzip_data); + + $core_future->addHeader('Content-Encoding', 'gzip'); + $core_future->setData($gzip_data); + } else { + $core_future->setData($data); + } + if ($this->username !== null) { $core_future->setHTTPBasicAuthCredentials( $this->username, diff --git a/src/conduit/ConduitFuture.php b/src/conduit/ConduitFuture.php --- a/src/conduit/ConduitFuture.php +++ b/src/conduit/ConduitFuture.php @@ -3,6 +3,7 @@ final class ConduitFuture extends FutureProxy { private $client; + private $engine; private $conduitMethod; private $profilerCallID; @@ -40,6 +41,19 @@ throw $status; } + $capabilities = array(); + foreach ($headers as $header) { + list($name, $value) = $header; + if (!strcasecmp($name, 'X-Conduit-Capabilities')) { + $capabilities = explode(' ', $value); + break; + } + } + + if ($capabilities) { + $this->client->enableCapabilities($capabilities); + } + $raw = $body; $shield = 'for(;;);';