Skip to content

Commit

Permalink
Integrate CorsBuilder into Response.
Browse files Browse the repository at this point in the history
This maintains compatiblity with previous releases, and also allows the
builder to be used for addtional options.
  • Loading branch information
markstory committed Nov 21, 2015
1 parent 423f2e9 commit 719e9da
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 38 deletions.
3 changes: 2 additions & 1 deletion src/Network/CorsBuilder.php
Expand Up @@ -27,7 +27,8 @@ public function allowOrigin($domain)
if (!preg_match($domain['preg'], $this->_origin)) {
continue;
}
$this->_response->header('Access-Control-Allow-Origin', $this->_origin);
$value = $domain['original'] === '*' ? '*' : $this->_origin;
$this->_response->header('Access-Control-Allow-Origin', $value);
break;
}
return $this;
Expand Down
48 changes: 11 additions & 37 deletions src/Network/Response.php
Expand Up @@ -1351,51 +1351,25 @@ public function cookie($options = null)
* @param string|array $allowedDomains List of allowed domains, see method description for more details
* @param string|array $allowedMethods List of HTTP verbs allowed
* @param string|array $allowedHeaders List of HTTP headers allowed
* @return void
* @return \Cake\Network\CorsBuilder A builder object the provides a fluent interface for defining
* additional CORS headers.
*/
public function cors(Request $request, $allowedDomains, $allowedMethods = [], $allowedHeaders = [])
{
$origin = $request->header('Origin');
$ssl = $request->is('ssl');
$builder = new CorsBuilder($this, $origin, $ssl);
if (!$origin) {
return;
return $builder;
}

$allowedDomains = $this->_normalizeCorsDomains((array)$allowedDomains, $request->is('ssl'));
foreach ($allowedDomains as $domain) {
if (!preg_match($domain['preg'], $origin)) {
continue;
}
$this->header('Access-Control-Allow-Origin', $domain['original'] === '*' ? '*' : $origin);
$allowedMethods && $this->header('Access-Control-Allow-Methods', implode(', ', (array)$allowedMethods));
$allowedHeaders && $this->header('Access-Control-Allow-Headers', implode(', ', (array)$allowedHeaders));
break;
$builder->allowOrigin($allowedDomains);
if ($allowedMethods) {
$builder->allowMethods((array)$allowedMethods);
}
}

/**
* Normalize the origin to regular expressions and put in an array format
*
* @param array $domains Domain names to normalize.
* @param bool $requestIsSSL Whether it's a SSL request.
* @return array
*/
protected function _normalizeCorsDomains($domains, $requestIsSSL = false)
{
$result = [];
foreach ($domains as $domain) {
if ($domain === '*') {
$result[] = ['preg' => '@.@', 'original' => '*'];
continue;
}

$original = $preg = $domain;
if (strpos($domain, '://') === false) {
$preg = ($requestIsSSL ? 'https://' : 'http://') . $domain;
}
$preg = '@' . str_replace('*', '.*', $domain) . '@';
$result[] = compact('original', 'preg');
if ($allowedHeaders) {
$builder->allowHeaders((array)$allowedHeaders);
}
return $result;
return $builder;
}

/**
Expand Down
5 changes: 5 additions & 0 deletions tests/TestCase/Network/CorsBuilderTest.php
Expand Up @@ -27,6 +27,11 @@ public function testAllowOriginNoOrigin()
*/
public function testAllowOrigin()
{
$response = new Response();
$builder = new CorsBuilder($response, 'http://www.example.com');
$this->assertSame($builder, $builder->allowOrigin('*'));
$this->assertHeader('*', $response, 'Access-Control-Allow-Origin');

$response = new Response();
$builder = new CorsBuilder($response, 'http://www.example.com');
$this->assertSame($builder, $builder->allowOrigin(['*.example.com', '*.foo.com']));
Expand Down

0 comments on commit 719e9da

Please sign in to comment.