From fb1f012a2842569a933e0a7f7ac6c0c90716dae6 Mon Sep 17 00:00:00 2001
From: Barracuda Team <admin@omega8.cc>
Date: Mon, 9 Dec 2013 22:01:18 +0100
Subject: [PATCH] Issue #1559116 by mva.name, omega8cc - Make core aware of
 Nginx and PHP-FPM to avoid confusing alerts.

---
 core/includes/file.inc                             | 46 ++++++++++++++++++++++
 core/modules/file/file.install                     | 28 ++++++++++---
 .../simpletest/lib/Drupal/simpletest/TestBase.php  | 21 +++++++++-
 .../lib/Drupal/system/Tests/File/DirectoryTest.php | 36 +++++++++++++----
 .../PhpStorage/MTimeProtectedFileStorageTest.php   | 22 ++++++++++-
 5 files changed, 137 insertions(+), 16 deletions(-)

diff --git a/core/includes/file.inc b/core/includes/file.inc
index 545fca3..ca22287 100644
--- a/core/includes/file.inc
+++ b/core/includes/file.inc
@@ -554,6 +554,29 @@ function file_prepare_directory(&$directory, $options = FILE_MODIFY_PERMISSIONS,
  * Creates a .htaccess file in each Drupal files directory if it is missing.
  */
 function file_ensure_htaccess() {
+
+  // Test the web server identity.
+  $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE');
+
+  if (!isset($server_software)) {
+    // Skip this in Drush where SERVER_SOFTWARE is not set
+    // and .htaccess never used anyway.
+    $use_htaccess = FALSE;
+  }
+  elseif (preg_match("/Nginx/i", $server_software)) {
+    $use_htaccess = FALSE;
+  }
+  elseif (preg_match("/Apache/i", $server_software)) {
+    $use_htaccess = TRUE;
+  }
+  else {
+    $use_htaccess = FALSE;
+  }
+
+  if (!$use_htaccess) {
+    return;
+  }
+
   file_save_htaccess('public://', FALSE);
   $private_path = \Drupal::config('system.file')->get('path.private');
   if (!empty($private_path)) {
@@ -574,6 +597,29 @@ function file_ensure_htaccess() {
  *   The default is TRUE which indicates a private and protected directory.
  */
 function file_save_htaccess($directory, $private = TRUE) {
+
+  // Test the web server identity.
+  $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE');
+
+  if (!isset($server_software)) {
+    // Skip this in Drush where SERVER_SOFTWARE is not set
+    // and .htaccess never used anyway.
+    $use_htaccess = FALSE;
+  }
+  elseif (preg_match("/Nginx/i", $server_software)) {
+    $use_htaccess = FALSE;
+  }
+  elseif (preg_match("/Apache/i", $server_software)) {
+    $use_htaccess = TRUE;
+  }
+  else {
+    $use_htaccess = FALSE;
+  }
+
+  if (!$use_htaccess) {
+    return;
+  }
+
   if (file_uri_scheme($directory)) {
     $directory = file_stream_wrapper_uri_normalize($directory);
   }
diff --git a/core/modules/file/file.install b/core/modules/file/file.install
index c5ec889..7e91f00 100644
--- a/core/modules/file/file.install
+++ b/core/modules/file/file.install
@@ -162,18 +162,34 @@ function file_requirements($phase) {
 
   // Check the server's ability to indicate upload progress.
   if ($phase == 'runtime') {
+    $description = NULL;
     $implementation = file_progress_implementation();
     $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE');
-    $apache = strpos($server_software, 'Apache') !== FALSE;
-    $fastcgi = strpos($server_software, 'mod_fastcgi') !== FALSE || strpos($server_software, 'mod_fcgi') !== FALSE;
-    $description = NULL;
-    if (!$apache) {
+
+    // Test the web server identity.
+    if (preg_match("/Nginx/i", $server_software)) {
+      $is_nginx = TRUE;
+      $is_apache = FALSE;
+      $fastcgi = FALSE;
+    }
+    elseif (preg_match("/Apache/i", $server_software)) {
+      $is_nginx = FALSE;
+      $is_apache = TRUE;
+      $fastcgi = strpos($server_software, 'mod_fastcgi') !== FALSE || strpos($server_software, 'mod_fcgi') !== FALSE;
+    }
+    else {
+      $is_nginx = FALSE;
+      $is_apache = FALSE;
+      $fastcgi = FALSE;
+    }
+
+    if (!$is_apache && !$is_nginx) {
       $value = t('Not enabled');
-      $description = t('Your server is not capable of displaying file upload progress. File upload progress requires an Apache server running PHP with mod_php.');
+      $description = t('Your server is not capable of displaying file upload progress. File upload progress requires an Apache server running PHP with mod_php or Nginx with PHP-FPM.');
     }
     elseif ($fastcgi) {
       $value = t('Not enabled');
-      $description = t('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php and not as FastCGI.');
+      $description = t('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php or PHP-FPM and not as FastCGI.');
     }
     elseif (!$implementation && extension_loaded('apc')) {
       $value = t('Not enabled');
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index 882542e..b35bdad 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -741,7 +741,26 @@ public function run(array $methods = array()) {
       $this->verbose = TRUE;
       $this->verboseDirectory = PublicStream::basePath() . '/simpletest/verbose';
       $this->verboseDirectoryUrl = file_create_url($this->verboseDirectory);
-      if (file_prepare_directory($this->verboseDirectory, FILE_CREATE_DIRECTORY) && !file_exists($this->verboseDirectory . '/.htaccess')) {
+
+      // Test the web server identity.
+      $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE');
+
+      if (!isset($server_software)) {
+        // Skip this in Drush where SERVER_SOFTWARE is not set
+        // and .htaccess never used anyway.
+        $use_htaccess = FALSE;
+      }
+      elseif (preg_match("/Nginx/i", $server_software)) {
+        $use_htaccess = FALSE;
+      }
+      elseif (preg_match("/Apache/i", $server_software)) {
+        $use_htaccess = TRUE;
+      }
+      else {
+        $use_htaccess = FALSE;
+      }
+
+      if ($use_htaccess && file_prepare_directory($this->verboseDirectory, FILE_CREATE_DIRECTORY) && !file_exists($this->verboseDirectory . '/.htaccess')) {
         file_put_contents($this->verboseDirectory . '/.htaccess', "<IfModule mod_expires.c>\nExpiresActive Off\n</IfModule>\n");
       }
       $this->verboseClassName = str_replace("\\", "_", $class);
diff --git a/core/modules/system/lib/Drupal/system/Tests/File/DirectoryTest.php b/core/modules/system/lib/Drupal/system/Tests/File/DirectoryTest.php
index 7fd19c5..19e0120 100644
--- a/core/modules/system/lib/Drupal/system/Tests/File/DirectoryTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/File/DirectoryTest.php
@@ -91,14 +91,34 @@ function testFileCheckDirectoryHandling() {
     // Test that the directory has the correct permissions.
     $this->assertDirectoryPermissions($directory, octdec(\Drupal::config('system.file')->get('chmod.directory')));
 
-    // Remove .htaccess file to then test that it gets re-created.
-    @drupal_unlink(file_default_scheme() . '://.htaccess');
-    $this->assertFalse(is_file(file_default_scheme() . '://.htaccess'), 'Successfully removed the .htaccess file in the files directory.', 'File');
-    file_ensure_htaccess();
-    $this->assertTrue(is_file(file_default_scheme() . '://.htaccess'), 'Successfully re-created the .htaccess file in the files directory.', 'File');
-    // Verify contents of .htaccess file.
-    $file = file_get_contents(file_default_scheme() . '://.htaccess');
-    $this->assertEqual($file, "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nOptions None\nOptions +FollowSymLinks", 'The .htaccess file contains the proper content.', 'File');
+    // Test the web server identity.
+    $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE');
+
+    if (!isset($server_software)) {
+      // Skip this in Drush where SERVER_SOFTWARE is not set
+      // and .htaccess never used anyway.
+      $use_htaccess = FALSE;
+    }
+    elseif (preg_match("/Nginx/i", $server_software)) {
+      $use_htaccess = FALSE;
+    }
+    elseif (preg_match("/Apache/i", $server_software)) {
+      $use_htaccess = TRUE;
+    }
+    else {
+      $use_htaccess = FALSE;
+    }
+
+    if ($use_htaccess) {
+      // Remove .htaccess file to then test that it gets re-created.
+      @drupal_unlink(file_default_scheme() . '://.htaccess');
+      $this->assertFalse(is_file(file_default_scheme() . '://.htaccess'), 'Successfully removed the .htaccess file in the files directory.', 'File');
+      file_ensure_htaccess();
+      $this->assertTrue(is_file(file_default_scheme() . '://.htaccess'), 'Successfully re-created the .htaccess file in the files directory.', 'File');
+      // Verify contents of .htaccess file.
+      $file = file_get_contents(file_default_scheme() . '://.htaccess');
+      $this->assertEqual($file, "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nOptions None\nOptions +FollowSymLinks", 'The .htaccess file contains the proper content.', 'File');
+    }
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageTest.php b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageTest.php
index 1e28e36..34c64d0 100644
--- a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageTest.php
+++ b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageTest.php
@@ -78,9 +78,29 @@ function testSecurity() {
     $this->assertSame(fileperms($expected_filename) & 0777, 0444);
     $this->assertSame(fileperms($expected_directory) & 0777, 0777);
 
+    // Test the web server identity.
+    $server_software = \Drupal::request()->server->get('SERVER_SOFTWARE');
+
+    if (!isset($server_software)) {
+      // Skip this in Drush where SERVER_SOFTWARE is not set
+      // and .htaccess never used anyway.
+      $use_htaccess = FALSE;
+    }
+    elseif (preg_match("/Nginx/i", $server_software)) {
+      $use_htaccess = FALSE;
+    }
+    elseif (preg_match("/Apache/i", $server_software)) {
+      $use_htaccess = TRUE;
+    }
+    else {
+      $use_htaccess = FALSE;
+    }
+
     // Ensure the root directory for the bin has a .htaccess file denying web
     // access.
-    $this->assertSame(file_get_contents($expected_root_directory . '/.htaccess'), "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nDeny from all\nOptions None\nOptions +FollowSymLinks");
+    if ($use_htaccess) {
+      $this->assertSame(file_get_contents($expected_root_directory . '/.htaccess'), "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nDeny from all\nOptions None\nOptions +FollowSymLinks");
+    }
 
     // Ensure that if the file is replaced with an untrusted one (due to another
     // script's file upload vulnerability), it does not get loaded. Since mtime
-- 
1.8.3.4 (Apple Git-47)

