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