You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by ro...@apache.org on 2014/07/26 00:26:29 UTC

git commit: THRIFT-2394 TCurlClient: an HTTP transport implementation using libcurl

Repository: thrift
Updated Branches:
  refs/heads/master fcd062d6c -> 6aacd4cc7


THRIFT-2394 TCurlClient: an HTTP transport implementation using libcurl

Client: PHP
Patch: Oran Kelly


Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/6aacd4cc
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/6aacd4cc
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/6aacd4cc

Branch: refs/heads/master
Commit: 6aacd4cc719e5a392236b9b351397d03f80ae0d6
Parents: fcd062d
Author: Roger Meier <ro...@apache.org>
Authored: Sat Jul 26 00:19:02 2014 +0200
Committer: Roger Meier <ro...@apache.org>
Committed: Sat Jul 26 00:19:02 2014 +0200

----------------------------------------------------------------------
 lib/php/Makefile.am                          |   1 +
 lib/php/lib/Thrift/Transport/TCurlClient.php | 222 ++++++++++++++++++++++
 2 files changed, 223 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/thrift/blob/6aacd4cc/lib/php/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/php/Makefile.am b/lib/php/Makefile.am
index d1a560a..e9d673c 100755
--- a/lib/php/Makefile.am
+++ b/lib/php/Makefile.am
@@ -95,6 +95,7 @@ phpstringfunc_DATA = \
 phptransportdir = $(phpdir)/Transport
 phptransport_DATA = \
   lib/Thrift/Transport/TBufferedTransport.php \
+  lib/Thrift/Transport/TCurlClient.php \
   lib/Thrift/Transport/TFramedTransport.php \
   lib/Thrift/Transport/THttpClient.php \
   lib/Thrift/Transport/TMemoryBuffer.php \

http://git-wip-us.apache.org/repos/asf/thrift/blob/6aacd4cc/lib/php/lib/Thrift/Transport/TCurlClient.php
----------------------------------------------------------------------
diff --git a/lib/php/lib/Thrift/Transport/TCurlClient.php b/lib/php/lib/Thrift/Transport/TCurlClient.php
new file mode 100644
index 0000000..9eeefe1
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TCurlClient.php
@@ -0,0 +1,222 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TTransport;
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * HTTP client for Thrift
+ *
+ * @package thrift.transport
+ */
+class TCurlClient extends TTransport {
+
+  private static $curlHandle;
+
+  /**
+   * The host to connect to
+   *
+   * @var string
+   */
+  protected $host_;
+
+  /**
+   * The port to connect on
+   *
+   * @var int
+   */
+  protected $port_;
+
+  /**
+   * The URI to request
+   *
+   * @var string
+   */
+  protected $uri_;
+
+  /**
+   * The scheme to use for the request, i.e. http, https
+   *
+   * @var string
+   */
+  protected $scheme_;
+
+  /**
+   * Buffer for the HTTP request data
+   *
+   * @var string
+   */
+  protected $request_;
+
+  /**
+   * Buffer for the HTTP response data.
+   *
+   * @var binary string
+   */
+  protected $response_;
+
+  /**
+   * Read timeout
+   *
+   * @var float
+   */
+  protected $timeout_;
+
+  /**
+   * Make a new HTTP client.
+   *
+   * @param string $host
+   * @param int    $port
+   * @param string $uri
+   */
+  public function __construct($host, $port=80, $uri='', $scheme = 'http') {
+    if ((TStringFuncFactory::create()->strlen($uri) > 0) && ($uri{0} != '/')) {
+      $uri = '/'.$uri;
+    }
+    $this->scheme_ = $scheme;
+    $this->host_ = $host;
+    $this->port_ = $port;
+    $this->uri_ = $uri;
+    $this->request_ = '';
+    $this->response_ = null;
+    $this->timeout_ = null;
+  }
+
+  /**
+   * Set read timeout
+   *
+   * @param float $timeout
+   */
+  public function setTimeoutSecs($timeout) {
+    $this->timeout_ = $timeout;
+  }
+
+  /**
+   * Whether this transport is open.
+   *
+   * @return boolean true if open
+   */
+  public function isOpen() {
+    return true;
+  }
+
+  /**
+   * Open the transport for reading/writing
+   *
+   * @throws TTransportException if cannot open
+   */
+  public function open() {
+  }
+
+  /**
+   * Close the transport.
+   */
+  public function close() {
+    $this->request_ = '';
+    $this->response_ = null;
+  }
+
+  /**
+   * Read some data into the array.
+   *
+   * @param int    $len How much to read
+   * @return string The data that has been read
+   * @throws TTransportException if cannot read any more data
+   */
+  public function read($len) {
+    if ($len >= strlen($this->response_)) {
+      return $this->response_;
+    } else {
+      $ret = substr($this->response_, 0, $len);
+      $this->response_ = substr($this->response_, $len);
+      return $ret;
+    }
+  }
+
+  /**
+   * Writes some data into the pending buffer
+   *
+   * @param string $buf  The data to write
+   * @throws TTransportException if writing fails
+   */
+  public function write($buf) {
+    $this->request_ .= $buf;
+  }
+
+  /**
+   * Opens and sends the actual request over the HTTP connection
+   *
+   * @throws TTransportException if a writing error occurs
+   */
+  public function flush() {
+    if (!self::$curlHandle) {
+      register_shutdown_function(array('Thrift\\Transport\\TCurlClient', 'closeCurlHandle'));
+      self::$curlHandle = curl_init();
+      curl_setopt(self::$curlHandle, CURLOPT_RETURNTRANSFER, true);
+      curl_setopt(self::$curlHandle, CURLOPT_BINARYTRANSFER, true);
+      curl_setopt(self::$curlHandle, CURLOPT_USERAGENT, 'PHP/TCurlClient');
+      curl_setopt(self::$curlHandle, CURLOPT_CUSTOMREQUEST, 'POST');
+      curl_setopt(self::$curlHandle, CURLOPT_FOLLOWLOCATION, true);
+      curl_setopt(self::$curlHandle, CURLOPT_MAXREDIRS, 1);
+    }
+    // God, PHP really has some esoteric ways of doing simple things.
+    $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
+    $fullUrl = $this->scheme_."://".$host.$this->uri_;
+
+    $headers = array('Accept: application/x-thrift',
+                     'Content-Type: application/x-thrift',
+                     'Content-Length: '.TStringFuncFactory::create()->strlen($this->request_));
+    curl_setopt(self::$curlHandle, CURLOPT_HTTPHEADER, $headers);
+
+    if ($this->timeout_ > 0) {
+      curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $this->timeout_);
+    }
+    curl_setopt(self::$curlHandle, CURLOPT_POSTFIELDS, $this->request_);
+    $this->request_ = '';
+
+    curl_setopt(self::$curlHandle, CURLOPT_URL, $fullUrl);
+    $this->response_ = curl_exec(self::$curlHandle);
+
+    // Connect failed?
+    if (!$this->response_) {
+      curl_close(self::$curlHandle);
+      self::$curlHandle = null;
+      $error = 'TCurlClient: Could not connect to '.$fullUrl;
+      throw new TTransportException($error, TTransportException::NOT_OPEN);
+    }
+  }
+
+  static function closeCurlHandle() {
+    try {
+      if (self::$curlHandle) {
+        curl_close(self::$curlHandle);
+        self::$curlHandle = null;
+      }
+    } catch (\Exception $x) {
+      error_log('There was an error closing the curl handle: ' . $x->getMessage());
+    }
+  }
+
+}