diff --git a/lib/Cake/Network/Http/Adapter/Stream.php b/lib/Cake/Network/Http/Adapter/Stream.php index fe5fa59cc1d..2db6fb7f779 100644 --- a/lib/Cake/Network/Http/Adapter/Stream.php +++ b/lib/Cake/Network/Http/Adapter/Stream.php @@ -48,6 +48,9 @@ protected function _buildContext(Request $request, $options) { $url = $request->url(); $scheme = parse_url($url, PHP_URL_SCHEME); + if ($scheme === 'https') { + $this->_buildSslContext($request, $options); + } $this->_context = stream_context_create([ $scheme => $this->_contextOptions ]); @@ -120,6 +123,37 @@ protected function _buildOptions(Request $request, $options) { } } +/** + * Build SSL options for the request. + * + * @param Request $request + * @param array $options + */ + protected function _buildSslContext($request, $options) { + $sslOptions = [ + 'ssl_verify_peer', + 'ssl_verify_depth', + 'ssl_allow_self_signed', + 'ssl_cafile', + 'ssl_local_cert', + 'ssl_passphrase', + ]; + if (empty($options['ssl_cafile'])) { + $options['ssl_cafile'] = CAKE . 'Config' . DS . 'cacert.pem'; + } + if (!empty($options['ssl_verify_host'])) { + $url = $request->url(); + $host = parse_url($url, PHP_URL_HOST); + $this->_contextOptions['CN_match'] = $host; + } + foreach ($sslOptions as $key) { + if (isset($options[$key])) { + $name = substr($key, 4); + $this->_contextOptions[$name] = $options[$key]; + } + } + } + protected function _send() { } diff --git a/lib/Cake/Test/TestCase/Network/Http/Adapter/StreamTest.php b/lib/Cake/Test/TestCase/Network/Http/Adapter/StreamTest.php index 5eb98a8f0dd..35a88fe8fb1 100644 --- a/lib/Cake/Test/TestCase/Network/Http/Adapter/StreamTest.php +++ b/lib/Cake/Test/TestCase/Network/Http/Adapter/StreamTest.php @@ -133,4 +133,32 @@ public function testSendContextContentArray() { $this->assertContains('my value', $result['content']); } +/** + * Test send() + context options for SSL. + * + * @return void + */ + public function testSendContextSsl() { + $request = new Request(); + $request->url('https://localhost.com/test.html'); + $options = [ + 'ssl_verify_host' => true, + 'ssl_verify_peer' => true, + 'ssl_verify_depth' => 9000, + 'ssl_allow_self_signed' => false, + ]; + + $this->stream->send($request, $options); + $result = $this->stream->contextOptions(); + $expected = [ + 'CN_match' => 'localhost.com', + 'verify_peer' => true, + 'verify_depth' => 9000, + 'allow_self_signed' => false, + ]; + foreach ($expected as $k => $v) { + $this->assertEquals($v, $result[$k]); + } + } + }