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