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