PageRenderTime 38ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

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

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