/cake/tests/cases/libs/http_socket.test.php

https://github.com/yjcqwliu/xuanjianghui · PHP · 1313 lines · 991 code · 165 blank · 157 comment · 8 complexity · 8911a2a7136d3ce0d35c80b44843d983 MD5 · raw file

  1. <?php
  2. /* SVN FILE: $Id: http_socket.test.php 7690 2008-10-02 04:56:53Z nate $ */
  3. /**
  4. * Short description for file.
  5. *
  6. * Long description for file
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
  11. * Copyright 2005-2008, Cake Software Foundation, Inc.
  12. * 1785 E. Sahara Avenue, Suite 490-204
  13. * Las Vegas, Nevada 89104
  14. *
  15. * Licensed under The Open Group Test Suite License
  16. * Redistributions of files must retain the above copyright notice.
  17. *
  18. * @filesource
  19. * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
  20. * @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
  21. * @package cake.tests
  22. * @subpackage cake.tests.cases.libs
  23. * @since CakePHP(tm) v 1.2.0.4206
  24. * @version $Revision: 7690 $
  25. * @modifiedby $LastChangedBy: nate $
  26. * @lastmodified $Date: 2008-10-02 00:56:53 -0400 (Thu, 02 Oct 2008) $
  27. * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
  28. */
  29. App::import('Core', 'HttpSocket');
  30. /**
  31. * Short description for class.
  32. *
  33. * @package cake.tests
  34. * @subpackage cake.tests.cases.libs
  35. */
  36. class HttpSocketTest extends CakeTestCase {
  37. /**
  38. * Socket property
  39. *
  40. * @var mixed null
  41. * @access public
  42. */
  43. var $Socket = null;
  44. /**
  45. * RequestSocket property
  46. *
  47. * @var mixed null
  48. * @access public
  49. */
  50. var $RequestSocket = null;
  51. /**
  52. * This function sets up a TestHttpSocket instance we are going to use for testing
  53. *
  54. */
  55. function setUp() {
  56. if (!class_exists('TestHttpSocket')) {
  57. Mock::generatePartial('HttpSocket', 'TestHttpSocket', array('read', 'write', 'connect'));
  58. Mock::generatePartial('HttpSocket', 'TestHttpSocketRequests', array('read', 'write', 'connect', 'request'));
  59. }
  60. $this->Socket =& new TestHttpSocket();
  61. $this->RequestSocket =& new TestHttpSocketRequests();
  62. }
  63. /**
  64. * We use this function to clean up after the test case was executed
  65. *
  66. */
  67. function tearDown() {
  68. unset($this->Socket, $this->RequestSocket);
  69. }
  70. /**
  71. * Test that HttpSocket::__construct does what one would expect it to do
  72. *
  73. */
  74. function testConstruct() {
  75. $this->Socket->reset();
  76. $baseConfig = $this->Socket->config;
  77. $this->Socket->expectNever('connect');
  78. $this->Socket->__construct(array('host' => 'foo-bar'));
  79. $baseConfig['host'] = 'foo-bar';
  80. $baseConfig['protocol'] = getprotobyname($baseConfig['protocol']);
  81. $this->assertIdentical($this->Socket->config, $baseConfig);
  82. $this->Socket->reset();
  83. $baseConfig = $this->Socket->config;
  84. $this->Socket->__construct('http://www.cakephp.org:23/');
  85. $baseConfig['host'] = 'www.cakephp.org';
  86. $baseConfig['request']['uri']['host'] = 'www.cakephp.org';
  87. $baseConfig['port'] = 23;
  88. $baseConfig['request']['uri']['port'] = 23;
  89. $baseConfig['protocol'] = getprotobyname($baseConfig['protocol']);
  90. $this->assertIdentical($this->Socket->config, $baseConfig);
  91. $this->Socket->reset();
  92. $this->Socket->__construct(array('request' => array('uri' => 'http://www.cakephp.org:23/')));
  93. $this->assertIdentical($this->Socket->config, $baseConfig);
  94. }
  95. /**
  96. * Test that HttpSocket::configUri works properly with different types of arguments
  97. *
  98. */
  99. function testConfigUri() {
  100. $this->Socket->reset();
  101. $r = $this->Socket->configUri('https://bob:secret@www.cakephp.org:23/?query=foo');
  102. $expected = array(
  103. 'persistent' => false,
  104. 'host' => 'www.cakephp.org',
  105. 'protocol' => 'tcp',
  106. 'port' => 23,
  107. 'timeout' => 30,
  108. 'request' => array(
  109. 'uri' => array(
  110. 'scheme' => 'https'
  111. , 'host' => 'www.cakephp.org'
  112. , 'port' => 23
  113. ),
  114. 'auth' => array(
  115. 'method' => 'basic'
  116. , 'user' => 'bob'
  117. , 'pass' => 'secret'
  118. ),
  119. 'cookies' => array(),
  120. )
  121. );
  122. $this->assertIdentical($this->Socket->config, $expected);
  123. $this->assertIdentical($r, $expected);
  124. $r = $this->Socket->configUri(array('host' => 'www.foo-bar.org'));
  125. $expected['host'] = 'www.foo-bar.org';
  126. $expected['request']['uri']['host'] = 'www.foo-bar.org';
  127. $this->assertIdentical($this->Socket->config, $expected);
  128. $this->assertIdentical($r, $expected);
  129. $r = $this->Socket->configUri('http://www.foo.com');
  130. $expected = array(
  131. 'persistent' => false,
  132. 'host' => 'www.foo.com',
  133. 'protocol' => 'tcp',
  134. 'port' => 80,
  135. 'timeout' => 30,
  136. 'request' => array(
  137. 'uri' => array(
  138. 'scheme' => 'http'
  139. , 'host' => 'www.foo.com'
  140. , 'port' => 80
  141. ),
  142. 'auth' => array(
  143. 'method' => 'basic'
  144. , 'user' => null
  145. , 'pass' => null
  146. ),
  147. 'cookies' => array()
  148. )
  149. );
  150. $this->assertIdentical($this->Socket->config, $expected);
  151. $this->assertIdentical($r, $expected);
  152. $r = $this->Socket->configUri('/this-is-broken');
  153. $this->assertIdentical($this->Socket->config, $expected);
  154. $this->assertIdentical($r, false);
  155. $r = $this->Socket->configUri(false);
  156. $this->assertIdentical($this->Socket->config, $expected);
  157. $this->assertIdentical($r, false);
  158. }
  159. /**
  160. * Tests that HttpSocket::request (the heart of the HttpSocket) is working properly.
  161. *
  162. */
  163. function testRequest() {
  164. $this->Socket->reset();
  165. $this->Socket->reset();
  166. $response = $this->Socket->request(true);
  167. $this->assertFalse($response);
  168. $tests = array(
  169. 0 => array(
  170. 'request' => 'http://www.cakephp.org/?foo=bar'
  171. , 'expectation' => array(
  172. 'config' => array(
  173. 'persistent' => false
  174. , 'host' => 'www.cakephp.org'
  175. , 'protocol' => 'tcp'
  176. , 'port' => 80
  177. , 'timeout' => 30
  178. , 'request' => array(
  179. 'uri' => array (
  180. 'scheme' => 'http'
  181. , 'host' => 'www.cakephp.org'
  182. , 'port' => 80,
  183. )
  184. , 'auth' => array(
  185. 'method' => 'basic'
  186. ,'user' => null
  187. ,'pass' => null
  188. ),
  189. 'cookies' => array(),
  190. ),
  191. )
  192. , 'request' => array(
  193. 'method' => 'GET'
  194. , 'uri' => array(
  195. 'scheme' => 'http'
  196. , 'host' => 'www.cakephp.org'
  197. , 'port' => 80
  198. , 'user' => null
  199. , 'pass' => null
  200. , 'path' => '/'
  201. , 'query' => array('foo' => 'bar')
  202. , 'fragment' => null
  203. )
  204. , 'auth' => array(
  205. 'method' => 'basic'
  206. , 'user' => null
  207. , 'pass' => null
  208. )
  209. , 'version' => '1.1'
  210. , 'body' => ''
  211. , 'line' => "GET /?foo=bar HTTP/1.1\r\n"
  212. , 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n"
  213. , 'raw' => ""
  214. , 'cookies' => array(),
  215. )
  216. )
  217. )
  218. , 1 => array(
  219. 'request' => array(
  220. 'uri' => array(
  221. 'host' => 'www.cakephp.org'
  222. , 'query' => '?foo=bar'
  223. )
  224. )
  225. )
  226. , 2 => array(
  227. 'request' => 'www.cakephp.org/?foo=bar'
  228. )
  229. , 3 => array(
  230. 'request' => array('host' => '192.168.0.1', 'uri' => 'http://www.cakephp.org/?foo=bar')
  231. , 'expectation' => array(
  232. 'request' => array(
  233. 'uri' => array('host' => 'www.cakephp.org')
  234. )
  235. , 'config' => array(
  236. 'request' => array(
  237. 'uri' => array('host' => 'www.cakephp.org')
  238. )
  239. , 'host' => '192.168.0.1'
  240. )
  241. )
  242. )
  243. , 'reset4' => array(
  244. 'request.uri.query' => array()
  245. )
  246. , 4 => array(
  247. 'request' => array('header' => array('Foo@woo' => 'bar-value'))
  248. , 'expectation' => array(
  249. 'request' => array(
  250. 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nFoo\"@\"woo: bar-value\r\n"
  251. , 'line' => "GET / HTTP/1.1\r\n"
  252. )
  253. )
  254. )
  255. , 5 => array(
  256. 'request' => array('header' => array('Foo@woo' => 'bar-value', 'host' => 'foo.com'), 'uri' => 'http://www.cakephp.org/')
  257. , 'expectation' => array(
  258. 'request' => array(
  259. 'header' => "Host: foo.com\r\nConnection: close\r\nUser-Agent: CakePHP\r\nFoo\"@\"woo: bar-value\r\n"
  260. )
  261. , 'config' => array(
  262. 'host' => 'www.cakephp.org'
  263. )
  264. )
  265. )
  266. , 6 => array(
  267. 'request' => array('header' => "Foo: bar\r\n")
  268. , 'expectation' => array(
  269. 'request' => array(
  270. 'header' => "Foo: bar\r\n"
  271. )
  272. )
  273. )
  274. , 7 => array(
  275. 'request' => array('header' => "Foo: bar\r\n", 'uri' => 'http://www.cakephp.org/search?q=http_socket#ignore-me')
  276. , 'expectation' => array(
  277. 'request' => array(
  278. 'uri' => array(
  279. 'path' => '/search'
  280. , 'query' => array('q' => 'http_socket')
  281. , 'fragment' => 'ignore-me'
  282. )
  283. , 'line' => "GET /search?q=http_socket HTTP/1.1\r\n"
  284. )
  285. )
  286. )
  287. , 'reset8' => array(
  288. 'request.uri.query' => array()
  289. )
  290. , 8 => array(
  291. 'request' => array('method' => 'POST', 'uri' => 'http://www.cakephp.org/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'))
  292. , 'expectation' => array(
  293. 'request' => array(
  294. 'method' => 'POST'
  295. , 'uri' => array(
  296. 'path' => '/posts/add'
  297. , 'fragment' => null
  298. )
  299. , 'body' => "name=HttpSocket-is-released&date=today"
  300. , 'line' => "POST /posts/add HTTP/1.1\r\n"
  301. , 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\n"
  302. , 'raw' => "name=HttpSocket-is-released&date=today"
  303. )
  304. )
  305. )
  306. , 9 => array(
  307. 'request' => array('method' => 'POST', 'uri' => 'https://www.cakephp.org/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'))
  308. , 'expectation' => array(
  309. 'config' => array(
  310. 'port' => 443
  311. , 'request' => array(
  312. 'uri' => array(
  313. 'scheme' => 'https'
  314. , 'port' => 443
  315. )
  316. )
  317. )
  318. , 'request' => array(
  319. 'uri' => array(
  320. 'scheme' => 'https'
  321. , 'port' => 443
  322. )
  323. )
  324. )
  325. )
  326. , 10 => array(
  327. 'request' => array(
  328. 'method' => 'POST',
  329. 'uri' => 'https://www.cakephp.org/posts/add',
  330. 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'),
  331. 'cookies' => array('foo' => array('value' => 'bar'))
  332. )
  333. , 'expectation' => array(
  334. 'request' => array(
  335. 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\nCookie: foo=bar\r\n",
  336. 'cookies' => array(
  337. 'foo' => array('value' => 'bar'),
  338. )
  339. )
  340. )
  341. )
  342. );
  343. $expectation = array();
  344. foreach ($tests as $i => $test) {
  345. if (strpos($i, 'reset') === 0) {
  346. foreach ($test as $path => $val) {
  347. $expectation = Set::insert($expectation, $path, $val);
  348. }
  349. continue;
  350. }
  351. if (isset($test['expectation'])) {
  352. $expectation = Set::merge($expectation, $test['expectation']);
  353. }
  354. $this->Socket->request($test['request']);
  355. $raw = $expectation['request']['raw'];
  356. $expectation['request']['raw'] = $expectation['request']['line'].$expectation['request']['header']."\r\n".$raw;
  357. $r = array('config' => $this->Socket->config, 'request' => $this->Socket->request);
  358. $v = $this->assertIdentical($r, $expectation, '%s in test #'.$i.' ');
  359. if (!$v) {
  360. debug('Result:');
  361. debug($r);
  362. debug('Expected:');
  363. debug($expectation);
  364. }
  365. $expectation['request']['raw'] = $raw;
  366. }
  367. $this->Socket->reset();
  368. $request = array('method' => 'POST', 'uri' => 'http://www.cakephp.org/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'));
  369. $response = $this->Socket->request($request);
  370. $this->assertIdentical($this->Socket->request['body'], "name=HttpSocket-is-released&date=today");
  371. $request = array('uri' => '*', 'method' => 'GET');
  372. $this->expectError(new PatternExpectation('/activate quirks mode/i'));
  373. $response = $this->Socket->request($request);
  374. $this->assertFalse($response);
  375. $this->assertFalse($this->Socket->response);
  376. $this->Socket->reset();
  377. $request = array('uri' => 'htpp://www.cakephp.org/');
  378. $this->Socket->setReturnValue('connect', true);
  379. $this->Socket->setReturnValue('read', false);
  380. $this->Socket->_mock->_call_counts['read'] = 0;
  381. $number = mt_rand(0, 9999999);
  382. $serverResponse = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>Hello, your lucky number is ".$number."</h1>";
  383. $this->Socket->setReturnValueAt(0, 'read', $serverResponse);
  384. $this->Socket->expect('write', array("GET / HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n\r\n"));
  385. $this->Socket->expectCallCount('read', 2);
  386. $response = $this->Socket->request($request);
  387. $this->assertIdentical($response, "<h1>Hello, your lucky number is ".$number."</h1>");
  388. $this->Socket->reset();
  389. $serverResponse = "HTTP/1.x 200 OK\r\nSet-Cookie: foo=bar\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a cookie test!</h1>";
  390. unset($this->Socket->_mock->_actions->_at['read']);
  391. $this->Socket->_mock->_call_counts['read'] = 0;
  392. $this->Socket->setReturnValueAt(0, 'read', $serverResponse);
  393. $this->Socket->connected = true;
  394. $this->Socket->request($request);
  395. $result = $this->Socket->response['cookies'];
  396. $expect = array(
  397. 'foo' => array(
  398. 'value' => 'bar'
  399. )
  400. );
  401. $this->assertEqual($result, $expect);
  402. $this->assertEqual($this->Socket->config['request']['cookies'], $expect);
  403. $this->assertFalse($this->Socket->connected);
  404. }
  405. /**
  406. * testUrl method
  407. *
  408. * @access public
  409. * @return void
  410. */
  411. function testUrl() {
  412. $this->Socket->reset(true);
  413. $this->assertIdentical($this->Socket->url(true), false);
  414. $url = $this->Socket->url('www.cakephp.org');
  415. $this->assertIdentical($url, 'http://www.cakephp.org/');
  416. $url = $this->Socket->url('https://www.cakephp.org/posts/add');
  417. $this->assertIdentical($url, 'https://www.cakephp.org/posts/add');
  418. $url = $this->Socket->url('http://www.cakephp/search?q=socket', '/%path?%query');
  419. $this->assertIdentical($url, '/search?q=socket');
  420. $this->Socket->config['request']['uri']['host'] = 'bakery.cakephp.org';
  421. $url = $this->Socket->url();
  422. $this->assertIdentical($url, 'http://bakery.cakephp.org/');
  423. $this->Socket->configUri('http://www.cakephp.org');
  424. $url = $this->Socket->url('/search?q=bar');
  425. $this->assertIdentical($url, 'http://www.cakephp.org/search?q=bar');
  426. $url = $this->Socket->url(array('host' => 'www.foobar.org', 'query' => array('q' => 'bar')));
  427. $this->assertIdentical($url, 'http://www.foobar.org/?q=bar');
  428. $url = $this->Socket->url(array('path' => '/supersearch', 'query' => array('q' => 'bar')));
  429. $this->assertIdentical($url, 'http://www.cakephp.org/supersearch?q=bar');
  430. $this->Socket->configUri('http://www.google.com');
  431. $url = $this->Socket->url('/search?q=socket');
  432. $this->assertIdentical($url, 'http://www.google.com/search?q=socket');
  433. $url = $this->Socket->url();
  434. $this->assertIdentical($url, 'http://www.google.com/');
  435. $this->Socket->configUri('https://www.google.com');
  436. $url = $this->Socket->url('/search?q=socket');
  437. $this->assertIdentical($url, 'https://www.google.com/search?q=socket');
  438. $this->Socket->reset();
  439. $this->Socket->configUri('www.google.com:443');
  440. $url = $this->Socket->url('/search?q=socket');
  441. $this->assertIdentical($url, 'https://www.google.com/search?q=socket');
  442. $this->Socket->reset();
  443. $this->Socket->configUri('www.google.com:8080');
  444. $url = $this->Socket->url('/search?q=socket');
  445. $this->assertIdentical($url, 'http://www.google.com:8080/search?q=socket');
  446. }
  447. /**
  448. * testGet method
  449. *
  450. * @access public
  451. * @return void
  452. */
  453. function testGet() {
  454. $this->RequestSocket->reset();
  455. $this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/')));
  456. $this->RequestSocket->get('http://www.google.com/');
  457. $this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=bar')));
  458. $this->RequestSocket->get('http://www.google.com/', array('foo' => 'bar'));
  459. $this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=bar')));
  460. $this->RequestSocket->get('http://www.google.com/', 'foo=bar');
  461. $this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=23&foobar=42')));
  462. $this->RequestSocket->get('http://www.google.com/?foo=bar', array('foobar' => '42', 'foo' => '23'));
  463. $this->RequestSocket->expect('request', a(array('method' => 'GET', 'uri' => 'http://www.google.com/', 'auth' => array('user' => 'foo', 'pass' => 'bar'))));
  464. $this->RequestSocket->get('http://www.google.com/', null, array('auth' => array('user' => 'foo', 'pass' => 'bar')));
  465. }
  466. /**
  467. * testPostPutDelete method
  468. *
  469. * @access public
  470. * @return void
  471. */
  472. function testPostPutDelete() {
  473. $this->RequestSocket->reset();
  474. foreach (array('POST', 'PUT', 'DELETE') as $method) {
  475. $this->RequestSocket->expect('request', a(array('method' => $method, 'uri' => 'http://www.google.com/', 'body' => array())));
  476. $this->RequestSocket->{low($method)}('http://www.google.com/');
  477. $this->RequestSocket->expect('request', a(array('method' => $method, 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar'))));
  478. $this->RequestSocket->{low($method)}('http://www.google.com/', array('Foo' => 'bar'));
  479. $this->RequestSocket->expect('request', a(array('method' => $method, 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server')));
  480. $this->RequestSocket->{low($method)}('http://www.google.com/', null, array('line' => 'Hey Server'));
  481. }
  482. }
  483. /**
  484. * Enter description here...
  485. *
  486. */
  487. function testParseResponse() {
  488. $this->Socket->reset();
  489. $r = $this->Socket->parseResponse(array('foo' => 'bar'));
  490. $this->assertIdentical($r, array('foo' => 'bar'));
  491. $r = $this->Socket->parseResponse(true);
  492. $this->assertIdentical($r, false);
  493. $r = $this->Socket->parseResponse("HTTP Foo\r\nBar: La");
  494. $this->assertIdentical($r, false);
  495. $tests = array(
  496. 'simple-request' => array(
  497. 'response' => array(
  498. 'status-line' => "HTTP/1.x 200 OK\r\n",
  499. 'header' => "Date: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\n",
  500. 'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
  501. )
  502. , 'expectations' => array(
  503. 'status.http-version' => 'HTTP/1.x',
  504. 'status.code' => 200,
  505. 'status.reason-phrase' => 'OK',
  506. 'header' => $this->Socket->parseHeader("Date: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\n"),
  507. 'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
  508. )
  509. ),
  510. 'no-header' => array(
  511. 'response' => array(
  512. 'status-line' => "HTTP/1.x 404 OK\r\n",
  513. 'header' => null,
  514. )
  515. , 'expectations' => array(
  516. 'status.code' => 404,
  517. 'header' => array()
  518. )
  519. ),
  520. 'chunked' => array(
  521. 'response' => array(
  522. 'header' => "Transfer-Encoding: chunked\r\n",
  523. 'body' => "19\r\nThis is a chunked message\r\n0\r\n"
  524. ),
  525. 'expectations' => array(
  526. 'body' => "This is a chunked message",
  527. 'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\n")
  528. )
  529. ),
  530. 'enitity-header' => array(
  531. 'response' => array(
  532. 'body' => "19\r\nThis is a chunked message\r\n0\r\nFoo: Bar\r\n"
  533. ),
  534. 'expectations' => array(
  535. 'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\nFoo: Bar\r\n")
  536. )
  537. ),
  538. 'enitity-header-combine' => array(
  539. 'response' => array(
  540. 'header' => "Transfer-Encoding: chunked\r\nFoo: Foobar\r\n"
  541. ),
  542. 'expectations' => array(
  543. 'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\nFoo: Foobar\r\nFoo: Bar\r\n")
  544. )
  545. )
  546. );
  547. $testResponse = array();
  548. $expectations = array();
  549. foreach ($tests as $name => $test) {
  550. $testResponse = array_merge($testResponse, $test['response']);
  551. $testResponse['response'] = $testResponse['status-line'].$testResponse['header']."\r\n".$testResponse['body'];
  552. $r = $this->Socket->parseResponse($testResponse['response']);
  553. $expectations = array_merge($expectations, $test['expectations']);
  554. foreach ($expectations as $property => $expectedVal) {
  555. $val = Set::extract($r, $property);
  556. $this->assertIdentical($val, $expectedVal, 'Test "'.$name.'": response.'.$property.' - %s');
  557. }
  558. foreach (array('status-line', 'header', 'body', 'response') as $field) {
  559. $this->assertIdentical($r['raw'][$field], $testResponse[$field], 'Test response.raw.'.$field.': %s');
  560. }
  561. }
  562. }
  563. /**
  564. * Enter description here...
  565. *
  566. */
  567. function testDecodeBody() {
  568. $this->Socket->reset();
  569. $r = $this->Socket->decodeBody(true);
  570. $this->assertIdentical($r, false);
  571. $r = $this->Socket->decodeBody('Foobar', false);
  572. $this->assertIdentical($r, array('body' => 'Foobar', 'header' => false));
  573. $encodings = array(
  574. 'chunked' => array(
  575. 'encoded' => "19\r\nThis is a chunked message\r\n0\r\n",
  576. 'decoded' => array('body' => "This is a chunked message", 'header' => false)
  577. ),
  578. 'foo-coded' => array(
  579. 'encoded' => '!Foobar!',
  580. 'decoded' => array('body' => '!Foobar!', 'header' => false),
  581. 'error' => new PatternExpectation('/unknown encoding: foo-coded/i')
  582. )
  583. );
  584. foreach ($encodings as $encoding => $sample) {
  585. if (isset($sample['error'])) {
  586. $this->expectError($sample['error']);
  587. }
  588. $r = $this->Socket->decodeBody($sample['encoded'], $encoding);
  589. $this->assertIdentical($r, $sample['decoded']);
  590. if (isset($sample['error'])) {
  591. $this->Socket->quirksMode = true;
  592. $r = $this->Socket->decodeBody($sample['encoded'], $encoding);
  593. $this->assertIdentical($r, $sample['decoded']);
  594. $this->Socket->quirksMode = false;
  595. }
  596. }
  597. }
  598. /**
  599. * Enter description here...
  600. *
  601. */
  602. function testDecodeChunkedBody() {
  603. $this->Socket->reset();
  604. $r = $this->Socket->decodeChunkedBody(true);
  605. $this->assertIdentical($r, false);
  606. $encoded = "19\r\nThis is a chunked message\r\n0\r\n";
  607. $decoded = "This is a chunked message";
  608. $r = $this->Socket->decodeChunkedBody($encoded);
  609. $this->assertIdentical($r['body'], $decoded);
  610. $this->assertIdentical($r['header'], false);
  611. $encoded = "19 \r\nThis is a chunked message\r\n0\r\n";
  612. $r = $this->Socket->decodeChunkedBody($encoded);
  613. $this->assertIdentical($r['body'], $decoded);
  614. $encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\n";
  615. $decoded = "This is a chunked message\nThat is cool\n";
  616. $r = $this->Socket->decodeChunkedBody($encoded);
  617. $this->assertIdentical($r['body'], $decoded);
  618. $this->assertIdentical($r['header'], false);
  619. $encoded = "19\r\nThis is a chunked message\r\nE;foo-chunk=5\r\n\nThat is cool\n\r\n0\r\n";
  620. $r = $this->Socket->decodeChunkedBody($encoded);
  621. $this->assertIdentical($r['body'], $decoded);
  622. $this->assertIdentical($r['header'], false);
  623. $encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\nfoo-header: bar\r\ncake: PHP\r\n\r\n";
  624. $r = $this->Socket->decodeChunkedBody($encoded);
  625. $this->assertIdentical($r['body'], $decoded);
  626. $this->assertIdentical($r['header'], array('Foo-Header' => 'bar', 'Cake' => 'PHP'));
  627. $encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n";
  628. $this->expectError(new PatternExpectation('/activate quirks mode/i'));
  629. $r = $this->Socket->decodeChunkedBody($encoded);
  630. $this->assertIdentical($r, false);
  631. $this->Socket->quirksMode = true;
  632. $r = $this->Socket->decodeChunkedBody($encoded);
  633. $this->assertIdentical($r['body'], $decoded);
  634. $this->assertIdentical($r['header'], false);
  635. $encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\nfoo-header: bar\r\ncake: PHP\r\n\r\n";
  636. $r = $this->Socket->decodeChunkedBody($encoded);
  637. $this->assertIdentical($r['body'], $decoded);
  638. $this->assertIdentical($r['header'], array('Foo-Header' => 'bar', 'Cake' => 'PHP'));
  639. }
  640. /**
  641. * testBuildRequestLine method
  642. *
  643. * @access public
  644. * @return void
  645. */
  646. function testBuildRequestLine() {
  647. $this->Socket->reset();
  648. $this->expectError(new PatternExpectation('/activate quirks mode/i'));
  649. $r = $this->Socket->buildRequestLine('Foo');
  650. $this->assertIdentical($r, false);
  651. $this->Socket->quirksMode = true;
  652. $r = $this->Socket->buildRequestLine('Foo');
  653. $this->assertIdentical($r, 'Foo');
  654. $this->Socket->quirksMode = false;
  655. $r = $this->Socket->buildRequestLine(true);
  656. $this->assertIdentical($r, false);
  657. $r = $this->Socket->buildRequestLine(array('foo' => 'bar', 'method' => 'foo'));
  658. $this->assertIdentical($r, false);
  659. $r = $this->Socket->buildRequestLine(array('method' => 'GET', 'uri' => 'http://www.cakephp.org/search?q=socket'));
  660. $this->assertIdentical($r, "GET /search?q=socket HTTP/1.1\r\n");
  661. $request = array(
  662. 'method' => 'GET',
  663. 'uri' => array(
  664. 'path' => '/search',
  665. 'query' => array('q' => 'socket')
  666. )
  667. );
  668. $r = $this->Socket->buildRequestLine($request);
  669. $this->assertIdentical($r, "GET /search?q=socket HTTP/1.1\r\n");
  670. unset($request['method']);
  671. $r = $this->Socket->buildRequestLine($request);
  672. $this->assertIdentical($r, "GET /search?q=socket HTTP/1.1\r\n");
  673. $r = $this->Socket->buildRequestLine($request, 'CAKE-HTTP/0.1');
  674. $this->assertIdentical($r, "GET /search?q=socket CAKE-HTTP/0.1\r\n");
  675. $request = array('method' => 'OPTIONS', 'uri' => '*');
  676. $r = $this->Socket->buildRequestLine($request);
  677. $this->assertIdentical($r, "OPTIONS * HTTP/1.1\r\n");
  678. $request['method'] = 'GET';
  679. $this->expectError(new PatternExpectation('/activate quirks mode/i'));
  680. $r = $this->Socket->buildRequestLine($request);
  681. $this->assertIdentical($r, false);
  682. $this->expectError(new PatternExpectation('/activate quirks mode/i'));
  683. $r = $this->Socket->buildRequestLine("GET * HTTP/1.1\r\n");
  684. $this->assertIdentical($r, false);
  685. $this->Socket->quirksMode = true;
  686. $r = $this->Socket->buildRequestLine($request);
  687. $this->assertIdentical($r, "GET * HTTP/1.1\r\n");
  688. $r = $this->Socket->buildRequestLine("GET * HTTP/1.1\r\n");
  689. $this->assertIdentical($r, "GET * HTTP/1.1\r\n");
  690. }
  691. /**
  692. * Asserts that HttpSocket::parseUri is working properly
  693. *
  694. */
  695. function testParseUri() {
  696. $this->Socket->reset();
  697. $uri = $this->Socket->parseUri(array('invalid' => 'uri-string'));
  698. $this->assertIdentical($uri, false);
  699. $uri = $this->Socket->parseUri(array('invalid' => 'uri-string'), array('host' => 'somehost'));
  700. $this->assertIdentical($uri, array('host' => 'somehost', 'invalid' => 'uri-string'));
  701. $uri = $this->Socket->parseUri(false);
  702. $this->assertIdentical($uri, false);
  703. $uri = $this->Socket->parseUri('/my-cool-path');
  704. $this->assertIdentical($uri, array('path' => '/my-cool-path'));
  705. $uri = $this->Socket->parseUri('http://bob:foo123@www.cakephp.org:40/search?q=dessert#results');
  706. $this->assertIdentical($uri, array(
  707. 'scheme' => 'http',
  708. 'host' => 'www.cakephp.org',
  709. 'port' => 40,
  710. 'user' => 'bob',
  711. 'pass' => 'foo123',
  712. 'path' => '/search',
  713. 'query' => array('q' => 'dessert'),
  714. 'fragment' => 'results'
  715. ));
  716. $uri = $this->Socket->parseUri('http://www.cakephp.org/');
  717. $this->assertIdentical($uri, array(
  718. 'scheme' => 'http',
  719. 'host' => 'www.cakephp.org',
  720. 'path' => '/',
  721. ));
  722. $uri = $this->Socket->parseUri('http://www.cakephp.org', true);
  723. $this->assertIdentical($uri, array(
  724. 'scheme' => 'http',
  725. 'host' => 'www.cakephp.org',
  726. 'port' => 80,
  727. 'user' => null,
  728. 'pass' => null,
  729. 'path' => '/',
  730. 'query' => array(),
  731. 'fragment' => null
  732. ));
  733. $uri = $this->Socket->parseUri('https://www.cakephp.org', true);
  734. $this->assertIdentical($uri, array(
  735. 'scheme' => 'https',
  736. 'host' => 'www.cakephp.org',
  737. 'port' => 443,
  738. 'user' => null,
  739. 'pass' => null,
  740. 'path' => '/',
  741. 'query' => array(),
  742. 'fragment' => null
  743. ));
  744. $uri = $this->Socket->parseUri('www.cakephp.org:443/query?foo', true);
  745. $this->assertIdentical($uri, array(
  746. 'scheme' => 'https',
  747. 'host' => 'www.cakephp.org',
  748. 'port' => 443,
  749. 'user' => null,
  750. 'pass' => null,
  751. 'path' => '/query',
  752. 'query' => array('foo' => ""),
  753. 'fragment' => null
  754. ));
  755. $uri = $this->Socket->parseUri('http://www.cakephp.org', array('host' => 'piephp.org', 'user' => 'bob', 'fragment' => 'results'));
  756. $this->assertIdentical($uri, array(
  757. 'host' => 'www.cakephp.org',
  758. 'user' => 'bob',
  759. 'fragment' => 'results',
  760. 'scheme' => 'http'
  761. ));
  762. $uri = $this->Socket->parseUri('https://www.cakephp.org', array('scheme' => 'http', 'port' => 23));
  763. $this->assertIdentical($uri, array(
  764. 'scheme' => 'https',
  765. 'port' => 23,
  766. 'host' => 'www.cakephp.org'
  767. ));
  768. $uri = $this->Socket->parseUri('www.cakephp.org:59', array('scheme' => array('http', 'https'), 'port' => 80));
  769. $this->assertIdentical($uri, array(
  770. 'scheme' => 'http',
  771. 'port' => 59,
  772. 'host' => 'www.cakephp.org'
  773. ));
  774. $uri = $this->Socket->parseUri(array('scheme' => 'http', 'host' => 'www.google.com', 'port' => 8080), array('scheme' => array('http', 'https'), 'host' => 'www.google.com', 'port' => array(80, 443)));
  775. $this->assertIdentical($uri, array(
  776. 'scheme' => 'http',
  777. 'host' => 'www.google.com',
  778. 'port' => 8080,
  779. ));
  780. }
  781. /**
  782. * Tests that HttpSocket::buildUri can turn all kinds of uri arrays (and strings) into fully or partially qualified URI's
  783. *
  784. */
  785. function testBuildUri() {
  786. $this->Socket->reset();
  787. $r = $this->Socket->buildUri(true);
  788. $this->assertIdentical($r, false);
  789. $r = $this->Socket->buildUri('foo.com');
  790. $this->assertIdentical($r, 'http://foo.com/');
  791. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org'));
  792. $this->assertIdentical($r, 'http://www.cakephp.org/');
  793. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'scheme' => 'https'));
  794. $this->assertIdentical($r, 'https://www.cakephp.org/');
  795. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'port' => 23));
  796. $this->assertIdentical($r, 'http://www.cakephp.org:23/');
  797. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'scheme' => 'https', 'port' => 79));
  798. $this->assertIdentical($r, 'https://www.cakephp.org:79/');
  799. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => 'foo'));
  800. $this->assertIdentical($r, 'http://www.cakephp.org/foo');
  801. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => '/foo'));
  802. $this->assertIdentical($r, 'http://www.cakephp.org/foo');
  803. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => '/search', 'query' => array('q' => 'HttpSocket')));
  804. $this->assertIdentical($r, 'http://www.cakephp.org/search?q=HttpSocket');
  805. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'fragment' => 'bar'));
  806. $this->assertIdentical($r, 'http://www.cakephp.org/#bar');
  807. $r = $this->Socket->buildUri(array(
  808. 'scheme' => 'https',
  809. 'host' => 'www.cakephp.org',
  810. 'port' => 25,
  811. 'user' => 'bob',
  812. 'pass' => 'secret',
  813. 'path' => '/cool',
  814. 'query' => array('foo' => 'bar'),
  815. 'fragment' => 'comment'
  816. ));
  817. $this->assertIdentical($r, 'https://bob:secret@www.cakephp.org:25/cool?foo=bar#comment');
  818. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'fragment' => 'bar'), '%fragment?%host');
  819. $this->assertIdentical($r, 'bar?www.cakephp.org');
  820. $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org'), '%fragment???%host');
  821. $this->assertIdentical($r, '???www.cakephp.org');
  822. $r = $this->Socket->buildUri(array('path' => '*'), '/%path?%query');
  823. $this->assertIdentical($r, '*');
  824. $r = $this->Socket->buildUri(array('scheme' => 'foo', 'host' => 'www.cakephp.org'));
  825. $this->assertIdentical($r, 'foo://www.cakephp.org:80/');
  826. }
  827. /**
  828. * Asserts that HttpSocket::parseQuery is working properly
  829. *
  830. */
  831. function testParseQuery() {
  832. $this->Socket->reset();
  833. $query = $this->Socket->parseQuery(array('framework' => 'cakephp'));
  834. $this->assertIdentical($query, array('framework' => 'cakephp'));
  835. $query = $this->Socket->parseQuery('');
  836. $this->assertIdentical($query, array());
  837. $query = $this->Socket->parseQuery('framework=cakephp');
  838. $this->assertIdentical($query, array('framework' => 'cakephp'));
  839. $query = $this->Socket->parseQuery('?framework=cakephp');
  840. $this->assertIdentical($query, array('framework' => 'cakephp'));
  841. $query = $this->Socket->parseQuery('a&b&c');
  842. $this->assertIdentical($query, array('a' => '', 'b' => '', 'c' => ''));
  843. $query = $this->Socket->parseQuery('value=12345');
  844. $this->assertIdentical($query, array('value' => '12345'));
  845. $query = $this->Socket->parseQuery('a[0]=foo&a[1]=bar&a[2]=cake');
  846. $this->assertIdentical($query, array('a' => array(0 => 'foo', 1 => 'bar', 2 => 'cake')));
  847. $query = $this->Socket->parseQuery('a[]=foo&a[]=bar&a[]=cake');
  848. $this->assertIdentical($query, array('a' => array(0 => 'foo', 1 => 'bar', 2 => 'cake')));
  849. $query = $this->Socket->parseQuery('a]][[=foo&[]=bar&]]][]=cake');
  850. $this->assertIdentical($query, array('a]][[' => 'foo', 0 => 'bar', ']]]' => array('cake')));
  851. $query = $this->Socket->parseQuery('a[][]=foo&a[][]=bar&a[][]=cake');
  852. $expectedQuery = array(
  853. 'a' => array(
  854. 0 => array(
  855. 0 => 'foo'
  856. ),
  857. 1 => array(
  858. 0 => 'bar'
  859. ),
  860. array(
  861. 0 => 'cake'
  862. )
  863. )
  864. );
  865. $this->assertIdentical($query, $expectedQuery);
  866. $query = $this->Socket->parseQuery('a[][]=foo&a[bar]=php&a[][]=bar&a[][]=cake');
  867. $expectedQuery = array(
  868. 'a' => array(
  869. 0 => array(
  870. 0 => 'foo'
  871. ),
  872. 'bar' => 'php',
  873. 1 => array(
  874. 0 => 'bar'
  875. ),
  876. array(
  877. 0 => 'cake'
  878. )
  879. )
  880. );
  881. $this->assertIdentical($query, $expectedQuery);
  882. $query = $this->Socket->parseQuery('user[]=jim&user[3]=tom&user[]=bob');
  883. $expectedQuery = array(
  884. 'user' => array(
  885. 0 => 'jim',
  886. 3 => 'tom',
  887. 4 => 'bob'
  888. )
  889. );
  890. $this->assertIdentical($query, $expectedQuery);
  891. $queryStr = 'user[0]=foo&user[0][items][]=foo&user[0][items][]=bar&user[][name]=jim&user[1][items][personal][]=book&user[1][items][personal][]=pen&user[1][items][]=ball&user[count]=2&empty';
  892. $query = $this->Socket->parseQuery($queryStr);
  893. $expectedQuery = array(
  894. 'user' => array(
  895. 0 => array(
  896. 'items' => array(
  897. 'foo',
  898. 'bar'
  899. )
  900. ),
  901. 1 => array(
  902. 'name' => 'jim',
  903. 'items' => array(
  904. 'personal' => array(
  905. 'book'
  906. , 'pen'
  907. ),
  908. 'ball'
  909. )
  910. ),
  911. 'count' => '2'
  912. ),
  913. 'empty' => ''
  914. );
  915. $this->assertIdentical($query, $expectedQuery);
  916. }
  917. /**
  918. * Tests that HttpSocket::buildHeader can turn a given $header array into a proper header string according to
  919. * HTTP 1.1 specs.
  920. *
  921. */
  922. function testBuildHeader() {
  923. $this->Socket->reset();
  924. $r = $this->Socket->buildHeader(true);
  925. $this->assertIdentical($r, false);
  926. $r = $this->Socket->buildHeader('My raw header');
  927. $this->assertIdentical($r, 'My raw header');
  928. $r = $this->Socket->buildHeader(array('Host' => 'www.cakephp.org'));
  929. $this->assertIdentical($r, "Host: www.cakephp.org\r\n");
  930. $r = $this->Socket->buildHeader(array('Host' => 'www.cakephp.org', 'Connection' => 'Close'));
  931. $this->assertIdentical($r, "Host: www.cakephp.org\r\nConnection: Close\r\n");
  932. $r = $this->Socket->buildHeader(array('People' => array('Bob', 'Jim', 'John')));
  933. $this->assertIdentical($r, "People: Bob,Jim,John\r\n");
  934. $r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\nMulti Line field"));
  935. $this->assertIdentical($r, "Multi-Line-Field: This is my\r\n Multi Line field\r\n");
  936. $r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\n Multi Line field"));
  937. $this->assertIdentical($r, "Multi-Line-Field: This is my\r\n Multi Line field\r\n");
  938. $r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\n\tMulti Line field"));
  939. $this->assertIdentical($r, "Multi-Line-Field: This is my\r\n\tMulti Line field\r\n");
  940. $r = $this->Socket->buildHeader(array('Test@Field' => "My value"));
  941. $this->assertIdentical($r, "Test\"@\"Field: My value\r\n");
  942. }
  943. /**
  944. * Test that HttpSocket::parseHeader can take apart a given (and valid) $header string and turn it into an array.
  945. *
  946. */
  947. function testParseHeader() {
  948. $this->Socket->reset();
  949. $r = $this->Socket->parseHeader(array('foo' => 'Bar', 'fOO-bAr' => 'quux'));
  950. $this->assertIdentical($r, array('Foo' => 'Bar', 'Foo-Bar' => 'quux'));
  951. $r = $this->Socket->parseHeader(true);
  952. $this->assertIdentical($r, false);
  953. $header = "Host: cakephp.org\t\r\n";
  954. $r = $this->Socket->parseHeader($header);
  955. $expected = array(
  956. 'Host' => 'cakephp.org'
  957. );
  958. $this->assertIdentical($r, $expected);
  959. $header = "Date:Sat, 07 Apr 2007 10:10:25 GMT\r\nX-Powered-By: PHP/5.1.2\r\n";
  960. $r = $this->Socket->parseHeader($header);
  961. $expected = array(
  962. 'Date' => 'Sat, 07 Apr 2007 10:10:25 GMT'
  963. , 'X-Powered-By' => 'PHP/5.1.2'
  964. );
  965. $this->assertIdentical($r, $expected);
  966. $header = "people: Jim,John\r\nfoo-LAND: Bar\r\ncAKe-PHP: rocks\r\n";
  967. $r = $this->Socket->parseHeader($header);
  968. $expected = array(
  969. 'People' => 'Jim,John'
  970. , 'Foo-Land' => 'Bar'
  971. , 'Cake-Php' => 'rocks'
  972. );
  973. $this->assertIdentical($r, $expected);
  974. $header = "People: Jim,John,Tim\r\nPeople: Lisa,Tina,Chelsea\r\n";
  975. $r = $this->Socket->parseHeader($header);
  976. $expected = array(
  977. 'People' => array('Jim,John,Tim', 'Lisa,Tina,Chelsea')
  978. );
  979. $this->assertIdentical($r, $expected);
  980. $header = "Multi-Line: I am a \r\nmulti line\t\r\nfield value.\r\nSingle-Line: I am not\r\n";
  981. $r = $this->Socket->parseHeader($header);
  982. $expected = array(
  983. 'Multi-Line' => "I am a\r\nmulti line\r\nfield value."
  984. , 'Single-Line' => 'I am not'
  985. );
  986. $this->assertIdentical($r, $expected);
  987. $header = "Esc\"@\"ped: value\r\n";
  988. $r = $this->Socket->parseHeader($header);
  989. $expected = array(
  990. 'Esc@ped' => 'value'
  991. );
  992. $this->assertIdentical($r, $expected);
  993. }
  994. /**
  995. * undocumented function
  996. *
  997. * @return void
  998. * @access public
  999. */
  1000. function testParseCookies() {
  1001. $header = array(
  1002. 'Set-Cookie' => array(
  1003. 'foo=bar',
  1004. 'people=jim,jack,johnny";";Path=/accounts'
  1005. ),
  1006. 'Transfer-Encoding' => 'chunked',
  1007. 'Date' => 'Sun, 18 Nov 2007 18:57:42 GMT',
  1008. );
  1009. $cookies = $this->Socket->parseCookies($header);
  1010. $expected = array(
  1011. 'foo' => array(
  1012. 'value' => 'bar'
  1013. ),
  1014. 'people' => array(
  1015. 'value' => 'jim,jack,johnny";"',
  1016. 'path' => '/accounts'
  1017. )
  1018. );
  1019. $this->assertEqual($cookies, $expected);
  1020. $header['Set-Cookie'][] = 'cakephp=great; Secure';
  1021. $expected['cakephp'] = array('value' => 'great', 'secure' => true);
  1022. $cookies = $this->Socket->parseCookies($header);
  1023. $this->assertEqual($cookies, $expected);
  1024. $header['Set-Cookie'] = 'foo=bar';
  1025. unset($expected['people'], $expected['cakephp']);
  1026. $cookies = $this->Socket->parseCookies($header);
  1027. $this->assertEqual($cookies, $expected);
  1028. }
  1029. /**
  1030. * undocumented function
  1031. *
  1032. * @return void
  1033. * @access public
  1034. * @todo Test more scenarios
  1035. */
  1036. function testBuildCookies() {
  1037. $cookies = array(
  1038. 'foo' => array(
  1039. 'value' => 'bar'
  1040. ),
  1041. 'people' => array(
  1042. 'value' => 'jim,jack,johnny;',
  1043. 'path' => '/accounts'
  1044. )
  1045. );
  1046. $expect = "Cookie: foo=bar\r\nCookie: people=jim,jack,johnny\";\"\r\n";
  1047. $result = $this->Socket->buildCookies($cookies);
  1048. $this->assertEqual($result, $expect);
  1049. }
  1050. /**
  1051. * Tests that HttpSocket::__tokenEscapeChars() returns the right characters.
  1052. *
  1053. */
  1054. function testTokenEscapeChars() {
  1055. $this->Socket->reset();
  1056. $expected = array(
  1057. '\x22','\x28','\x29','\x3c','\x3e','\x40','\x2c','\x3b','\x3a','\x5c','\x2f','\x5b','\x5d','\x3f','\x3d','\x7b',
  1058. '\x7d','\x20','\x00','\x01','\x02','\x03','\x04','\x05','\x06','\x07','\x08','\x09','\x0a','\x0b','\x0c','\x0d',
  1059. '\x0e','\x0f','\x10','\x11','\x12','\x13','\x14','\x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1d',
  1060. '\x1e','\x1f','\x7f'
  1061. );
  1062. $r = $this->Socket->__tokenEscapeChars();
  1063. $this->assertEqual($r, $expected);
  1064. foreach ($expected as $key => $char) {
  1065. $expected[$key] = chr(hexdec(substr($char, 2)));
  1066. }
  1067. $r = $this->Socket->__tokenEscapeChars(false);
  1068. $this->assertEqual($r, $expected);
  1069. }
  1070. /**
  1071. * Test that HttpSocket::escapeToken is escaping all characters as descriped in RFC 2616 (HTTP 1.1 specs)
  1072. *
  1073. */
  1074. function testEscapeToken() {
  1075. $this->Socket->reset();
  1076. $this->assertIdentical($this->Socket->escapeToken('Foo'), 'Foo');
  1077. $escape = $this->Socket->__tokenEscapeChars(false);
  1078. foreach ($escape as $char) {
  1079. $token = 'My-special-'.$char.'-Token';
  1080. $escapedToken = $this->Socket->escapeToken($token);
  1081. $expectedToken = 'My-special-"'.$char.'"-Token';
  1082. $this->assertIdentical($escapedToken, $expectedToken, 'Test token escaping for ASCII '.ord($char));
  1083. }
  1084. $token = 'Extreme-:Token- -"@-test';
  1085. $escapedToken = $this->Socket->escapeToken($token);
  1086. $expectedToken = 'Extreme-":"Token-" "-""""@"-test';
  1087. $this->assertIdentical($expectedToken, $escapedToken);
  1088. }
  1089. /**
  1090. * Test that escaped token strings are properly unescaped by HttpSocket::unescapeToken
  1091. *
  1092. */
  1093. function testUnescapeToken() {
  1094. $this->Socket->reset();
  1095. $this->assertIdentical($this->Socket->unescapeToken('Foo'), 'Foo');
  1096. $escape = $this->Socket->__tokenEscapeChars(false);
  1097. foreach ($escape as $char) {
  1098. $token = 'My-special-"'.$char.'"-Token';
  1099. $unescapedToken = $this->Socket->unescapeToken($token);
  1100. $expectedToken = 'My-special-'.$char.'-Token';
  1101. $this->assertIdentical($unescapedToken, $expectedToken, 'Test token unescaping for ASCII '.ord($char));
  1102. }
  1103. $token = 'Extreme-":"Token-" "-""""@"-test';
  1104. $escapedToken = $this->Socket->unescapeToken($token);
  1105. $expectedToken = 'Extreme-:Token- -"@-test';
  1106. $this->assertIdentical($expectedToken, $escapedToken);
  1107. }
  1108. /**
  1109. * This tests asserts HttpSocket::reset() resets a HttpSocket instance to it's initial state (before Object::__construct
  1110. * got executed)
  1111. *
  1112. */
  1113. function testReset() {
  1114. $this->Socket->reset();
  1115. $initialState = get_class_vars('HttpSocket');
  1116. foreach ($initialState as $property => $value) {
  1117. $this->Socket->{$property} = 'Overwritten';
  1118. }
  1119. $return = $this->Socket->reset();
  1120. foreach ($initialState as $property => $value) {
  1121. $this->assertIdentical($this->Socket->{$property}, $value);
  1122. }
  1123. $this->assertIdentical($return, true);
  1124. }
  1125. /**
  1126. * This tests asserts HttpSocket::reset(false) resets certain HttpSocket properties to their initial state (before
  1127. * Object::__construct got executed).
  1128. *
  1129. */
  1130. function testPartialReset() {
  1131. $this->Socket->reset();
  1132. $partialResetProperties = array('request', 'response');
  1133. $initialState = get_class_vars('HttpSocket');
  1134. foreach ($initialState as $property => $value) {
  1135. $this->Socket->{$property} = 'Overwritten';
  1136. }
  1137. $return = $this->Socket->reset(false);
  1138. foreach ($initialState as $property => $originalValue) {
  1139. if (in_array($property, $partialResetProperties)) {
  1140. $this->assertIdentical($this->Socket->{$property}, $originalValue);
  1141. } else {
  1142. $this->assertIdentical($this->Socket->{$property}, 'Overwritten');
  1143. }
  1144. }
  1145. $this->assertIdentical($return, true);
  1146. }
  1147. }
  1148. ?>