blob: 06cf9d82d39d0ba1fbe2301a3707f80ebae20535 [file] [log] [blame]
Mark Slee4d73d5c2007-06-29 23:15:00 +00001<?php
2
3/**
4 * Copyright (c) 2006- Facebook
5 * Distributed under the Thrift Software License
6 *
7 * See accompanying file LICENSE or visit the Thrift site at:
8 * http://developers.facebook.com/thrift/
9 *
10 * @package thrift.transport
11 * @author Mark Slee <mcslee@facebook.com>
12 */
13
14/**
15 * HTTP client for Thrift
16 *
17 * @package thrift.transport
18 * @author Mark Slee <mcslee@facebook.com>
19 */
20class THttpClient extends TTransport {
21
22 /**
23 * The host to connect to
24 *
25 * @var string
26 */
27 protected $host_;
28
29 /**
30 * The port to connect on
31 *
32 * @var int
33 */
34 protected $port_;
35
36 /**
37 * The URI to request
38 *
39 * @var string
40 */
41 protected $uri_;
42
43 /**
44 * Buffer for the HTTP request data
45 *
46 * @var string
47 */
48 protected $buf_;
49
50 /**
51 * Input socket stream.
52 *
53 * @var resource
54 */
55 protected $handle_;
56
57 /**
58 * Read timeout
59 *
60 * @var float
61 */
62 protected $timeout_;
63
64 /**
65 * Make a new HTTP client.
66 *
67 * @param string $host
68 * @param int $port
69 * @param string $uri
70 */
71 public function __construct($host, $port=80, $uri='') {
72 if ((strlen($uri) > 0) && ($uri{0} != '/')) {
73 $uri = '/'.$uri;
74 }
75 $this->host_ = $host;
76 $this->port_ = $port;
77 $this->uri_ = $uri;
78 $this->buf_ = '';
79 $this->handle_ = null;
80 $this->timeout_ = null;
81 }
82
83 /**
84 * Set read timeout
85 *
86 * @param float $timeout
87 */
88 public function setTimeoutSecs($timeout) {
89 $this->timeout_ = $timeout;
90 }
91
92 /**
93 * Whether this transport is open.
94 *
95 * @return boolean true if open
96 */
97 public function isOpen() {
98 return true;
99 }
100
101 /**
102 * Open the transport for reading/writing
103 *
104 * @throws TTransportException if cannot open
105 */
106 public function open() {}
107
108 /**
109 * Close the transport.
110 */
111 public function close() {
112 if ($this->handle_) {
113 @fclose($this->handle_);
114 $this->handle_ = null;
115 }
116 }
117
118 /**
119 * Read some data into the array.
120 *
121 * @param int $len How much to read
122 * @return string The data that has been read
123 * @throws TTransportException if cannot read any more data
124 */
125 public function read($len) {
126 $data = @fread($this->handle_, $len);
127 if ($data === FALSE || $data === '') {
128 $md = stream_get_meta_data($this->handle_);
129 if ($md['timed_out']) {
130 throw new TTransportException('THttpClient: timed out reading '.$len.' bytes from '.$this->host_.':'.$this->port_.'/'.$this->uri_, TTransportException::TIMED_OUT);
131 } else {
132 throw new TTransportException('THttpClient: Could not read '.$len.' bytes from '.$this->host_.':'.$this->port_.'/'.$this->uri_, TTransportException::UNKNOWN);
133 }
134 }
135 return $data;
136 }
137
138 /**
139 * Writes some data into the pending buffer
140 *
141 * @param string $buf The data to write
142 * @throws TTransportException if writing fails
143 */
144 public function write($buf) {
145 $this->buf_ .= $buf;
146 }
147
148 /**
149 * Opens and sends the actual request over the HTTP connection
150 *
151 * @throws TTransportException if a writing error occurs
152 */
153 public function flush() {
154 // God, PHP really has some esoteric ways of doing simple things.
155 $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
156
157 $headers = array('Host: '.$host,
158 'Accept: application/x-thrift',
159 'User-Agent: PHP/THttpClient',
160 'Content-Type: application/x-thrift',
161 'Content-Length: '.strlen($this->buf_));
162
163 $options = array('method' => 'POST',
164 'header' => implode("\r\n", $headers),
165 'max_redirects' => 1,
166 'content' => $this->buf_);
167 if ($this->timeout_ > 0) {
168 $options['timeout'] = $this->timeout_;
169 }
170 $this->buf_ = '';
171
172 $contextid = stream_context_create(array('http' => $options));
173 $this->handle_ = @fopen('http://'.$host.$this->uri_, 'r', false, $contextid);
174
175 // Connect failed?
176 if ($this->handle_ === FALSE) {
177 $this->handle_ = null;
178 $error = 'THttpClient: Could not connect to '.$host.$this->uri_;
179 throw new TTransportException($error, TTransportException::NOT_OPEN);
180 }
181 }
182
183}
184
185?>