blob: 102dbbb765efe34aaca0af5fd93c4f635f9fb547 [file] [log] [blame]
Mark Slee4d73d5c2007-06-29 23:15:00 +00001<?php
David Reissea2cba82009-03-30 21:35:00 +00002/*
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
Mark Slee4d73d5c2007-06-29 23:15:00 +000010 *
David Reissea2cba82009-03-30 21:35:00 +000011 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
Mark Slee4d73d5c2007-06-29 23:15:00 +000019 *
20 * @package thrift.transport
Mark Slee4d73d5c2007-06-29 23:15:00 +000021 */
22
David Reissea2cba82009-03-30 21:35:00 +000023
Mark Slee4d73d5c2007-06-29 23:15:00 +000024/**
25 * HTTP client for Thrift
26 *
27 * @package thrift.transport
Mark Slee4d73d5c2007-06-29 23:15:00 +000028 */
29class THttpClient extends TTransport {
30
31 /**
32 * The host to connect to
33 *
34 * @var string
35 */
36 protected $host_;
37
38 /**
39 * The port to connect on
40 *
41 * @var int
42 */
43 protected $port_;
44
45 /**
46 * The URI to request
47 *
48 * @var string
49 */
50 protected $uri_;
51
52 /**
David Reiss1f5ce502008-07-27 23:41:13 +000053 * The scheme to use for the request, i.e. http, https
54 *
55 * @var string
56 */
57 protected $scheme_;
58
59 /**
Mark Slee4d73d5c2007-06-29 23:15:00 +000060 * Buffer for the HTTP request data
61 *
62 * @var string
63 */
64 protected $buf_;
65
66 /**
67 * Input socket stream.
68 *
69 * @var resource
70 */
71 protected $handle_;
72
73 /**
74 * Read timeout
75 *
76 * @var float
77 */
78 protected $timeout_;
79
80 /**
81 * Make a new HTTP client.
82 *
83 * @param string $host
84 * @param int $port
85 * @param string $uri
86 */
David Reiss1f5ce502008-07-27 23:41:13 +000087 public function __construct($host, $port=80, $uri='', $scheme = 'http') {
Mark Slee4d73d5c2007-06-29 23:15:00 +000088 if ((strlen($uri) > 0) && ($uri{0} != '/')) {
89 $uri = '/'.$uri;
90 }
David Reiss1f5ce502008-07-27 23:41:13 +000091 $this->scheme_ = $scheme;
Mark Slee4d73d5c2007-06-29 23:15:00 +000092 $this->host_ = $host;
93 $this->port_ = $port;
94 $this->uri_ = $uri;
95 $this->buf_ = '';
96 $this->handle_ = null;
97 $this->timeout_ = null;
98 }
99
100 /**
101 * Set read timeout
102 *
103 * @param float $timeout
104 */
105 public function setTimeoutSecs($timeout) {
106 $this->timeout_ = $timeout;
107 }
108
109 /**
110 * Whether this transport is open.
111 *
112 * @return boolean true if open
113 */
114 public function isOpen() {
115 return true;
116 }
117
118 /**
119 * Open the transport for reading/writing
120 *
121 * @throws TTransportException if cannot open
122 */
123 public function open() {}
124
125 /**
126 * Close the transport.
127 */
128 public function close() {
129 if ($this->handle_) {
130 @fclose($this->handle_);
131 $this->handle_ = null;
132 }
133 }
134
135 /**
136 * Read some data into the array.
137 *
138 * @param int $len How much to read
139 * @return string The data that has been read
140 * @throws TTransportException if cannot read any more data
141 */
142 public function read($len) {
143 $data = @fread($this->handle_, $len);
144 if ($data === FALSE || $data === '') {
145 $md = stream_get_meta_data($this->handle_);
146 if ($md['timed_out']) {
147 throw new TTransportException('THttpClient: timed out reading '.$len.' bytes from '.$this->host_.':'.$this->port_.'/'.$this->uri_, TTransportException::TIMED_OUT);
148 } else {
149 throw new TTransportException('THttpClient: Could not read '.$len.' bytes from '.$this->host_.':'.$this->port_.'/'.$this->uri_, TTransportException::UNKNOWN);
150 }
151 }
152 return $data;
153 }
154
155 /**
156 * Writes some data into the pending buffer
157 *
158 * @param string $buf The data to write
159 * @throws TTransportException if writing fails
160 */
161 public function write($buf) {
162 $this->buf_ .= $buf;
163 }
164
165 /**
166 * Opens and sends the actual request over the HTTP connection
167 *
168 * @throws TTransportException if a writing error occurs
169 */
170 public function flush() {
171 // God, PHP really has some esoteric ways of doing simple things.
172 $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
173
174 $headers = array('Host: '.$host,
175 'Accept: application/x-thrift',
176 'User-Agent: PHP/THttpClient',
177 'Content-Type: application/x-thrift',
178 'Content-Length: '.strlen($this->buf_));
Mark Slee0cdc6c82007-11-13 10:19:08 +0000179
Mark Slee4d73d5c2007-06-29 23:15:00 +0000180 $options = array('method' => 'POST',
181 'header' => implode("\r\n", $headers),
182 'max_redirects' => 1,
183 'content' => $this->buf_);
184 if ($this->timeout_ > 0) {
185 $options['timeout'] = $this->timeout_;
186 }
187 $this->buf_ = '';
188
189 $contextid = stream_context_create(array('http' => $options));
David Reiss1f5ce502008-07-27 23:41:13 +0000190 $this->handle_ = @fopen($this->scheme_.'://'.$host.$this->uri_, 'r', false, $contextid);
Mark Slee4d73d5c2007-06-29 23:15:00 +0000191
192 // Connect failed?
193 if ($this->handle_ === FALSE) {
194 $this->handle_ = null;
195 $error = 'THttpClient: Could not connect to '.$host.$this->uri_;
196 throw new TTransportException($error, TTransportException::NOT_OPEN);
197 }
198 }
199
200}