PageRenderTime 98ms CodeModel.GetById 3ms app.highlight 83ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php

https://github.com/brendo10x/Sistema-de-mercadinho
PHP | 1764 lines | 1222 code | 213 blank | 329 comment | 6 complexity | 26a45281c8ecac695e15f5bc26509e1f MD5 | raw file
   1<?php
   2/**
   3 * HttpSocketTest file
   4 *
   5 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
   6 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
   7 *
   8 * Licensed under The MIT License
   9 * For full copyright and license information, please see the LICENSE.txt
  10 * Redistributions of files must retain the above copyright notice
  11 *
  12 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  14 * @package       Cake.Test.Case.Network.Http
  15 * @since         CakePHP(tm) v 1.2.0.4206
  16 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
  17 */
  18
  19App::uses('HttpSocket', 'Network/Http');
  20App::uses('HttpResponse', 'Network/Http');
  21
  22/**
  23 * TestAuthentication class
  24 *
  25 * @package       Cake.Test.Case.Network.Http
  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 string|array $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|array $uri URI to parse
  96 * @param boolean|array $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 formatted 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 string|array $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.Test.Case.Network.Http
 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		parent::setUp();
 195		if (!class_exists('MockHttpSocket')) {
 196			$this->getMock('TestHttpSocket', array('read', 'write', 'connect'), array(), 'MockHttpSocket');
 197			$this->getMock('TestHttpSocket', array('read', 'write', 'connect', 'request'), array(), 'MockHttpSocketRequests');
 198		}
 199
 200		$this->Socket = new MockHttpSocket();
 201		$this->RequestSocket = new MockHttpSocketRequests();
 202	}
 203
 204/**
 205 * We use this function to clean up after the test case was executed
 206 *
 207 * @return void
 208 */
 209	public function tearDown() {
 210		parent::tearDown();
 211		unset($this->Socket, $this->RequestSocket);
 212	}
 213
 214/**
 215 * Test that HttpSocket::__construct does what one would expect it to do
 216 *
 217 * @return void
 218 */
 219	public function testConstruct() {
 220		$this->Socket->reset();
 221		$baseConfig = $this->Socket->config;
 222		$this->Socket->expects($this->never())->method('connect');
 223		$this->Socket->__construct(array('host' => 'foo-bar'));
 224		$baseConfig['host'] = 'foo-bar';
 225		$baseConfig['protocol'] = getprotobyname($baseConfig['protocol']);
 226		$this->assertEquals($this->Socket->config, $baseConfig);
 227
 228		$this->Socket->reset();
 229		$baseConfig = $this->Socket->config;
 230		$this->Socket->__construct('http://www.cakephp.org:23/');
 231		$baseConfig['host'] = $baseConfig['request']['uri']['host'] = 'www.cakephp.org';
 232		$baseConfig['port'] = $baseConfig['request']['uri']['port'] = 23;
 233		$baseConfig['request']['uri']['scheme'] = 'http';
 234		$baseConfig['protocol'] = getprotobyname($baseConfig['protocol']);
 235		$this->assertEquals($this->Socket->config, $baseConfig);
 236
 237		$this->Socket->reset();
 238		$this->Socket->__construct(array('request' => array('uri' => 'http://www.cakephp.org:23/')));
 239		$this->assertEquals($this->Socket->config, $baseConfig);
 240	}
 241
 242/**
 243 * Test that HttpSocket::configUri works properly with different types of arguments
 244 *
 245 * @return void
 246 */
 247	public function testConfigUri() {
 248		$this->Socket->reset();
 249		$r = $this->Socket->configUri('https://bob:secret@www.cakephp.org:23/?query=foo');
 250		$expected = array(
 251			'persistent' => false,
 252			'host' => 'www.cakephp.org',
 253			'protocol' => 'tcp',
 254			'port' => 23,
 255			'timeout' => 30,
 256			'ssl_verify_peer' => true,
 257			'ssl_allow_self_signed' => false,
 258			'ssl_verify_depth' => 5,
 259			'ssl_verify_host' => true,
 260			'request' => array(
 261				'uri' => array(
 262					'scheme' => 'https',
 263					'host' => 'www.cakephp.org',
 264					'port' => 23
 265				),
 266				'redirect' => false,
 267				'cookies' => array(),
 268			)
 269		);
 270		$this->assertEquals($expected, $this->Socket->config);
 271		$this->assertTrue($r);
 272		$r = $this->Socket->configUri(array('host' => 'www.foo-bar.org'));
 273		$expected['host'] = 'www.foo-bar.org';
 274		$expected['request']['uri']['host'] = 'www.foo-bar.org';
 275		$this->assertEquals($expected, $this->Socket->config);
 276		$this->assertTrue($r);
 277
 278		$r = $this->Socket->configUri('http://www.foo.com');
 279		$expected = array(
 280			'persistent' => false,
 281			'host' => 'www.foo.com',
 282			'protocol' => 'tcp',
 283			'port' => 80,
 284			'timeout' => 30,
 285			'ssl_verify_peer' => true,
 286			'ssl_allow_self_signed' => false,
 287			'ssl_verify_depth' => 5,
 288			'ssl_verify_host' => true,
 289			'request' => array(
 290				'uri' => array(
 291					'scheme' => 'http',
 292					'host' => 'www.foo.com',
 293					'port' => 80
 294				),
 295				'redirect' => false,
 296				'cookies' => array(),
 297			)
 298		);
 299		$this->assertEquals($expected, $this->Socket->config);
 300		$this->assertTrue($r);
 301
 302		$r = $this->Socket->configUri('/this-is-broken');
 303		$this->assertEquals($expected, $this->Socket->config);
 304		$this->assertFalse($r);
 305
 306		$r = $this->Socket->configUri(false);
 307		$this->assertEquals($expected, $this->Socket->config);
 308		$this->assertFalse($r);
 309	}
 310
 311/**
 312 * Tests that HttpSocket::request (the heart of the HttpSocket) is working properly.
 313 *
 314 * @return void
 315 */
 316	public function testRequest() {
 317		$this->Socket->reset();
 318
 319		$response = $this->Socket->request(true);
 320		$this->assertFalse($response);
 321
 322		$context = array(
 323			'ssl' => array(
 324				'verify_peer' => true,
 325				'allow_self_signed' => false,
 326				'verify_depth' => 5,
 327				'CN_match' => 'www.cakephp.org',
 328				'cafile' => CAKE . 'Config' . DS . 'cacert.pem'
 329			)
 330		);
 331
 332		$tests = array(
 333			array(
 334				'request' => 'http://www.cakephp.org/?foo=bar',
 335				'expectation' => array(
 336					'config' => array(
 337						'persistent' => false,
 338						'host' => 'www.cakephp.org',
 339						'protocol' => 'tcp',
 340						'port' => 80,
 341						'timeout' => 30,
 342						'context' => $context,
 343						'request' => array(
 344							'uri' => array(
 345								'scheme' => 'http',
 346								'host' => 'www.cakephp.org',
 347								'port' => 80
 348							),
 349							'redirect' => false,
 350							'cookies' => array()
 351						)
 352					),
 353					'request' => array(
 354						'method' => 'GET',
 355						'uri' => array(
 356							'scheme' => 'http',
 357							'host' => 'www.cakephp.org',
 358							'port' => 80,
 359							'user' => null,
 360							'pass' => null,
 361							'path' => '/',
 362							'query' => array('foo' => 'bar'),
 363							'fragment' => null
 364						),
 365						'version' => '1.1',
 366						'body' => '',
 367						'line' => "GET /?foo=bar HTTP/1.1\r\n",
 368						'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n",
 369						'raw' => "",
 370						'redirect' => false,
 371						'cookies' => array(),
 372						'proxy' => array(),
 373						'auth' => array()
 374					)
 375				)
 376			),
 377			array(
 378				'request' => array(
 379					'uri' => array(
 380						'host' => 'www.cakephp.org',
 381						'query' => '?foo=bar'
 382					)
 383				)
 384			),
 385			array(
 386				'request' => 'www.cakephp.org/?foo=bar'
 387			),
 388			array(
 389				'request' => array(
 390					'host' => '192.168.0.1',
 391					'uri' => 'http://www.cakephp.org/?foo=bar'
 392				),
 393				'expectation' => array(
 394					'request' => array(
 395						'uri' => array('host' => 'www.cakephp.org')
 396					),
 397					'config' => array(
 398						'request' => array(
 399							'uri' => array('host' => 'www.cakephp.org')
 400						),
 401						'host' => '192.168.0.1'
 402					)
 403				)
 404			),
 405			'reset4' => array(
 406				'request.uri.query' => array()
 407			),
 408			array(
 409				'request' => array(
 410					'header' => array('Foo@woo' => 'bar-value')
 411				),
 412				'expectation' => array(
 413					'request' => array(
 414						'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nFoo\"@\"woo: bar-value\r\n",
 415						'line' => "GET / HTTP/1.1\r\n"
 416					)
 417				)
 418			),
 419			array(
 420				'request' => array('header' => array('Foo@woo' => 'bar-value', 'host' => 'foo.com'), 'uri' => 'http://www.cakephp.org/'),
 421				'expectation' => array(
 422					'request' => array(
 423						'header' => "Host: foo.com\r\nConnection: close\r\nUser-Agent: CakePHP\r\nFoo\"@\"woo: bar-value\r\n"
 424					),
 425					'config' => array(
 426						'host' => 'www.cakephp.org'
 427					)
 428				)
 429			),
 430			array(
 431				'request' => array('header' => "Foo: bar\r\n"),
 432				'expectation' => array(
 433					'request' => array(
 434						'header' => "Foo: bar\r\n"
 435					)
 436				)
 437			),
 438			array(
 439				'request' => array('header' => "Foo: bar\r\n", 'uri' => 'http://www.cakephp.org/search?q=http_socket#ignore-me'),
 440				'expectation' => array(
 441					'request' => array(
 442						'uri' => array(
 443							'path' => '/search',
 444							'query' => array('q' => 'http_socket'),
 445							'fragment' => 'ignore-me'
 446						),
 447						'line' => "GET /search?q=http_socket HTTP/1.1\r\n"
 448					)
 449				)
 450			),
 451			'reset8' => array(
 452				'request.uri.query' => array()
 453			),
 454			array(
 455				'request' => array(
 456					'method' => 'POST',
 457					'uri' => 'http://www.cakephp.org/posts/add',
 458					'body' => array(
 459						'name' => 'HttpSocket-is-released',
 460						'date' => 'today'
 461					)
 462				),
 463				'expectation' => array(
 464					'request' => array(
 465						'method' => 'POST',
 466						'uri' => array(
 467							'path' => '/posts/add',
 468							'fragment' => null
 469						),
 470						'body' => "name=HttpSocket-is-released&date=today",
 471						'line' => "POST /posts/add HTTP/1.1\r\n",
 472						'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",
 473						'raw' => "name=HttpSocket-is-released&date=today"
 474					)
 475				)
 476			),
 477			array(
 478				'request' => array(
 479					'method' => 'POST',
 480					'uri' => 'http://www.cakephp.org:8080/posts/add',
 481					'body' => array(
 482						'name' => 'HttpSocket-is-released',
 483						'date' => 'today'
 484					)
 485				),
 486				'expectation' => array(
 487					'config' => array(
 488						'port' => 8080,
 489						'request' => array(
 490							'uri' => array(
 491								'port' => 8080
 492							)
 493						)
 494					),
 495					'request' => array(
 496						'uri' => array(
 497							'port' => 8080
 498						),
 499						'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"
 500					)
 501				)
 502			),
 503			array(
 504				'request' => array(
 505					'method' => 'POST',
 506					'uri' => 'https://www.cakephp.org/posts/add',
 507					'body' => array(
 508						'name' => 'HttpSocket-is-released',
 509						'date' => 'today'
 510					)
 511				),
 512				'expectation' => array(
 513					'config' => array(
 514						'port' => 443,
 515						'request' => array(
 516							'uri' => array(
 517								'scheme' => 'https',
 518								'port' => 443
 519							)
 520						)
 521					),
 522					'request' => array(
 523						'uri' => array(
 524							'scheme' => 'https',
 525							'port' => 443
 526						),
 527						'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"
 528					)
 529				)
 530			),
 531			array(
 532				'request' => array(
 533					'method' => 'POST',
 534					'uri' => 'https://www.cakephp.org/posts/add',
 535					'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'),
 536					'cookies' => array('foo' => array('value' => 'bar'))
 537				),
 538				'expectation' => array(
 539					'request' => array(
 540						'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",
 541						'cookies' => array(
 542							'foo' => array('value' => 'bar'),
 543						)
 544					)
 545				)
 546			)
 547		);
 548
 549		$expectation = array();
 550		foreach ($tests as $i => $test) {
 551			if (strpos($i, 'reset') === 0) {
 552				foreach ($test as $path => $val) {
 553					$expectation = Hash::insert($expectation, $path, $val);
 554				}
 555				continue;
 556			}
 557
 558			if (isset($test['expectation'])) {
 559				$expectation = Hash::merge($expectation, $test['expectation']);
 560			}
 561			$this->Socket->request($test['request']);
 562
 563			$raw = $expectation['request']['raw'];
 564			$expectation['request']['raw'] = $expectation['request']['line'] . $expectation['request']['header'] . "\r\n" . $raw;
 565
 566			$r = array('config' => $this->Socket->config, 'request' => $this->Socket->request);
 567			$this->assertEquals($r, $expectation, 'Failed test #' . $i . ' ');
 568			$expectation['request']['raw'] = $raw;
 569		}
 570
 571		$this->Socket->reset();
 572		$request = array('method' => 'POST', 'uri' => 'http://www.cakephp.org/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'));
 573		$response = $this->Socket->request($request);
 574		$this->assertEquals("name=HttpSocket-is-released&date=today", $this->Socket->request['body']);
 575	}
 576
 577/**
 578 * Test the scheme + port keys
 579 *
 580 * @return void
 581 */
 582	public function testGetWithSchemeAndPort() {
 583		$this->Socket->reset();
 584		$request = array(
 585			'uri' => array(
 586				'scheme' => 'http',
 587				'host' => 'cakephp.org',
 588				'port' => 8080,
 589				'path' => '/',
 590			),
 591			'method' => 'GET'
 592		);
 593		$this->Socket->request($request);
 594		$this->assertContains('Host: cakephp.org:8080', $this->Socket->request['header']);
 595	}
 596
 597/**
 598 * Test URLs like http://cakephp.org/index.php?somestring without key/value pair for query
 599 *
 600 * @return void
 601 */
 602	public function testRequestWithStringQuery() {
 603		$this->Socket->reset();
 604		$request = array(
 605			'uri' => array(
 606				'scheme' => 'http',
 607				'host' => 'cakephp.org',
 608				'path' => 'index.php',
 609				'query' => 'somestring'
 610			),
 611			'method' => 'GET'
 612		);
 613		$this->Socket->request($request);
 614		$this->assertContains("GET /index.php?somestring HTTP/1.1", $this->Socket->request['line']);
 615	}
 616
 617/**
 618 * The "*" asterisk character is only allowed for the following methods: OPTIONS.
 619 *
 620 * @expectedException SocketException
 621 * @return void
 622 */
 623	public function testRequestNotAllowedUri() {
 624		$this->Socket->reset();
 625		$request = array('uri' => '*', 'method' => 'GET');
 626		$this->Socket->request($request);
 627	}
 628
 629/**
 630 * testRequest2 method
 631 *
 632 * @return void
 633 */
 634	public function testRequest2() {
 635		$this->Socket->reset();
 636		$request = array('uri' => 'htpp://www.cakephp.org/');
 637		$number = mt_rand(0, 9999999);
 638		$this->Socket->expects($this->once())->method('connect')->will($this->returnValue(true));
 639		$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>";
 640		$this->Socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
 641		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
 642		$this->Socket->expects($this->once())->method('write')
 643			->with("GET / HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n\r\n");
 644		$response = (string)$this->Socket->request($request);
 645		$this->assertEquals($response, "<h1>Hello, your lucky number is " . $number . "</h1>");
 646	}
 647
 648/**
 649 * testRequest3 method
 650 *
 651 * @return void
 652 */
 653	public function testRequest3() {
 654		$request = array('uri' => 'htpp://www.cakephp.org/');
 655		$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>";
 656		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
 657		$this->Socket->connected = true;
 658		$this->Socket->request($request);
 659		$result = $this->Socket->response['cookies'];
 660		$expect = array(
 661			'foo' => array(
 662				'value' => 'bar'
 663			)
 664		);
 665		$this->assertEquals($expect, $result);
 666		$this->assertEquals($this->Socket->config['request']['cookies']['www.cakephp.org'], $expect);
 667		$this->assertFalse($this->Socket->connected);
 668	}
 669
 670/**
 671 * testRequestWithConstructor method
 672 *
 673 * @return void
 674 */
 675	public function testRequestWithConstructor() {
 676		$request = array(
 677			'request' => array(
 678				'uri' => array(
 679					'scheme' => 'http',
 680					'host' => 'localhost',
 681					'port' => '5984',
 682					'user' => null,
 683					'pass' => null
 684				)
 685			)
 686		);
 687		$http = new MockHttpSocketRequests($request);
 688
 689		$expected = array('method' => 'GET', 'uri' => '/_test');
 690		$http->expects($this->at(0))->method('request')->with($expected);
 691		$http->get('/_test');
 692
 693		$expected = array('method' => 'GET', 'uri' => 'http://localhost:5984/_test?count=4');
 694		$http->expects($this->at(0))->method('request')->with($expected);
 695		$http->get('/_test', array('count' => 4));
 696	}
 697
 698/**
 699 * testRequestWithResource
 700 *
 701 * @return void
 702 */
 703	public function testRequestWithResource() {
 704		$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>";
 705		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
 706		$this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
 707		$this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse));
 708		$this->Socket->connected = true;
 709
 710		$f = fopen(TMP . 'download.txt', 'w');
 711		if (!$f) {
 712			$this->markTestSkipped('Can not write in TMP directory.');
 713		}
 714
 715		$this->Socket->setContentResource($f);
 716		$result = (string)$this->Socket->request('http://www.cakephp.org/');
 717		$this->assertEquals('', $result);
 718		$this->assertEquals('CakeHttp Server', $this->Socket->response['header']['Server']);
 719		fclose($f);
 720		$this->assertEquals(file_get_contents(TMP . 'download.txt'), '<h1>This is a test!</h1>');
 721		unlink(TMP . 'download.txt');
 722
 723		$this->Socket->setContentResource(false);
 724		$result = (string)$this->Socket->request('http://www.cakephp.org/');
 725		$this->assertEquals('<h1>This is a test!</h1>', $result);
 726	}
 727
 728/**
 729 * testRequestWithCrossCookie
 730 *
 731 * @return void
 732 */
 733	public function testRequestWithCrossCookie() {
 734		$this->Socket->connected = true;
 735		$this->Socket->config['request']['cookies'] = array();
 736
 737		$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>";
 738		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
 739		$this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
 740		$expected = array('www.cakephp.org' => array('foo' => array('value' => 'bar')));
 741		$this->Socket->request('http://www.cakephp.org/');
 742		$this->assertEquals($expected, $this->Socket->config['request']['cookies']);
 743
 744		$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>";
 745		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
 746		$this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
 747		$this->Socket->request('http://www.cakephp.org/other');
 748		$this->assertEquals(array('foo' => array('value' => 'bar')), $this->Socket->request['cookies']);
 749		$expected['www.cakephp.org'] += array('bar' => array('value' => 'foo'));
 750		$this->assertEquals($expected, $this->Socket->config['request']['cookies']);
 751
 752		$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>";
 753		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
 754		$this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
 755		$this->Socket->request('/other2');
 756		$this->assertEquals($expected, $this->Socket->config['request']['cookies']);
 757
 758		$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>";
 759		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
 760		$this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
 761		$this->Socket->request('http://www.cake.com');
 762		$this->assertTrue(empty($this->Socket->request['cookies']));
 763		$expected['www.cake.com'] = array('foobar' => array('value' => 'ok'));
 764		$this->assertEquals($expected, $this->Socket->config['request']['cookies']);
 765	}
 766
 767/**
 768 * testRequestCustomResponse
 769 *
 770 * @return void
 771 */
 772	public function testRequestCustomResponse() {
 773		$this->Socket->connected = true;
 774		$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>";
 775		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
 776		$this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
 777
 778		$this->Socket->responseClass = 'CustomResponse';
 779		$response = $this->Socket->request('http://www.cakephp.org/');
 780		$this->assertInstanceOf('CustomResponse', $response);
 781		$this->assertEquals('HTTP/1.x 2', $response->first10);
 782	}
 783
 784/**
 785 * Test that redirect URLs are urldecoded
 786 *
 787 * @return void
 788 */
 789	public function testRequestWithRedirectUrlEncoded() {
 790		$request = array(
 791			'uri' => 'http://localhost/oneuri',
 792			'redirect' => 1
 793		);
 794		$serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://i.cmpnet.com%2Ftechonline%2Fpdf%2Fa.pdf=\r\n\r\n";
 795		$serverResponse2 = "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>You have been redirected</h1>";
 796
 797		$this->Socket->expects($this->at(1))
 798			->method('read')
 799			->will($this->returnValue($serverResponse1));
 800
 801		$this->Socket->expects($this->at(3))
 802			->method('write')
 803			->with($this->logicalAnd(
 804				$this->stringContains('Host: i.cmpnet.com'),
 805				$this->stringContains('GET /techonline/pdf/a.pdf')
 806			));
 807
 808		$this->Socket->expects($this->at(4))
 809			->method('read')
 810			->will($this->returnValue($serverResponse2));
 811
 812		$response = $this->Socket->request($request);
 813		$this->assertEquals('<h1>You have been redirected</h1>', $response->body());
 814	}
 815
 816/**
 817 * testRequestWithRedirect method
 818 *
 819 * @return void
 820 */
 821	public function testRequestWithRedirectAsTrue() {
 822		$request = array(
 823			'uri' => 'http://localhost/oneuri',
 824			'redirect' => true
 825		);
 826		$serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/anotheruri\r\n\r\n";
 827		$serverResponse2 = "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>You have been redirected</h1>";
 828		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse1));
 829		$this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse2));
 830
 831		$response = $this->Socket->request($request);
 832		$this->assertEquals('<h1>You have been redirected</h1>', $response->body());
 833	}
 834
 835/**
 836 * Test that redirects with a count limit are decremented.
 837 *
 838 * @return void
 839 */
 840	public function testRequestWithRedirectAsInt() {
 841		$request = array(
 842			'uri' => 'http://localhost/oneuri',
 843			'redirect' => 2
 844		);
 845		$serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/anotheruri\r\n\r\n";
 846		$serverResponse2 = "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>You have been redirected</h1>";
 847		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse1));
 848		$this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse2));
 849
 850		$this->Socket->request($request);
 851		$this->assertEquals(1, $this->Socket->request['redirect']);
 852	}
 853
 854/**
 855 * Test that redirects after the redirect count reaches 9 are not followed.
 856 *
 857 * @return void
 858 */
 859	public function testRequestWithRedirectAsIntReachingZero() {
 860		$request = array(
 861			'uri' => 'http://localhost/oneuri',
 862			'redirect' => 1
 863		);
 864		$serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/oneruri\r\n\r\n";
 865		$serverResponse2 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/anotheruri\r\n\r\n";
 866		$this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse1));
 867		$this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse2));
 868
 869		$response = $this->Socket->request($request);
 870		$this->assertEquals(0, $this->Socket->request['redirect']);
 871		$this->assertEquals(302, $response->code);
 872		$this->assertEquals('http://localhost/anotheruri', $response->getHeader('Location'));
 873	}
 874
 875/**
 876 * testProxy method
 877 *
 878 * @return void
 879 */
 880	public function testProxy() {
 881		$this->Socket->reset();
 882		$this->Socket->expects($this->any())->method('connect')->will($this->returnValue(true));
 883		$this->Socket->expects($this->any())->method('read')->will($this->returnValue(false));
 884
 885		$this->Socket->configProxy('proxy.server', 123);
 886		$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";
 887		$this->Socket->request('http://www.cakephp.org/');
 888		$this->assertEquals($expected, $this->Socket->request['raw']);
 889		$this->assertEquals('proxy.server', $this->Socket->config['host']);
 890		$this->assertEquals(123, $this->Socket->config['port']);
 891		$expected = array(
 892			'host' => 'proxy.server',
 893			'port' => 123,
 894			'method' => null,
 895			'user' => null,
 896			'pass' => null
 897		);
 898		$this->assertEquals($expected, $this->Socket->request['proxy']);
 899
 900		$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";
 901		$this->Socket->request('/bakery');
 902		$this->assertEquals($expected, $this->Socket->request['raw']);
 903		$this->assertEquals('proxy.server', $this->Socket->config['host']);
 904		$this->assertEquals(123, $this->Socket->config['port']);
 905		$expected = array(
 906			'host' => 'proxy.server',
 907			'port' => 123,
 908			'method' => null,
 909			'user' => null,
 910			'pass' => null
 911		);
 912		$this->assertEquals($expected, $this->Socket->request['proxy']);
 913
 914		$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";
 915		$this->Socket->configProxy('proxy.server', 123, 'Test', 'mark', 'secret');
 916		$this->Socket->request('http://www.cakephp.org/');
 917		$this->assertEquals($expected, $this->Socket->request['raw']);
 918		$this->assertEquals('proxy.server', $this->Socket->config['host']);
 919		$this->assertEquals(123, $this->Socket->config['port']);
 920		$expected = array(
 921			'host' => 'proxy.server',
 922			'port' => 123,
 923			'method' => 'Test',
 924			'user' => 'mark',
 925			'pass' => 'secret'
 926		);
 927		$this->assertEquals($expected, $this->Socket->request['proxy']);
 928
 929		$this->Socket->configAuth('Test', 'login', 'passwd');
 930		$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";
 931		$this->Socket->request('http://www.cakephp.org/');
 932		$this->assertEquals($expected, $this->Socket->request['raw']);
 933		$expected = array(
 934			'host' => 'proxy.server',
 935			'port' => 123,
 936			'method' => 'Test',
 937			'user' => 'mark',
 938			'pass' => 'secret'
 939		);
 940		$this->assertEquals($expected, $this->Socket->request['proxy']);
 941		$expected = array(
 942			'Test' => array(
 943				'user' => 'login',
 944				'pass' => 'passwd'
 945			)
 946		);
 947		$this->assertEquals($expected, $this->Socket->request['auth']);
 948	}
 949
 950/**
 951 * testUrl method
 952 *
 953 * @return void
 954 */
 955	public function testUrl() {
 956		$this->Socket->reset(true);
 957
 958		$this->assertEquals(false, $this->Socket->url(true));
 959
 960		$url = $this->Socket->url('www.cakephp.org');
 961		$this->assertEquals('http://www.cakephp.org/', $url);
 962
 963		$url = $this->Socket->url('https://www.cakephp.org/posts/add');
 964		$this->assertEquals('https://www.cakephp.org/posts/add', $url);
 965		$url = $this->Socket->url('http://www.cakephp/search?q=socket', '/%path?%query');
 966		$this->assertEquals('/search?q=socket', $url);
 967
 968		$this->Socket->config['request']['uri']['host'] = 'bakery.cakephp.org';
 969		$url = $this->Socket->url();
 970		$this->assertEquals('http://bakery.cakephp.org/', $url);
 971
 972		$this->Socket->configUri('http://www.cakephp.org');
 973		$url = $this->Socket->url('/search?q=bar');
 974		$this->assertEquals('http://www.cakephp.org/search?q=bar', $url);
 975
 976		$url = $this->Socket->url(array('host' => 'www.foobar.org', 'query' => array('q' => 'bar')));
 977		$this->assertEquals('http://www.foobar.org/?q=bar', $url);
 978
 979		$url = $this->Socket->url(array('path' => '/supersearch', 'query' => array('q' => 'bar')));
 980		$this->assertEquals('http://www.cakephp.org/supersearch?q=bar', $url);
 981
 982		$this->Socket->configUri('http://www.google.com');
 983		$url = $this->Socket->url('/search?q=socket');
 984		$this->assertEquals('http://www.google.com/search?q=socket', $url);
 985
 986		$url = $this->Socket->url();
 987		$this->assertEquals('http://www.google.com/', $url);
 988
 989		$this->Socket->configUri('https://www.google.com');
 990		$url = $this->Socket->url('/search?q=socket');
 991		$this->assertEquals('https://www.google.com/search?q=socket', $url);
 992
 993		$this->Socket->reset();
 994		$this->Socket->configUri('www.google.com:443');
 995		$url = $this->Socket->url('/search?q=socket');
 996		$this->assertEquals('https://www.google.com/search?q=socket', $url);
 997
 998		$this->Socket->reset();
 999		$this->Socket->configUri('www.google.com:8080');
1000		$url = $this->Socket->url('/search?q=socket');
1001		$this->assertEquals('http://www.google.com:8080/search?q=socket', $url);
1002	}
1003
1004/**
1005 * testGet method
1006 *
1007 * @return void
1008 */
1009	public function testGet() {
1010		$this->RequestSocket->reset();
1011
1012		$this->RequestSocket->expects($this->at(0))
1013			->method('request')
1014			->with(array('method' => 'GET', 'uri' => 'http://www.google.com/'));
1015
1016		$this->RequestSocket->expects($this->at(1))
1017			->method('request')
1018			->with(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=bar'));
1019
1020		$this->RequestSocket->expects($this->at(2))
1021			->method('request')
1022			->with(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=bar'));
1023
1024		$this->RequestSocket->expects($this->at(3))
1025			->method('request')
1026			->with(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=23&foobar=42'));
1027
1028		$this->RequestSocket->expects($this->at(4))
1029			->method('request')
1030			->with(array('method' => 'GET', 'uri' => 'http://www.google.com/', 'version' => '1.0'));
1031
1032		$this->RequestSocket->expects($this->at(5))
1033			->method('request')
1034			->with(array('method' => 'GET', 'uri' => 'https://secure.example.com/test.php?one=two'));
1035
1036		$this->RequestSocket->expects($this->at(6))
1037			->method('request')
1038			->with(array('method' => 'GET', 'uri' => 'https://example.com/oauth/access?clientid=123&redirect_uri=http%3A%2F%2Fexample.com&code=456'));
1039
1040		$this->RequestSocket->get('http://www.google.com/');
1041		$this->RequestSocket->get('http://www.google.com/', array('foo' => 'bar'));
1042		$this->RequestSocket->get('http://www.google.com/', 'foo=bar');
1043		$this->RequestSocket->get('http://www.google.com/?foo=bar', array('foobar' => '42', 'foo' => '23'));
1044		$this->RequestSocket->get('http://www.google.com/', null, array('version' => '1.0'));
1045		$this->RequestSocket->get('https://secure.example.com/test.php', array('one' => 'two'));
1046		$this->RequestSocket->get('https://example.com/oauth/access', array(
1047			'clientid' => '123',
1048			'redirect_uri' => 'http://example.com',
1049			'code' => 456
1050		));
1051	}
1052
1053/**
1054 * Test authentication
1055 *
1056 * @return void
1057 */
1058	public function testAuth() {
1059		$socket = new MockHttpSocket();
1060		$socket->get('http://mark:secret@example.com/test');
1061		$this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic bWFyazpzZWNyZXQ=') !== false);
1062
1063		$socket->configAuth(false);
1064		$socket->get('http://example.com/test');
1065		$this->assertFalse(strpos($socket->request['header'], 'Authorization:'));
1066
1067		$socket->configAuth('Test', 'mark', 'passwd');
1068		$socket->get('http://example.com/test');
1069		$this->assertTrue(strpos($socket->request['header'], 'Authorization: Test mark.passwd') !== false);
1070
1071		$socket->configAuth(false);
1072		$socket->request(array(
1073			'method' => 'GET',
1074			'uri' => 'http://example.com/test',
1075			'auth' => array(
1076				'method' => 'Basic',
1077				'user' => 'joel',
1078				'pass' => 'hunter2'
1079			)
1080		));
1081		$this->assertEquals($socket->request['auth'], array('Basic' => array('user' => 'joel', 'pass' => 'hunter2')));
1082		$this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic am9lbDpodW50ZXIy') !== false);
1083	}
1084
1085/**
1086 * test that two consecutive get() calls reset the authentication credentials.
1087 *
1088 * @return void
1089 */
1090	public function testConsecutiveGetResetsAuthCredentials() {
1091		$socket = new MockHttpSocket();
1092		$socket->get('http://mark:secret@example.com/test');
1093		$this->assertEquals('mark', $socket->request['uri']['user']);
1094		$this->assertEquals('secret', $socket->request['uri']['pass']);
1095		$this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic bWFyazpzZWNyZXQ=') !== false);
1096
1097		$socket->get('/test2');
1098		$this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic bWFyazpzZWNyZXQ=') !== false);
1099
1100		$socket->get('/test3');
1101		$this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic bWFyazpzZWNyZXQ=') !== false);
1102	}
1103
1104/**
1105 * testPostPutDelete method
1106 *
1107 * @return void
1108 */
1109	public function testPost() {
1110		$this->RequestSocket->reset();
1111		$this->RequestSocket->expects($this->at(0))
1112			->method('request')
1113			->with(array('method' => 'POST', 'uri' => 'http://www.google.com/', 'body' => array()));
1114
1115		$this->RequestSocket->expects($this->at(1))
1116			->method('request')
1117			->with(array('method' => 'POST', 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar')));
1118
1119		$this->RequestSocket->expects($this->at(2))
1120			->method('request')
1121			->with(array('method' => 'POST', 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server'));
1122
1123		$this->RequestSocket->post('http://www.google.com/');
1124		$this->RequestSocket->post('http://www.google.com/', array('Foo' => 'bar'));
1125		$this->RequestSocket->post('http://www.google.com/', null, array('line' => 'Hey Server'));
1126	}
1127
1128/**
1129 * testPut
1130 *
1131 * @return void
1132 */
1133	public function testPut() {
1134		$this->RequestSocket->reset();
1135		$this->RequestSocket->expects($this->at(0))
1136			->method('request')
1137			->with(array('method' => 'PUT', 'uri' => 'http://www.google.com/', 'body' => array()));
1138
1139		$this->RequestSocket->expects($this->at(1))
1140			->method('request')
1141			->with(array('method' => 'PUT', 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar')));
1142
1143		$this->RequestSocket->expects($this->at(2))
1144			->method('request')
1145			->with(array('method' => 'PUT', 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server'));
1146
1147		$this->RequestSocket->put('http://www.google.com/');
1148		$this->RequestSocket->put('http://www.google.com/', array('Foo' => 'bar'));
1149		$this->RequestSocket->put('http://www.google.com/', null, array('line' => 'Hey Server'));
1150	}
1151
1152/**
1153 * testPatch
1154 *
1155 * @return void
1156 */
1157	public function testPatch() {
1158		$this->RequestSocket->reset();
1159		$this->RequestSocket->expects($this->at(0))
1160			->method('request')
1161			->with(array('method' => 'PATCH', 'uri' => 'http://www.google.com/', 'body' => array()));
1162
1163		$this->RequestSocket->expects($this->at(1))
1164			->method('request')
1165			->with(array('method' => 'PATCH', 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar')));
1166
1167		$this->RequestSocket->expects($this->at(2))
1168			->method('request')
1169			->with(array('method' => 'PATCH', 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server'));
1170
1171		$this->RequestSocket->patch('http://www.google.com/');
1172		$this->RequestSocket->patch('http://www.google.com/', array('Foo' => 'bar'));
1173		$this->RequestSocket->patch('http://www.google.com/', null, array('line' => 'Hey Server'));
1174	}
1175
1176/**
1177 * testDelete
1178 *
1179 * @return void
1180 */
1181	public function testDelete() {
1182		$this->RequestSocket->reset();
1183		$this->RequestSocket->expects($this->at(0))
1184			->method('request')
1185			->with(array('method' => 'DELETE', 'uri' => 'http://www.google.com/', 'body' => array()));
1186
1187		$this->RequestSocket->expects($this->at(1))
1188			->method('request')
1189			->with(array('method' => 'DELETE', 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar')));
1190
1191		$this->RequestSocket->expects($this->at(2))
1192			->method('request')
1193			->with(array('method' => 'DELETE', 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server'));
1194
1195		$this->RequestSocket->delete('http://www.google.com/');
1196		$this->RequestSocket->delete('http://www.google.com/', array('Foo' => 'bar'));
1197		$this->RequestSocket->delete('http://www.google.com/', null, array('line' => 'Hey Server'));
1198	}
1199
1200/**
1201 * testBuildRequestLine method
1202 *
1203 * @return void
1204 */
1205	public function testBuildRequestLine() {
1206		$this->Socket->reset();
1207
1208		$this->Socket->quirksMode = true;
1209		$r = $this->Socket->buildRequestLine('Foo');
1210		$this->assertEquals('Foo', $r);
1211		$this->Socket->quirksMode = false;
1212
1213		$r = $this->Socket->buildRequestLine(true);
1214		$this->assertEquals(false, $r);
1215
1216		$r = $this->Socket->buildRequestLine(array('foo' => 'bar', 'method' => 'foo'));
1217		$this->assertEquals(false, $r);
1218
1219		$r = $this->Socket->buildRequestLine(array('method' => 'GET', 'uri' => 'http://www.cakephp.org/search?q=socket'));
1220		$this->assertEquals("GET /search?q=socket HTTP/1.1\r\n", $r);
1221
1222		$request = array(
1223			'method' => 'GET',
1224			'uri' => array(
1225				'path' => '/search',
1226				'query' => array('q' => 'socket')
1227			)
1228		);
1229		$r = $this->Socket->buildRequestLine($request);
1230		$this->assertEquals("GET /search?q=socket HTTP/1.1\r\n", $r);
1231
1232		unset($request['method']);
1233		$r = $this->Socket->buildRequestLine($request);
1234		$this->assertEquals("GET /search?q=socket HTTP/1.1\r\n", $r);
1235
1236		$r = $this->Socket->buildRequestLine($request, 'CAKE-HTTP/0.1');
1237		$this->assertEquals("GET /search?q=socket CAKE-HTTP/0.1\r\n", $r);
1238
1239		$request = array('method' => 'OPTIONS', 'uri' => '*');
1240		$r = $this->Socket->buildRequestLine($request);
1241		$this->assertEquals("OPTIONS * HTTP/1.1\r\n", $r);
1242
1243		$request['method'] = 'GET';
1244		$this->Socket->quirksMode = true;
1245		$r = $this->Socket->buildRequestLine($request);
1246		$this->assertEquals("GET * HTTP/1.1\r\n", $r);
1247
1248		$r = $this->Socket->buildRequestLine("GET * HTTP/1.1\r\n");
1249		$this->assertEquals("GET * HTTP/1.1\r\n", $r);
1250	}
1251
1252/**
1253 * testBadBuildRequestLine method
1254 *
1255 * @expectedException SocketException
1256 * @return void
1257 */
1258	public function testBadBuildRequestLine() {
1259		$this->Socket->buildRequestLine('Foo');
1260	}
1261
1262/**
1263 * testBadBuildRequestLine2 method
1264 *
1265 * @expectedException SocketException
1266 * @return void
1267 */
1268	public function testBadBuildRequestLine2() {
1269		$this->Socket->buildRequestLine("GET * HTTP/1.1\r\n");
1270	}
1271
1272/**
1273 * Asserts that HttpSocket::parseUri is working properly
1274 *
1275 * @return void
1276 */
1277	public function testParseUri() {
1278		$this->Socket->reset();
1279
1280		$uri = $this->Socket->parseUri(array('invalid' => 'uri-string'));
1281		$this->assertEquals(false, $uri);
1282
1283		$uri = $this->Socket->parseUri(array('invalid' => 'uri-string'), array('host' => 'somehost'));
1284		$this->assertEquals(array('host' => 'somehost', 'invalid' => 'uri-string'), $uri);
1285
1286		$uri = $this->Socket->parseUri(false);
1287		$this->assertEquals(false, $uri);
1288
1289		$uri = $this->Socket->parseUri('/my-cool-path');
1290		$this->assertEquals(array('path' => '/my-cool-path'), $uri);
1291
1292		$uri = $this->Socket->parseUri('http://bob:foo123@www.cakephp.org:40/search?q=dessert#results');
1293		$this->assertEquals($uri, array(
1294			'scheme' => 'http',
1295			'host' => 'www.cakephp.org',
1296			'port' => 40,
1297			'user' => 'bob',
1298			'pass' => 'foo123',
1299			'path' => '/search',
1300			'query' => array('q' => 'dessert'),
1301			'fragment' => 'results'
1302		));
1303
1304		$uri = $this->Socket->parseUri('http://www.cakephp.org/');
1305		$this->assertEquals($uri, array(
1306			'scheme' => 'http',
1307			'host' => 'www.cakephp.org',
1308			'path' => '/'
1309		));
1310
1311		$uri = $this->Socket->parseUri('http://www.cakephp.org', true);
1312		$this->assertEquals($uri, array(
1313			'scheme' => 'http',
1314			'host' => 'www.cakephp.org',
1315			'port' => 80,
1316			'user' => null,
1317			'pass' => null,
1318			'path' => '/',
1319			'query' => array(),
1320			'fragment' => null
1321		));
1322
1323		$uri = $this->Socket->parseUri('https://www.cakephp.org', true);
1324		$this->assertEquals($uri, array(
1325			'scheme' => 'https',
1326			'host' => 'www.cakephp.org',
1327			'port' => 443,
1328			'user' => null,
1329			'pass' => null,
1330			'path' => '/',
1331			'query' => array(),
1332			'fragment' => null
1333		));
1334
1335		$uri = $this->Socket->parseUri('www.cakephp.org:443/query?foo', true);
1336		$this->assertEquals($uri, array(
1337			'scheme' => 'https',
1338			'host' => 'www.cakephp.org',
1339			'port' => 443,
1340			'user' => null,
1341			'pass' => null,
1342			'path' => '/query',
1343			'query' => array('foo' => ""),
1344			'fragment' => null
1345		));
1346
1347		$uri = $this->Socket->parseUri('http://www.cakephp.org', array('host' => 'piephp.org', 'user' => 'bob', 'fragment' => 'results'));
1348		$this->assertEquals($uri, array(
1349			'host' => 'www.cakephp.org',
1350			'user' => 'bob',
1351			'fragment' => 'results',
1352			'scheme' => 'http'
1353		));
1354
1355		$uri = $this->Socket->parseUri('https://www.cakephp.org', array('scheme' => 'http', 'port' => 23));
1356		$this->assertEquals($uri, array(
1357			'scheme' => 'https',
1358			'port' => 23,
1359			'host' => 'www.cakephp.org'
1360		));
1361
1362		$uri = $this->Socket->parseUri('www.cakephp.org:59', array('scheme' => array('http', 'https'), 'port' => 80));
1363		$this->assertEquals($uri, array(
1364			'scheme' => 'http',
1365			'port' => 59,
1366			'host' => 'www.cakephp.org'
1367		));
1368
1369		$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)));
1370		$this->assertEquals($uri, array(
1371			'scheme' => 'http',
1372			'host' => 'www.google.com',
1373			'port' => 8080
1374		));
1375
1376		$uri = $this->Socket->parseUri('http://www.cakephp.org/?param1=value1&param2=value2%3Dvalue3');
1377		$this->assertEquals($uri, array(
1378			'scheme' => 'http',
1379			'host' => 'www.cakephp.org',
1380			'path' => '/',
1381			'query' => array(
1382				'param1' => 'value1',
1383				'param2' => 'value2=value3'
1384			)
1385		));
1386
1387		$uri = $this->Socket->parseUri('http://www.cakephp.org/?param1=value1&param2=value2=value3');
1388		$this->assertEquals($uri, array(
1389			'scheme' => 'http',
1390			'host' => 'www.cakephp.org',
1391			'path' => '/',
1392			'query' => array(
1393				'param1' => 'value1',
1394				'param2' => 'value2=value3'
1395			)
1396		));
1397	}
1398
1399/**
1400 * Tests that HttpSocket::buildUri can turn all kinds of uri arrays (and strings) into fully or partially qualified URI's
1401 *
1402 * @return void
1403 */
1404	public function testBuildUri() {
1405		$this->Socket->reset();
1406
1407		$r = $this->Socket->buildUri(true);
1408		$this->assertEquals(false, $r);
1409
1410		$r = $this->Socket->buildUri('foo.com');
1411		$this->assertEquals('http://foo.com/', $r);
1412
1413		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org'));
1414		$this->assertEquals('http://www.cakephp.org/', $r);
1415
1416		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'scheme' => 'https'));
1417		$this->assertEquals('https://www.cakephp.org/', $r);
1418
1419		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'port' => 23));
1420		$this->assertEquals('http://www.cakephp.org:23/', $r);
1421
1422		$r = $this->Socket->buildUri(array('path' => 'www.google.com/search', 'query' => 'q=cakephp'));
1423		$this->assertEquals('http://www.google.com/search?q=cakephp', $r);
1424
1425		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'scheme' => 'https', 'port' => 79));
1426		$this->assertEquals('https://www.cakephp.org:79/', $r);
1427
1428		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => 'foo'));
1429		$this->assertEquals('http://www.cakephp.org/foo', $r);
1430
1431		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => '/foo'));
1432		$this->assertEquals('http://www.cakephp.org/foo', $r);
1433
1434		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => '/search', 'query' => array('q' => 'HttpSocket')));
1435		$this->assertEquals('http://www.cakephp.org/search?q=HttpSocket', $r);
1436
1437		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'fragment' => 'bar'));
1438		$this->assertEquals('http://www.cakephp.org/#bar', $r);
1439
1440		$r = $this->Socket->buildUri(array(
1441			'scheme' => 'https',
1442			'host' => 'www.cakephp.org',
1443			'port' => 25,
1444			'user' => 'bob',
1445			'pass' => 'secret',
1446			'path' => '/cool',
1447			'query' => array('foo' => 'bar'),
1448			'fragment' => 'comment'
1449		));
1450		$this->assertEquals('https://bob:secret@www.cakephp.org:25/cool?foo=bar#comment', $r);
1451
1452		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'fragment' => 'bar'), '%fragment?%host');
1453		$this->assertEquals('bar?www.cakephp.org', $r);
1454
1455		$r = $this->Socket->buildUri(array('host' => 'www.cakephp.org'), '%fragment???%host');
1456		$this->assertEquals('???www.cakephp.org', $r);
1457
1458		$r = $this->Socket->buildUri(array('path' => '*'), '/%path?%query');
1459		$this->assertEquals('*', $r);
1460
1461		$r = $this->Socket->buildUri(array('scheme' => 'foo', 'host' => 'www.cakephp.org'));
1462		$this->assertEquals('foo://www.cakephp.org:80/', $r);
1463	}
1464
1465/**
1466 * Asserts that HttpSocket::parseQuery is working properly
1467 *
1468 * @return void
1469 */
1470	public function testParseQuery() {
1471		$this->Socket->reset();
1472
1473		$query = $this->Socket->parseQuery(array('framework' => 'cakephp'));
1474		$this->assertEquals(array('framework' => 'cakephp'), $query);
1475
1476		$query = $this->Socket->parseQuery('');
1477		$this->assertEquals(array(), $query);
1478
1479		$query = $this->Socket->parseQuery('framework=cakephp');
1480		$this->assertEquals(array('framework' => 'cakephp'), $query);
1481
1482		$query = $this->Socket->parseQuery('?framework=cakephp');
1483		$this->assertEquals(array('framework' => 'cakephp'), $query);
1484
1485		$query = $this->Socket->parseQuery('a&b&c');
1486		$this->assertEquals(array('a' => '', 'b' => '', 'c' => ''), $query);
1487
1488		$query = $this->Socket->parseQuery('value=12345');
1489		$this->assertEquals(array('value' => '12345'), $query);
1490
1491		$query = $this->Socket->parseQuery('a[0]=foo&a[1]=bar&a[2]=cake');
1492		$this->assertEquals(array('a' => array(0 => 'foo', 1 => 'bar', 2 => 'cake')), $query);
1493
1494		$query = $this->Socket->parseQuery('a[]=foo&a[]=bar&a[]=cake');
1495		$this->assertEquals(array('a' => array(0 => 'foo', 1 => 'bar', 2 => 'cake')), $query);
1496
1497		$query = $this->Socket->parseQuery('a[][]=foo&a[][]=bar&a[][]=cake');
1498		$expectedQuery = array(
1499			'a' => array(
1500				0 => array(
1501					0 => 'foo'
1502				),
1503				1 => array(
1504					0 => 'bar'
1505				),
1506				array(
1507					0 => 'cake'
1508				)
1509			)
1510		);
1511		$this->assertEquals($expectedQuery, $query);
1512
1513		$query = $this->Socket->parseQuery('a[][]=foo&a[bar]=php&a[][]=bar&a[][]=cake');
1514		$expectedQuery = array(
1515			'a' => array(
1516				array('foo'),
1517				'bar' => 'php',
1518				array('bar'),
1519				array('cake')
1520			)
1521		);
1522		$this->assertEquals($expectedQuery, $query);
1523
1524		$query = $this->Socket->parseQuery('user[]=jim&user[3]=tom&user[]=bob');
1525		$expectedQuery = array(
1526			'user' => array(
1527				0 => 'jim',
1528				3 => 'tom',
1529				4 => 'bob'
1530			)
1531		);
1532		$this->assertEquals($expectedQuery, $query);
1533
1534		$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';
1535		$query = $this->Socket->parseQuery($queryStr);
1536		$expectedQuery = array(
1537			'user' => array(
1538				0 => array(
1539					'items' => array(
1540						'foo',
1541						'bar'
1542					)
1543				),
1544				1 => array(
1545					'name' => 'jim',
1546					'items' => array(
1547						'personal' => array(
1548							'book',
1549							'pen'
1550						),
1551						'ball'
1552					)
1553				),
1554				'count' => '2'
1555			),
1556			'empty' => ''
1557		);
1558		$this->assertEquals($expectedQuery, $query);
1559
1560		$query = 'openid.ns=example.com&foo=bar&foo=baz';
1561		$result = $this->Socket->parseQuery($query);
1562		$expected = array(
1563			'openid.ns' => 'example.com',
1564			'foo' => array('bar', 'baz')
1565		);
1566		$this->assertEquals($expected, $result);
1567	}
1568
1569/**
1570 * Tests that HttpSocket::buildHeader can turn a given $header array into a proper header string according to
1571 * HTTP 1.1 specs.
1572 *
1573 * @return void
1574 */
1575	public function testBuildHeader() {
1576		$this->Socket->reset();
1577
1578		$r = $this->Socket->buildHeader(true);
1579		$this->assertEquals(false, $r);
1580
1581		$r = $this->Socket->buildHeader('My raw header');
1582		$this->assertEquals('My raw header', $r);
1583
1584		$r = $this->Socket->buildHeader(array('Host' => 'www.cakephp.org'));
1585		$this->assertEquals("Host: www.cakephp.org\r\n", $r);
1586
1587		$r = $this->Socket->buildHeader(array('Host' => 'www.cakephp.org', 'Connection' => 'Close'));
1588		$this->assertEquals("Host: www.cakephp.org\r\nConnection: Close\r\n", $r);
1589
1590		$r = $this->Socket->buildHeader(array('People' => array('Bob', 'Jim', 'John')));
1591		$this->assertEquals("People: Bob,Jim,John\r\n", $r);
1592
1593		$r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\nMulti Line field"));
1594		$this->assertEquals("Multi-Line-Field: This is my\r\n Multi Line field\r\n", $r);
1595
1596		$r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\n Multi Line field"));
1597		$this->assertEquals("Multi-Line-Field: This is my\r\n Multi Line field\r\n", $r);
1598
1599		$r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\n\tMulti Line field"));
1600		$this->assertEquals("Multi-Line-Field: This is my\r\n\tMulti Line field\r\n", $r);
1601
1602		$r = $this->Socket->buildHeader(array('Test@Field' => "My value"));
1603		$this->assertEquals("Test\"@\"Field: My value\r\n", $r);
1604	}
1605
1606/**
1607 * testBuildCookies method
1608 *
1609 * @return void
1610 */
1611	public function testBuildCookies() {
1612		$cookies = array(
1613			'foo' => array(
1614				'value' => 'bar'
1615			),
1616			'people' => array(
1617				'value' => 'jim,jack,johnny;',
1618				'path' => '/accounts'
1619			),
1620			'key' => 'value'
1621		);
1622		$expect = "Cookie: foo=bar; people=jim,jack,johnny\";\"; key=value\r\n";
1623		$result = $this->Socket->buildCookies($cookies);
1624		$this->assertEquals($expect, $result);
1625	}
1626
1627/**
1628 * Tests that HttpSocket::_tokenEscapeChars() returns the right characters.
1629 *
1630 * @return void
1631 */
1632	public function testTokenEscapeChars() {
1633		$this->Socket->reset();
1634
1635		$expected = array(
1636			'\x22', '\x28', '\x29', '\x3c', '\x3e', '\x40', '\x2c', '\x3b', '\x3a', '\x5c', '\x2f', '\x5b', '\x5d', '\x3f', '\x3d', '\x7b',
1637			'\x7d', '\x20', '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d',
1638			'\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d',
1639			'\x1e', '\x1f', '\x7f'
1640		);
1641		$r = $this->Socket->tokenEscapeChars();
1642		$this->assertEquals($expected, $r);
1643
1644		foreach ($expected as $key => $char) {
1645			$expected[$key] = chr(hexdec(substr($char, 2)));
1646		}
1647
1648		$r = $this->Socket->tokenEscapeChars(false);
1649		$this->assertEquals($expected, $r);
1650	}
1651
1652/**
1653 * Test that HttpSocket::escapeToken is escaping all characters as described in RFC 2616 (HTTP 1.1 specs)
1654 *
1655 * @return void
1656 */
1657	public function testEscapeToken() {
1658		$this->Socket->reset();
1659
1660		$this->assertEquals('Foo', $this->Socket->escapeToken('Foo'));
1661
1662		$escape = $this->Socket->tokenEscapeChars(false);
1663		foreach ($escape as $char) {
1664			$token = 'My-special-' . $char . '-Token';
1665			$escapedToken = $this->Socket->escapeToken($token);
1666			$expectedToken = 'My-special-"' . $char . '"-Token';
1667
1668			$this->assertEquals($expectedToken, $escapedToken, 'Test token escaping for ASCII ' . ord($char));
1669		}
1670
1671		$token = 'Extreme-:Token-	-"@-test';
1672		$escapedToken = $this->Socket->escapeToken($token);
1673		$expectedToken = 'Extreme-":"Token-"	"-""""@"-test';
1674		$this->assertEquals($expectedToken, $escapedToken);
1675	}
1676
1677/**
1678 * This tests asserts HttpSocket::reset() resets a HttpSocket instance to it's initial state (before Object::__construct
1679 * got executed)
1680 *
1681 * @return void
1682 */
1683	public function testReset() {
1684		$this->Socket->reset();
1685
1686		$initialState = get_class_vars('HttpSocket');
1687		foreach ($initialState as $property => $value) {
1688			$this->Socket->{$property} = 'Overwritten';
1689		}
1690
1691		$return = $this->Socket->reset();
1692
1693		foreach ($initialState as $property => $value) {
1694			$this->assertEquals($this->Socket->{$property}, $value);
1695		}
1696
1697		$this->assertEquals(true, $return);
1698	}
1699
1700/**
1701 * This tests asserts HttpSocket::reset(false) resets certain HttpSocket properties to their initial state (before
1702 * Object::__construct got executed).
1703 *
1704 * @return void
1705 */
1706	public function testPartialReset() {
1707		$this->Socket->reset();
1708
1709		$partialResetProperties = array('request', 'response');
1710		$initialState = get_class_vars('HttpSocket');
1711
1712		foreach ($initialState as $property => $value) {
1713			$this->Socket->{$property} = 'Overwritten';
1714		}
1715
1716		$return = $this->Socket->reset(false);
1717
1718		foreach ($initialState as $property => $originalValue) {
1719			if (in_array($property, $partialResetProperties)) {
1720				$this->assertEquals($this->Socket->{$property}, $originalValue);
1721			} else {
1722				$this->assertEquals('Overwritten', $this->Socket->{$property});
1723			}
1724		}
1725		$this->assertEquals(true, $return);
1726	}
1727
1728/**
1729 * test configuring the context from the flat keys.
1730 *
1731 * @return void
1732 */
1733	public function testConfigContext() {
1734		$this->Socket->reset();
1735		$this->Socket->request('http://example.com');
1736		$this->assertTrue($this->Socket->config['context']['ssl']['verify_peer']);
1737		$this->assertFalse($this->Socket->config['context']['ssl']['allow_self_signed']);
1738		$this->assertEquals(5, $this->Socket->config['context']['ssl']['verify_depth']);
1739		$this->assertEquals('example.com', $this->Socket->config['context']['ssl']['CN_match']);
1740		$this->assertArrayNotHasKey('ssl_verify_peer', $this->Socket->config);
1741		$this->assertArrayNotHasKey('ssl_allow_self_signed', $this->Socket->config);
1742		$this->assertArrayNotHasKey('ssl_verify_host', $this->Socket->config);
1743		$this->assertArrayNotHasKey('ssl_verify_depth', $this->Socket->config);
1744	}
1745
1746/**
1747 * Test that requests fail when peer verification fails.
1748 *
1749 * @return void
1750 */
1751	public function testVerifyPeer() {
1752		$this->skipIf(!extension_loaded('openssl'), 'OpenSSL is not enabled cannot test SSL.');
1753		$socket = new HttpSocket();
1754		try {
1755			$socket->get('https://typography.com');
1756			$this->markTestSkipped('Found valid certificate, was expecting invalid certificate.');
1757		} catch (SocketException $e) {
1758			$message = $e->getMessage();
1759			$this->skipIf(strpos($message, 'Invalid HTTP') !== false, 'Invalid HTTP Response received, skipping.');
1760			$this->assertContains('Peer certificate CN', $message);
1761			$this->assertContains('Failed to enable crypto', $message);
1762		}
1763	}
1764}