PageRenderTime 163ms CodeModel.GetById 33ms RepoModel.GetById 2ms app.codeStats 0ms

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

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