Skip to content
Browse files

ENHANCEMENT Sapphire Doesn't Read HTTP Headers (fixes #6311)

  • Loading branch information...
1 parent 627a291 commit a60f03f28e462edb700239a9242c5e3ac2059725 @ajshort ajshort committed with chillu
Showing with 71 additions and 5 deletions.
  1. +36 −5 control/Director.php
  2. +35 −0 tests/control/DirectorTest.php
View
41 control/Director.php
@@ -87,11 +87,18 @@ static function direct($url) {
array_merge((array)$_POST, (array)$_FILES),
@file_get_contents('php://input')
);
-
- // @todo find better way to extract HTTP headers
- if(isset($_SERVER['HTTP_ACCEPT'])) $req->addHeader("Accept", $_SERVER['HTTP_ACCEPT']);
- if(isset($_SERVER['CONTENT_TYPE'])) $req->addHeader("Content-Type", $_SERVER['CONTENT_TYPE']);
- if(isset($_SERVER['HTTP_REFERER'])) $req->addHeader("Referer", $_SERVER['HTTP_REFERER']);
+
+ // Load the request headers. If we're not running on Apache, then we
+ // need to manually extract the headers from the $_SERVER array.
+ if (function_exists('apache_request_headers')) {
+ $headers = apache_request_headers();
+ } else {
+ $headers = self::extract_request_headers($_SERVER);
+ }
+
+ foreach ($headers as $header => $value) {
+ $req->addHeader($header, $value);
+ }
// Load the session into the controller
$session = new Session(isset($_SESSION) ? $_SESSION : null);
@@ -536,7 +543,31 @@ public static function is_site_url($url) {
$relativeUrl = Director::makeRelative($url);
return (bool)self::is_relative_url($relativeUrl);
}
+
+ /**
+ * Takes a $_SERVER data array and extracts HTTP request headers.
+ *
+ * @param array $data
+ * @return array
+ */
+ protected static function extract_request_headers(array $server) {
+ $headers = array();
+
+ foreach($server as $key => $value) {
+ if(substr($key, 0, 5) == 'HTTP_') {
+ $key = substr($key, 5);
+ $key = strtolower(str_replace('_', ' ', $key));
+ $key = str_replace(' ', '-', ucwords($key));
+ $headers[$key] = $value;
+ }
+ }
+
+ if(isset($server['CONTENT_TYPE'])) $headers['Content-Type'] = $server['CONTENT_TYPE'];
+ if(isset($server['CONTENT_LENGTH'])) $headers['Content-Length'] = $server['CONTENT_LENGTH'];
+ return $headers;
+ }
+
/**
* Given a filesystem reference relative to the site root, return the full file-system path.
*
View
35 tests/control/DirectorTest.php
@@ -225,6 +225,41 @@ function testForceSSLWithPatternDoesNotMatchOtherPages() {
$this->assertFalse($output);
}
+ /**
+ * @covers Director::extract_request_headers()
+ */
+ public function testExtractRequestHeaders() {
+ $request = array(
+ 'REDIRECT_STATUS' => '200',
+ 'HTTP_HOST' => 'host',
+ 'HTTP_USER_AGENT' => 'User Agent',
+ 'HTTP_ACCEPT' => 'text/html',
+ 'HTTP_ACCEPT_LANGUAGE' => 'en-us',
+ 'HTTP_COOKIE' => 'PastMember=1',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ 'REQUEST_METHOD' => 'GET',
+ 'REQUEST_URI' => '/',
+ 'SCRIPT_NAME' => '/sapphire/main.php',
+ 'CONTENT_TYPE' => 'text/xml',
+ 'CONTENT_LENGTH' => 10
+ );
+
+ $headers = array(
+ 'Host' => 'host',
+ 'User-Agent' => 'User Agent',
+ 'Accept' => 'text/html',
+ 'Accept-Language' => 'en-us',
+ 'Cookie' => 'PastMember=1',
+ 'Content-Type' => 'text/xml',
+ 'Content-Length' => '10'
+ );
+
+ $method = new ReflectionMethod('Director', 'extract_request_headers');
+ $method->setAccessible(true);
+
+ $this->assertEquals($headers, $method->invoke(null, $request));
+ }
+
}
class DirectorTestRequest_Controller extends Controller implements TestOnly {

0 comments on commit a60f03f

Please sign in to comment.
Something went wrong with that request. Please try again.