|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Queue |
|
17 * @subpackage Stomp |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Frame.php 22662 2010-07-24 17:37:36Z mabe $ |
|
21 */ |
|
22 |
|
23 /** |
|
24 * @see Zend_Queue_Stomp_FrameInterface |
|
25 */ |
|
26 require_once 'Zend/Queue/Stomp/FrameInterface.php'; |
|
27 |
|
28 /** |
|
29 * This class represents a Stomp Frame |
|
30 * |
|
31 * @category Zend |
|
32 * @package Zend_Queue |
|
33 * @subpackage Stomp |
|
34 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
35 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
36 */ |
|
37 class Zend_Queue_Stomp_Frame |
|
38 implements Zend_Queue_Stomp_FrameInterface |
|
39 { |
|
40 const END_OF_FRAME = "\x00\n"; |
|
41 const CONTENT_LENGTH = 'content-length'; |
|
42 const EOL = "\n"; |
|
43 |
|
44 /** |
|
45 * Headers for the frame |
|
46 * |
|
47 * @var array |
|
48 */ |
|
49 protected $_headers = array(); |
|
50 |
|
51 /** |
|
52 * The command for the frame |
|
53 * |
|
54 * @var string |
|
55 */ |
|
56 protected $_command = null; |
|
57 |
|
58 /** |
|
59 * The body of the frame |
|
60 * |
|
61 * @var string |
|
62 */ |
|
63 protected $_body = null; |
|
64 |
|
65 /** |
|
66 * Do the content-length automatically? |
|
67 */ |
|
68 protected $_autoContentLength = null; |
|
69 |
|
70 /** |
|
71 * Constructor |
|
72 */ |
|
73 public function __construct() |
|
74 { |
|
75 $this->setHeaders(array()); |
|
76 $this->setBody(null); |
|
77 $this->setCommand(null); |
|
78 $this->setAutoContentLength(true); |
|
79 } |
|
80 |
|
81 /** |
|
82 * get the status of the auto content length |
|
83 * |
|
84 * If AutoContentLength is true this code will automatically put the |
|
85 * content-length header in, even if it is already set by the user. |
|
86 * |
|
87 * This is done to make the message sending more reliable. |
|
88 * |
|
89 * @return boolean |
|
90 */ |
|
91 public function getAutoContentLength() |
|
92 { |
|
93 return $this->_autoContentLength; |
|
94 } |
|
95 |
|
96 /** |
|
97 * setAutoContentLength() |
|
98 * |
|
99 * Set the value on or off. |
|
100 * |
|
101 * @param boolean $auto |
|
102 * @return $this; |
|
103 * @throws Zend_Queue_Exception |
|
104 */ |
|
105 public function setAutoContentLength($auto) |
|
106 { |
|
107 if (!is_bool($auto)) { |
|
108 require_once 'Zend/Queue/Exception.php'; |
|
109 throw new Zend_Queue_Exception('$auto is not a boolean'); |
|
110 } |
|
111 |
|
112 $this->_autoContentLength = $auto; |
|
113 return $this; |
|
114 } |
|
115 |
|
116 /** |
|
117 * Get the headers |
|
118 * |
|
119 * @return array |
|
120 */ |
|
121 public function getHeaders() |
|
122 { |
|
123 return $this->_headers; |
|
124 } |
|
125 |
|
126 /** |
|
127 * Set the headers |
|
128 * |
|
129 * Throws an exception if the array values are not strings. |
|
130 * |
|
131 * @param array $headers |
|
132 * @return $this |
|
133 * @throws Zend_Queue_Exception |
|
134 */ |
|
135 public function setHeaders(array $headers) |
|
136 { |
|
137 foreach ($headers as $header => $value) { |
|
138 $this->setHeader($header, $value); |
|
139 } |
|
140 |
|
141 return $this; |
|
142 } |
|
143 |
|
144 /** |
|
145 * Sets a value for a header |
|
146 * |
|
147 * @param string $header |
|
148 * @param string $value |
|
149 * @return Zend_Queue_Stomp_Frame |
|
150 * @throws Zend_Queue_Exception |
|
151 */ |
|
152 public function setHeader($header, $value) { |
|
153 if (!is_string($header)) { |
|
154 require_once 'Zend/Queue/Exception.php'; |
|
155 throw new Zend_Queue_Exception('$header is not a string: ' . print_r($header, true)); |
|
156 } |
|
157 |
|
158 if (!is_scalar($value)) { |
|
159 require_once 'Zend/Queue/Exception.php'; |
|
160 throw new Zend_Queue_Exception('$value is not a string: ' . print_r($value, true)); |
|
161 } |
|
162 |
|
163 $this->_headers[$header] = $value; |
|
164 return $this; |
|
165 } |
|
166 |
|
167 |
|
168 /** |
|
169 * Returns a value for a header |
|
170 * |
|
171 * Returns false if the header does not exist. |
|
172 * |
|
173 * @param string $header |
|
174 * @return string|false |
|
175 * @throws Zend_Queue_Exception |
|
176 */ |
|
177 public function getHeader($header) |
|
178 { |
|
179 if (!is_string($header)) { |
|
180 require_once 'Zend/Queue/Exception.php'; |
|
181 throw new Zend_Queue_Exception('$header is not a string'); |
|
182 } |
|
183 |
|
184 return isset($this->_headers[$header]) |
|
185 ? $this->_headers[$header] |
|
186 : false; |
|
187 } |
|
188 |
|
189 /** |
|
190 * Return the body for this frame |
|
191 * |
|
192 * Returns false if the body does not exist |
|
193 * |
|
194 * @return false|string |
|
195 */ |
|
196 public function getBody() |
|
197 { |
|
198 return $this->_body === null |
|
199 ? false |
|
200 : $this->_body; |
|
201 } |
|
202 |
|
203 /** |
|
204 * Set the body for this frame |
|
205 * |
|
206 * Set to null for no body. |
|
207 * |
|
208 * @param string|null $body |
|
209 * @return Zend_Queue_Stomp_Frame |
|
210 * @throws Zend_Queue_Exception |
|
211 */ |
|
212 public function setBody($body) |
|
213 { |
|
214 if (!is_string($body) && $body !== null) { |
|
215 require_once 'Zend/Queue/Exception.php'; |
|
216 throw new Zend_Queue_Exception('$body is not a string or null'); |
|
217 } |
|
218 |
|
219 $this->_body = $body; |
|
220 return $this; |
|
221 } |
|
222 |
|
223 /** |
|
224 * Return the command for this frame |
|
225 * |
|
226 * Return false if the command does not exist |
|
227 * |
|
228 * @return string|false |
|
229 */ |
|
230 public function getCommand() |
|
231 { |
|
232 return $this->_command === null |
|
233 ? false |
|
234 : $this->_command; |
|
235 } |
|
236 |
|
237 /** |
|
238 * Set the body for this frame |
|
239 * |
|
240 * @param string|null |
|
241 * @return Zend_Queue_Stomp_Frame |
|
242 * @throws Zend_Queue_Exception |
|
243 */ |
|
244 public function setCommand($command) |
|
245 { |
|
246 if (!is_string($command) && $command !== null) { |
|
247 require_once 'Zend/Queue/Exception.php'; |
|
248 throw new Zend_Queue_Exception('$command is not a string or null'); |
|
249 } |
|
250 |
|
251 $this->_command = $command; |
|
252 return $this; |
|
253 } |
|
254 |
|
255 /** |
|
256 * Takes the current parameters and returns a Stomp Frame |
|
257 * |
|
258 * @return string |
|
259 * @throws Zend_Queue_Exception |
|
260 */ |
|
261 public function toFrame() |
|
262 { |
|
263 if ($this->getCommand() === false) { |
|
264 require_once 'Zend/Queue/Exception.php'; |
|
265 throw new Zend_Queue_Exception('You must set the command'); |
|
266 } |
|
267 |
|
268 $command = $this->getCommand(); |
|
269 $headers = $this->getHeaders(); |
|
270 $body = $this->getBody(); |
|
271 $frame = ''; |
|
272 |
|
273 // add a content-length to the SEND command. |
|
274 // @see http://stomp.codehaus.org/Protocol |
|
275 if ($this->getAutoContentLength()) { |
|
276 $headers[self::CONTENT_LENGTH] = strlen($this->getBody()); |
|
277 } |
|
278 |
|
279 // Command |
|
280 $frame = $command . self::EOL; |
|
281 |
|
282 // Headers |
|
283 foreach ($headers as $key=>$value) { |
|
284 $frame .= $key . ': ' . $value . self::EOL; |
|
285 } |
|
286 |
|
287 // Seperator |
|
288 $frame .= self::EOL; // blank line required by protocol |
|
289 |
|
290 // add the body if any |
|
291 if ($body !== false) { |
|
292 $frame .= $body; |
|
293 } |
|
294 $frame .= self::END_OF_FRAME; |
|
295 |
|
296 return $frame; |
|
297 } |
|
298 |
|
299 /** |
|
300 * @see toFrame() |
|
301 * @return string |
|
302 */ |
|
303 public function __toString() |
|
304 { |
|
305 try { |
|
306 $return = $this->toFrame(); |
|
307 } catch (Zend_Queue_Exception $e) { |
|
308 $return = ''; |
|
309 } |
|
310 return $return; |
|
311 } |
|
312 |
|
313 /** |
|
314 * Accepts a frame and deconstructs the frame into its component parts |
|
315 * |
|
316 * @param string $frame - a stomp frame |
|
317 * @return $this |
|
318 */ |
|
319 public function fromFrame($frame) |
|
320 { |
|
321 if (!is_string($frame)) { |
|
322 require_once 'Zend/Queue/Exception.php'; |
|
323 throw new Zend_Queue_Exception('$frame is not a string'); |
|
324 } |
|
325 |
|
326 $headers = array(); |
|
327 $body = null; |
|
328 $command = false; |
|
329 $header = ''; |
|
330 |
|
331 // separate the headers and the body |
|
332 $match = self::EOL . self::EOL; |
|
333 if (preg_match('/' . $match . '/', $frame)) { |
|
334 list ($header, $body) = explode($match, $frame, 2); |
|
335 } else { |
|
336 $header = $frame; |
|
337 } |
|
338 |
|
339 // blow up headers |
|
340 $headers = explode(self::EOL, $header); |
|
341 unset($header); |
|
342 |
|
343 // get the command (first line) |
|
344 $this->setCommand(array_shift($headers)); |
|
345 |
|
346 // set each of the headers. |
|
347 foreach ($headers as $header) { |
|
348 if (strpos($header, ':') > 0) { |
|
349 list($name, $value) = explode(':', $header, 2); |
|
350 $this->setHeader($name, $value); |
|
351 } |
|
352 } |
|
353 |
|
354 // crop the body if content-length is present |
|
355 if ($this->getHeader(self::CONTENT_LENGTH) !== false ) { |
|
356 $length = (int) $this->getHeader(self::CONTENT_LENGTH); |
|
357 $body = substr($body, 0, $length); |
|
358 } |
|
359 |
|
360 $this->setBody($body); |
|
361 return $this; |
|
362 } |
|
363 } |