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