PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/common/libraries/plugin/simpletest/encoding.php

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