Skip to content

Commit

Permalink
Add handling of origin port to reply if set
Browse files Browse the repository at this point in the history
  • Loading branch information
rbairwell committed Apr 20, 2016
1 parent fc3439b commit 83d9185
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 84 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
v0.3.6 - 20th Apr 2016
Add handling of origin port to reply if sent.
v0.3.5 - 19th Apr 2016
Add handling of origin protocol scheme to reply if sent.
v0.3.0 - 13th Apr 2016
Expand Down
63 changes: 41 additions & 22 deletions src/MiddlewareCors/Traits/Parse.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,26 +170,17 @@ protected function parseOrigin(ServerRequestInterface $request) : string

$this->addLog('Processing origin of "'.$origin.'"');
// lowercase the user provided origin for comparison purposes.
$origin = strtolower($origin);
$parsed = parse_url($origin);
$protocol = '';
$origin = strtolower($origin);
$parsed = parse_url($origin);
$originHost = $origin;
if (true === is_array($parsed)) {
if (true === isset($parsed['host'])) {
$this->addLog('Parsed a hostname from origin: '.$parsed['host']);
$origin = $parsed['host'];
} else {
$this->addLog('Unable to parse hostname from origin');
}
if (true === isset($parsed['scheme'])) {
$this->addLog('Parsed a protocol from origin: '.$parsed['scheme']);
$protocol = $parsed['scheme'].'://';
} else {
$this->addLog('Unable to parse protocol/scheme from origin');
$originHost = $parsed['host'];
}
} else {
$this->addLog('Unable to parse URL from origin of '.$origin);
$parsed = [];
}

// read the current origin setting
$originSetting = $this->settings['origin'];

Expand All @@ -209,11 +200,11 @@ protected function parseOrigin(ServerRequestInterface $request) : string
foreach ($originSetting as $item) {
// see if the origin matches (the parseOriginMatch function supports
// wildcards)
$matched = $this->parseOriginMatch($item, $origin);
$matched = $this->parseOriginMatch($item, $originHost);
// if anything else but '' was returned, then we have a valid match.
if ('' !== $matched) {
$this->addLog('Iterator found a matched origin of '.$matched);
$matched = $this->addProtocolIfNeeded($protocol, $matched);
$matched = $this->addProtocolPortIfNeeded($matched, $parsed);
return $matched;
}
}
Expand All @@ -223,31 +214,59 @@ protected function parseOrigin(ServerRequestInterface $request) : string
// is to try to match it as a string (if applicable)
if ('' === $matched && true === is_string($originSetting)) {
$this->addLog('Attempting to match origin as string');
$matched = $this->parseOriginMatch($originSetting, $origin);
$matched = $this->parseOriginMatch($originSetting, $originHost);
}

// return the matched setting (may be '' to indicate nothing matched)
$matched = $this->addProtocolIfNeeded($protocol, $matched);
$matched = $this->addProtocolPortIfNeeded($matched, $parsed);
return $matched;
}//end parseOrigin()

/**
* Returns the protocol if needed.
*
* @param string $protocol Protocol to add if matched is not empty or *.
* @param string $matched The matched host.
* @param string $matched The matched host.
* @param array $parsed The results of parse_url.
*
* @return string
*/
protected function addProtocolIfNeeded(string $protocol, string $matched) : string
protected function addProtocolPortIfNeeded(string $matched, array $parsed) : string
{
if ('' === $matched || '*' === $matched) {
$return = $matched;

return $return;
}
$protocol = 'https://';
$port = 0;
if (true === isset($parsed['scheme'])) {
$this->addLog('Parsed a protocol from origin: '.$parsed['scheme']);
$protocol = $parsed['scheme'].'://';
} else {
$this->addLog('Unable to parse protocol/scheme from origin');
}
if (true === isset($parsed['port'])) {
$this->addLog('Parsed a port from origin: '.$parsed['port']);
$port = (int) $parsed['port'];
} else {
$this->addLog('Unable to parse port from origin');
}

if (0 === $port) {
if ('https://' === $protocol) {
$port = 443;
} else {
$port = 80;
}
}

if (('http://' === $protocol && 80 === $port) || ('https://' === $protocol && 443 === $port)) {
$return = $protocol.$matched;
} else {
$return = $protocol.$matched.':'.$port;
}
return $return;
}//end addProtocolIfNeeded()
}//end addProtocolPortIfNeeded()

/**
* Check to see if an origin string matches an item (wildcarded or not).
Expand Down
56 changes: 28 additions & 28 deletions tests/MiddlewareCors/PreflightTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -359,35 +359,35 @@ public function testInvokerPreflightValidAcrmValidAcrh()
*/
public function testInvokerPreflightAllTheThings()
{
$results = $this->runInvoke(
[
'method' => 'OPTIONS',
'setHeaders' => [
'origin' => 'example.com',
'access-control-request-method' => 'put',
'access-control-request-headers' => 'x-jeff, x-smith, x-jones'
],
'configuration' => [
'allowMethods' => ['PUT', 'POST'],
'allowHeaders' => 'x-jeff,x-smith,x-jones',
'maxAge' => 300,
'allowCredentials' => true,
'origin' => 'example.com'
$results = $this->runInvoke(
[
'method' => 'OPTIONS',
'setHeaders' => [
'origin' => 'http://example.com',
'access-control-request-method' => 'put',
'access-control-request-headers' => 'x-jeff, x-smith, x-jones'
],
'configuration' => [
'allowMethods' => ['PUT', 'POST'],
'allowHeaders' => 'x-jeff,x-smith,x-jones',
'maxAge' => 300,
'allowCredentials' => true,
'origin' => 'example.com'
]
]
]
);
$expected = [
'withHeader:Access-Control-Allow-Origin' => 'example.com',
'withHeader:Access-Control-Allow-Credentials' => 'true',
'withHeader:Access-Control-Allow-Methods' => 'PUT, POST',
'withHeader:Access-Control-Allow-Headers' => 'x-jeff, x-smith, x-jones',
'withHeader:Access-Control-Max-Age' => 300,
'withAddedHeader:Vary' => 'Origin',
'withStatus' => '204:No Content',
'withoutHeader:Content-Type' => true,
'withoutHeader:Content-Length' => true
];
$this->arraysAreSimilar($expected, $results);
);
$expected = [
'withHeader:Access-Control-Allow-Origin' => 'http://example.com',
'withHeader:Access-Control-Allow-Credentials' => 'true',
'withHeader:Access-Control-Allow-Methods' => 'PUT, POST',
'withHeader:Access-Control-Allow-Headers' => 'x-jeff, x-smith, x-jones',
'withHeader:Access-Control-Max-Age' => 300,
'withAddedHeader:Vary' => 'Origin',
'withStatus' => '204:No Content',
'withoutHeader:Content-Type' => true,
'withoutHeader:Content-Length' => true
];
$this->arraysAreSimilar($expected, $results);
}//end testInvokerPreflightAllTheThings()

/**
Expand Down
Loading

0 comments on commit 83d9185

Please sign in to comment.