PageRenderTime 10ms CodeModel.GetById 74ms app.highlight 65ms RepoModel.GetById 1ms app.codeStats 1ms

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