Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

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