THRIFT-948: SSL socket support for PHP
Client: php
Patch: Mansi Nahar
Adds TSSLServerSocket and TSSLSocket to PHP
diff --git a/lib/php/lib/Thrift/Server/TSSLServerSocket.php b/lib/php/lib/Thrift/Server/TSSLServerSocket.php
new file mode 100644
index 0000000..dfc4704
--- /dev/null
+++ b/lib/php/lib/Thrift/Server/TSSLServerSocket.php
@@ -0,0 +1,94 @@
+<?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.
+ *
+ */
+
+namespace Thrift\Server;
+
+use Thrift\Transport\TSSLSocket;
+
+/**
+ * Socket implementation of a server agent.
+ *
+ * @package thrift.transport
+ */
+class TSSLServerSocket extends TServerSocket
+{
+ /**
+ * Remote port
+ *
+ * @var resource
+ */
+ protected $context_ = null;
+
+ /**
+ * ServerSocket constructor
+ *
+ * @param string $host Host to listen on
+ * @param int $port Port to listen on
+ * @param resource $context Stream context
+ * @return void
+ */
+ public function __construct($host = 'localhost', $port = 9090, $context = null)
+ {
+ $ssl_host = $this->getSSLHost($host);
+ parent::__construct($ssl_host, $port);
+ $this->context_ = $context;
+ }
+
+ public function getSSLHost($host)
+ {
+ $transport_protocol_loc = strpos($host, "://");
+ if ($transport_protocol_loc === false) {
+ $host = 'ssl://'.$host;
+ }
+ return $host;
+ }
+
+ /**
+ * Opens a new socket server handle
+ *
+ * @return void
+ */
+ public function listen()
+ {
+ $this->listener_ = @stream_socket_server(
+ $this->host_ . ':' . $this->port_,
+ $errno,
+ $errstr,
+ STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
+ $this->context_);
+ }
+
+ /**
+ * Implementation of accept. If not client is accepted in the given time
+ *
+ * @return TSocket
+ */
+ protected function acceptImpl()
+ {
+ $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0);
+ if(!$handle) return null;
+
+ $socket = new TSSLSocket();
+ $socket->setHandle($handle);
+
+ return $socket;
+ }
+}
diff --git a/lib/php/lib/Thrift/Server/TServerSocket.php b/lib/php/lib/Thrift/Server/TServerSocket.php
index 4eff29c..da8e226 100644
--- a/lib/php/lib/Thrift/Server/TServerSocket.php
+++ b/lib/php/lib/Thrift/Server/TServerSocket.php
@@ -1,4 +1,24 @@
<?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\Server;
@@ -16,28 +36,28 @@
*
* @var resource
*/
- private $listener_;
+ protected $listener_;
/**
* Port for the listener to listen on
*
* @var int
*/
- private $port_;
+ protected $port_;
/**
* Timeout when listening for a new client
*
* @var int
*/
- private $acceptTimeout_ = 30000;
+ protected $acceptTimeout_ = 30000;
/**
* Host to listen on
*
* @var string
*/
- private $host_;
+ protected $host_;
/**
* ServerSocket constructor
diff --git a/lib/php/lib/Thrift/Transport/TSSLSocket.php b/lib/php/lib/Thrift/Transport/TSSLSocket.php
new file mode 100644
index 0000000..533b7bb
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TSSLSocket.php
@@ -0,0 +1,112 @@
+<?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\Exception\TException;
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Sockets implementation of the TTransport interface.
+ *
+ * @package thrift.transport
+ */
+class TSSLSocket extends TSocket
+{
+ /**
+ * Remote port
+ *
+ * @var resource
+ */
+ protected $context_ = null;
+
+ /**
+ * Socket constructor
+ *
+ * @param string $host Remote hostname
+ * @param int $port Remote port
+ * @param resource $context Stream context
+ * @param bool $persist Whether to use a persistent socket
+ * @param string $debugHandler Function to call for error logging
+ */
+ public function __construct($host='localhost',
+ $port=9090,
+ $context=null,
+ $debugHandler=null) {
+ $this->host_ = $this->getSSLHost($host);
+ $this->port_ = $port;
+ $this->context_ = $context;
+ $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log';
+ }
+
+ /**
+ * Creates a host name with SSL transport protocol
+ * if no transport protocol already specified in
+ * the host name.
+ *
+ * @param string $host Host to listen on
+ * @return string $host Host name with transport protocol
+ */
+ private function getSSLHost($host)
+ {
+ $transport_protocol_loc = strpos($host, "://");
+ if ($transport_protocol_loc === false) {
+ $host = 'ssl://'.$host;
+ }
+ return $host;
+ }
+
+ /**
+ * Connects the socket.
+ */
+ public function open()
+ {
+ if ($this->isOpen()) {
+ throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN);
+ }
+
+ if (empty($this->host_)) {
+ throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN);
+ }
+
+ if ($this->port_ <= 0) {
+ throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN);
+ }
+
+ $this->handle_ = @stream_socket_client($this->host_.':'.$this->port_,
+ $errno,
+ $errstr,
+ $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000),
+ STREAM_CLIENT_CONNECT,
+ $this->context_);
+
+ // Connect failed?
+ if ($this->handle_ === FALSE) {
+ $error = 'TSocket: Could not connect to '.$this->host_.':'.$this->port_.' ('.$errstr.' ['.$errno.'])';
+ if ($this->debug_) {
+ call_user_func($this->debugHandler_, $error);
+ }
+ throw new TException($error);
+ }
+ }
+}
diff --git a/lib/php/lib/Thrift/Transport/TSocket.php b/lib/php/lib/Thrift/Transport/TSocket.php
index 96935d4..10d5115 100644
--- a/lib/php/lib/Thrift/Transport/TSocket.php
+++ b/lib/php/lib/Thrift/Transport/TSocket.php
@@ -38,7 +38,7 @@
*
* @var resource
*/
- private $handle_ = null;
+ protected $handle_ = null;
/**
* Remote hostname
@@ -61,7 +61,7 @@
*
* @var int
*/
- private $sendTimeoutSec_ = 0;
+ protected $sendTimeoutSec_ = 0;
/**
* Send timeout in microseconds.
@@ -70,7 +70,7 @@
*
* @var int
*/
- private $sendTimeoutUsec_ = 100000;
+ protected $sendTimeoutUsec_ = 100000;
/**
* Recv timeout in seconds
@@ -79,7 +79,7 @@
*
* @var int
*/
- private $recvTimeoutSec_ = 0;
+ protected $recvTimeoutSec_ = 0;
/**
* Recv timeout in microseconds
@@ -88,7 +88,7 @@
*
* @var int
*/
- private $recvTimeoutUsec_ = 750000;
+ protected $recvTimeoutUsec_ = 750000;
/**
* Persistent socket or plain?
@@ -270,7 +270,7 @@
$readable = @stream_select($read, $null, $null, $this->recvTimeoutSec_, $this->recvTimeoutUsec_);
if ($readable > 0) {
- $data = @stream_socket_recvfrom($this->handle_, $len);
+ $data = fread($this->handle_, $len);
if ($data === false) {
throw new TTransportException('TSocket: Could not read '.$len.' bytes from '.
$this->host_.':'.$this->port_);
@@ -304,7 +304,7 @@
$writable = @stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
if ($writable > 0) {
// write buffer to stream
- $written = @stream_socket_sendto($this->handle_, $buf);
+ $written = fwrite($this->handle_, $buf);
if ($written === -1 || $written === false) {
throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
$this->host_.':'.$this->port_);