source: trunk/server/www/vendors/simpletest/encoding.php @ 6

Last change on this file since 6 was 6, checked in by sander, 11 years ago

Added SimpleTest? test framework

File size: 14.4 KB
Line 
1<?php
2/**
3 *  base include file for SimpleTest
4 *  @package    SimpleTest
5 *  @subpackage WebTester
6 *  @version    $Id: encoding.php 1723 2008-04-08 00:34:10Z lastcraft $
7 */
8   
9/**#@+
10 *  include other SimpleTest class files
11 */
12require_once(dirname(__FILE__) . '/socket.php');
13/**#@-*/
14
15/**
16 *    Single post parameter.
17 *    @package SimpleTest
18 *    @subpackage WebTester
19 */
20class SimpleEncodedPair {
21    var $_key;
22    var $_value;
23   
24    /**
25     *    Stashes the data for rendering later.
26     *    @param string $key       Form element name.
27     *    @param string $value     Data to send.
28     */
29    function SimpleEncodedPair($key, $value) {
30        $this->_key = $key;
31        $this->_value = $value;
32    }
33   
34    /**
35     *    The pair as a single string.
36     *    @return string        Encoded pair.
37     *    @access public
38     */
39    function asRequest() {
40        return urlencode($this->_key) . '=' . urlencode($this->_value);
41    }
42   
43    /**
44     *    The MIME part as a string.
45     *    @return string        MIME part encoding.
46     *    @access public
47     */
48    function asMime() {
49        $part = 'Content-Disposition: form-data; ';
50        $part .= "name=\"" . $this->_key . "\"\r\n";
51        $part .= "\r\n" . $this->_value;
52        return $part;
53    }
54   
55    /**
56     *    Is this the value we are looking for?
57     *    @param string $key    Identifier.
58     *    @return boolean       True if matched.
59     *    @access public
60     */
61    function isKey($key) {
62        return $key == $this->_key;
63    }
64   
65    /**
66     *    Is this the value we are looking for?
67     *    @return string       Identifier.
68     *    @access public
69     */
70    function getKey() {
71        return $this->_key;
72    }
73   
74    /**
75     *    Is this the value we are looking for?
76     *    @return string       Content.
77     *    @access public
78     */
79    function getValue() {
80        return $this->_value;
81    }
82}
83
84/**
85 *    Single post parameter.
86 *    @package SimpleTest
87 *    @subpackage WebTester
88 */
89class SimpleAttachment {
90    var $_key;
91    var $_content;
92    var $_filename;
93   
94    /**
95     *    Stashes the data for rendering later.
96     *    @param string $key          Key to add value to.
97     *    @param string $content      Raw data.
98     *    @param hash $filename       Original filename.
99     */
100    function SimpleAttachment($key, $content, $filename) {
101        $this->_key = $key;
102        $this->_content = $content;
103        $this->_filename = $filename;
104    }
105   
106    /**
107     *    The pair as a single string.
108     *    @return string        Encoded pair.
109     *    @access public
110     */
111    function asRequest() {
112        return '';
113    }
114   
115    /**
116     *    The MIME part as a string.
117     *    @return string        MIME part encoding.
118     *    @access public
119     */
120    function asMime() {
121        $part = 'Content-Disposition: form-data; ';
122        $part .= 'name="' . $this->_key . '"; ';
123        $part .= 'filename="' . $this->_filename . '"';
124        $part .= "\r\nContent-Type: " . $this->_deduceMimeType();
125        $part .= "\r\n\r\n" . $this->_content;
126        return $part;
127    }
128   
129    /**
130     *    Attempts to figure out the MIME type from the
131     *    file extension and the content.
132     *    @return string        MIME type.
133     *    @access private
134     */
135    function _deduceMimeType() {
136        if ($this->_isOnlyAscii($this->_content)) {
137            return 'text/plain';
138        }
139        return 'application/octet-stream';
140    }
141   
142    /**
143     *    Tests each character is in the range 0-127.
144     *    @param string $ascii    String to test.
145     *    @access private
146     */
147    function _isOnlyAscii($ascii) {
148        for ($i = 0, $length = strlen($ascii); $i < $length; $i++) {
149            if (ord($ascii[$i]) > 127) {
150                return false;
151            }
152        }
153        return true;
154    }
155   
156    /**
157     *    Is this the value we are looking for?
158     *    @param string $key    Identifier.
159     *    @return boolean       True if matched.
160     *    @access public
161     */
162    function isKey($key) {
163        return $key == $this->_key;
164    }
165   
166    /**
167     *    Is this the value we are looking for?
168     *    @return string       Identifier.
169     *    @access public
170     */
171    function getKey() {
172        return $this->_key;
173    }
174   
175    /**
176     *    Is this the value we are looking for?
177     *    @return string       Content.
178     *    @access public
179     */
180    function getValue() {
181        return $this->_filename;
182    }
183}
184
185/**
186 *    Bundle of GET/POST parameters. Can include
187 *    repeated parameters.
188 *    @package SimpleTest
189 *    @subpackage WebTester
190 */
191class SimpleEncoding {
192    var $_request;
193   
194    /**
195     *    Starts empty.
196     *    @param array $query       Hash of parameters.
197     *                              Multiple values are
198     *                              as lists on a single key.
199     *    @access public
200     */
201    function SimpleEncoding($query = false) {
202        if (! $query) {
203            $query = array();
204        }
205        $this->clear();
206        $this->merge($query);
207    }
208   
209    /**
210     *    Empties the request of parameters.
211     *    @access public
212     */
213    function clear() {
214        $this->_request = array();
215    }
216   
217    /**
218     *    Adds a parameter to the query.
219     *    @param string $key            Key to add value to.
220     *    @param string/array $value    New data.
221     *    @access public
222     */
223    function add($key, $value) {
224        if ($value === false) {
225            return;
226        }
227        if (is_array($value)) {
228            foreach ($value as $item) {
229                $this->_addPair($key, $item);
230            }
231        } else {
232            $this->_addPair($key, $value);
233        }
234    }
235   
236    /**
237     *    Adds a new value into the request.
238     *    @param string $key            Key to add value to.
239     *    @param string/array $value    New data.
240     *    @access private
241     */
242    function _addPair($key, $value) {
243        $this->_request[] = new SimpleEncodedPair($key, $value);
244    }
245   
246    /**
247     *    Adds a MIME part to the query. Does nothing for a
248     *    form encoded packet.
249     *    @param string $key          Key to add value to.
250     *    @param string $content      Raw data.
251     *    @param hash $filename       Original filename.
252     *    @access public
253     */
254    function attach($key, $content, $filename) {
255        $this->_request[] = new SimpleAttachment($key, $content, $filename);
256    }
257   
258    /**
259     *    Adds a set of parameters to this query.
260     *    @param array/SimpleQueryString $query  Multiple values are
261     *                                           as lists on a single key.
262     *    @access public
263     */
264    function merge($query) {
265        if (is_object($query)) {
266            $this->_request = array_merge($this->_request, $query->getAll());
267        } elseif (is_array($query)) {
268            foreach ($query as $key => $value) {
269                $this->add($key, $value);
270            }
271        }
272    }
273   
274    /**
275     *    Accessor for single value.
276     *    @return string/array    False if missing, string
277     *                            if present and array if
278     *                            multiple entries.
279     *    @access public
280     */
281    function getValue($key) {
282        $values = array();
283        foreach ($this->_request as $pair) {
284            if ($pair->isKey($key)) {
285                $values[] = $pair->getValue();
286            }
287        }
288        if (count($values) == 0) {
289            return false;
290        } elseif (count($values) == 1) {
291            return $values[0];
292        } else {
293            return $values;
294        }
295    }
296   
297    /**
298     *    Accessor for listing of pairs.
299     *    @return array        All pair objects.
300     *    @access public
301     */
302    function getAll() {
303        return $this->_request;
304    }
305   
306    /**
307     *    Renders the query string as a URL encoded
308     *    request part.
309     *    @return string        Part of URL.
310     *    @access protected
311     */
312    function _encode() {
313        $statements = array();
314        foreach ($this->_request as $pair) {
315            if ($statement = $pair->asRequest()) {
316                $statements[] = $statement;
317            }
318        }
319        return implode('&', $statements);
320    }
321}
322
323/**
324 *    Bundle of GET parameters. Can include
325 *    repeated parameters.
326 *    @package SimpleTest
327 *    @subpackage WebTester
328 */
329class SimpleGetEncoding extends SimpleEncoding {
330   
331    /**
332     *    Starts empty.
333     *    @param array $query       Hash of parameters.
334     *                              Multiple values are
335     *                              as lists on a single key.
336     *    @access public
337     */
338    function SimpleGetEncoding($query = false) {
339        $this->SimpleEncoding($query);
340    }
341   
342    /**
343     *    HTTP request method.
344     *    @return string        Always GET.
345     *    @access public
346     */
347    function getMethod() {
348        return 'GET';
349    }
350   
351    /**
352     *    Writes no extra headers.
353     *    @param SimpleSocket $socket        Socket to write to.
354     *    @access public
355     */
356    function writeHeadersTo(&$socket) {
357    }
358   
359    /**
360     *    No data is sent to the socket as the data is encoded into
361     *    the URL.
362     *    @param SimpleSocket $socket        Socket to write to.
363     *    @access public
364     */
365    function writeTo(&$socket) {
366    }
367   
368    /**
369     *    Renders the query string as a URL encoded
370     *    request part for attaching to a URL.
371     *    @return string        Part of URL.
372     *    @access public
373     */
374    function asUrlRequest() {
375        return $this->_encode();
376    }
377}
378
379/**
380 *    Bundle of URL parameters for a HEAD request.
381 *    @package SimpleTest
382 *    @subpackage WebTester
383 */
384class SimpleHeadEncoding extends SimpleGetEncoding {
385   
386    /**
387     *    Starts empty.
388     *    @param array $query       Hash of parameters.
389     *                              Multiple values are
390     *                              as lists on a single key.
391     *    @access public
392     */
393    function SimpleHeadEncoding($query = false) {
394        $this->SimpleGetEncoding($query);
395    }
396   
397    /**
398     *    HTTP request method.
399     *    @return string        Always HEAD.
400     *    @access public
401     */
402    function getMethod() {
403        return 'HEAD';
404    }
405}
406
407/**
408 *    Bundle of POST parameters. Can include
409 *    repeated parameters.
410 *    @package SimpleTest
411 *    @subpackage WebTester
412 */
413class SimplePostEncoding extends SimpleEncoding {
414   
415    /**
416     *    Starts empty.
417     *    @param array $query       Hash of parameters.
418     *                              Multiple values are
419     *                              as lists on a single key.
420     *    @access public
421     */
422    function SimplePostEncoding($query = false) {
423        if (is_array($query) and $this->hasMoreThanOneLevel($query)) {
424            $query = $this->rewriteArrayWithMultipleLevels($query);
425        }
426        $this->SimpleEncoding($query);
427    }
428   
429    function hasMoreThanOneLevel($query) {
430        foreach ($query as $key => $value) {
431            if (is_array($value)) {
432                return true;
433            }
434        }
435        return false;
436    }
437
438    function rewriteArrayWithMultipleLevels($query) {
439        $query_ = array();
440        foreach ($query as $key => $value) {
441            if (is_array($value)) {
442                foreach ($value as $sub_key => $sub_value) {
443                    $query_[$key."[".$sub_key."]"] = $sub_value;
444                }
445            } else {
446                $query_[$key] = $value;
447            }
448        }
449        if ($this->hasMoreThanOneLevel($query_)) {
450            $query_ = $this->rewriteArrayWithMultipleLevels($query_);
451        }
452       
453        return $query_;
454    }
455   
456   
457    /**
458     *    HTTP request method.
459     *    @return string        Always POST.
460     *    @access public
461     */
462    function getMethod() {
463        return 'POST';
464    }
465   
466    /**
467     *    Dispatches the form headers down the socket.
468     *    @param SimpleSocket $socket        Socket to write to.
469     *    @access public
470     */
471    function writeHeadersTo(&$socket) {
472        $socket->write("Content-Length: " . (integer)strlen($this->_encode()) . "\r\n");
473        $socket->write("Content-Type: application/x-www-form-urlencoded\r\n");
474    }
475   
476    /**
477     *    Dispatches the form data down the socket.
478     *    @param SimpleSocket $socket        Socket to write to.
479     *    @access public
480     */
481    function writeTo(&$socket) {
482        $socket->write($this->_encode());
483    }
484   
485    /**
486     *    Renders the query string as a URL encoded
487     *    request part for attaching to a URL.
488     *    @return string        Part of URL.
489     *    @access public
490     */
491    function asUrlRequest() {
492        return '';
493    }
494}
495
496/**
497 *    Bundle of POST parameters in the multipart
498 *    format. Can include file uploads.
499 *    @package SimpleTest
500 *    @subpackage WebTester
501 */
502class SimpleMultipartEncoding extends SimplePostEncoding {
503    var $_boundary;
504   
505    /**
506     *    Starts empty.
507     *    @param array $query       Hash of parameters.
508     *                              Multiple values are
509     *                              as lists on a single key.
510     *    @access public
511     */
512    function SimpleMultipartEncoding($query = false, $boundary = false) {
513        $this->SimplePostEncoding($query);
514        $this->_boundary = ($boundary === false ? uniqid('st') : $boundary);
515    }
516   
517    /**
518     *    Dispatches the form headers down the socket.
519     *    @param SimpleSocket $socket        Socket to write to.
520     *    @access public
521     */
522    function writeHeadersTo(&$socket) {
523        $socket->write("Content-Length: " . (integer)strlen($this->_encode()) . "\r\n");
524        $socket->write("Content-Type: multipart/form-data, boundary=" . $this->_boundary . "\r\n");
525    }
526   
527    /**
528     *    Dispatches the form data down the socket.
529     *    @param SimpleSocket $socket        Socket to write to.
530     *    @access public
531     */
532    function writeTo(&$socket) {
533        $socket->write($this->_encode());
534    }
535   
536    /**
537     *    Renders the query string as a URL encoded
538     *    request part.
539     *    @return string        Part of URL.
540     *    @access public
541     */
542    function _encode() {
543        $stream = '';
544        foreach ($this->_request as $pair) {
545            $stream .= "--" . $this->_boundary . "\r\n";
546            $stream .= $pair->asMime() . "\r\n";
547        }
548        $stream .= "--" . $this->_boundary . "--\r\n";
549        return $stream;
550    }
551}
552?>
Note: See TracBrowser for help on using the repository browser.