diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index be9821d..8d1211c 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -826,7 +826,6 @@ protected function initializeRequestGlobals(Request $request) {
     global $base_url;
     // Set and derived from $base_url by this function.
     global $base_path, $base_root;
-    global $base_secure_url, $base_insecure_url;
 
     // @todo Refactor with the Symfony Request object.
     if (isset($base_url)) {
@@ -864,8 +863,6 @@ protected function initializeRequestGlobals(Request $request) {
         $base_path = '/';
       }
     }
-    $base_secure_url = str_replace('http://', 'https://', $base_url);
-    $base_insecure_url = str_replace('https://', 'http://', $base_url);
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Session/SessionHttpsTest.php b/core/modules/system/src/Tests/Session/SessionHttpsTest.php
index cd52f3d..8205e98 100644
--- a/core/modules/system/src/Tests/Session/SessionHttpsTest.php
+++ b/core/modules/system/src/Tests/Session/SessionHttpsTest.php
@@ -10,6 +10,7 @@
 use Drupal\simpletest\WebTestBase;
 use Symfony\Component\HttpFoundation\Request;
 use Drupal\Component\Utility\Crypt;
+use Drupal\Core\Session\AccountInterface;
 
 /**
  * Ensure that when running under HTTPS two session cookies are generated.
@@ -19,6 +20,20 @@
 class SessionHttpsTest extends WebTestBase {
 
   /**
+   * The name of the session cookie when using HTTP.
+   *
+   * @var string
+   */
+  protected $insecureSessionName;
+
+  /**
+   * The name of the session cookie when using HTTPS.
+   *
+   * @var string
+   */
+  protected $secureSessionName;
+
+  /**
    * Modules to enable.
    *
    * @var array
@@ -27,81 +42,68 @@ class SessionHttpsTest extends WebTestBase {
 
   protected function setUp() {
     parent::setUp();
-    $this->request = Request::createFromGlobals();
-    $this->container->get('request_stack')->push($this->request);
-  }
 
-  public function testHttpsSession() {
-    if ($this->request->isSecure()) {
-      $secure_session_name = $this->getSessionName();
-      $insecure_session_name = substr($this->getSessionName(), 1);
+    $request = Request::createFromGlobals();
+    if ($request->isSecure()) {
+      $this->secureSessionName = $this->getSessionName();
+      $this->insecureSessionName = substr($this->getSessionName(), 1);
     }
     else {
-      $secure_session_name = 'S' . $this->getSessionName();
-      $insecure_session_name = $this->getSessionName();
+      $this->secureSessionName = 'S' . $this->getSessionName();
+      $this->insecureSessionName = $this->getSessionName();
     }
+  }
 
+  public function testHttpsSession() {
     $user = $this->drupalCreateUser(array('access administration pages'));
 
     // Test HTTPS session handling by altering the form action to submit the
     // login form through https.php, which creates a mock HTTPS request.
-    $this->drupalGet('user/login');
-    $form = $this->xpath('//form[@id="user-login-form"]');
-    $form[0]['action'] = $this->httpsUrl('user/login');
-    $edit = array('name' => $user->getUsername(), 'pass' => $user->pass_raw);
-    $this->drupalPostForm(NULL, $edit, t('Log in'));
+    $this->loginHttps($user);
 
     // Test a second concurrent session.
     $this->curlClose();
-    $this->drupalGet('user/login');
-    $form = $this->xpath('//form[@id="user-login-form"]');
-    $form[0]['action'] = $this->httpsUrl('user/login');
-    $this->drupalPostForm(NULL, $edit, t('Log in'));
+    $this->curlCookies = array();
+    $this->loginHttps($user);
 
     // Check secure cookie on secure page.
-    $this->assertTrue($this->cookies[$secure_session_name]['secure'], 'The secure cookie has the secure attribute');
+    $this->assertTrue($this->cookies[$this->secureSessionName]['secure'], 'The secure cookie has the secure attribute');
     // Check insecure cookie is not set.
-    $this->assertFalse(isset($this->cookies[$insecure_session_name]));
-    $ssid = $this->cookies[$secure_session_name]['value'];
+    $this->assertFalse(isset($this->cookies[$this->insecureSessionName]));
+    $ssid = $this->cookies[$this->secureSessionName]['value'];
     $this->assertSessionIds($ssid, 'Session has a non-empty SID and a correct secure SID.');
-    $cookie = $secure_session_name . '=' . $ssid;
 
     // Verify that user is logged in on secure URL.
-    $this->curlClose();
-    $this->drupalGet($this->httpsUrl('admin/config'), array(), array('Cookie: ' . $cookie));
+    $this->drupalGet($this->httpsUrl('admin/config'));
     $this->assertText(t('Configuration'));
     $this->assertResponse(200);
 
     // Verify that user is not logged in on non-secure URL.
-    $this->curlClose();
-    $this->drupalGet($this->httpUrl('admin/config'), array(), array('Cookie: ' . $cookie));
+    $this->drupalGet($this->httpUrl('admin/config'));
     $this->assertNoText(t('Configuration'));
     $this->assertResponse(403);
 
     // Verify that empty SID cannot be used on the non-secure site.
     $this->curlClose();
-    $cookie = $insecure_session_name . '=';
-    $this->drupalGet($this->httpUrl('admin/config'), array(), array('Cookie: ' . $cookie));
+    $this->curlCookies = array($this->insecureSessionName . '=');
+    $this->drupalGet($this->httpUrl('admin/config'));
     $this->assertResponse(403);
 
     // Test HTTP session handling by altering the form action to submit the
     // login form through http.php, which creates a mock HTTP request on HTTPS
     // test environments.
     $this->curlClose();
-    $this->drupalGet('user/login');
-    $form = $this->xpath('//form[@id="user-login-form"]');
-    $form[0]['action'] = $this->httpUrl('user/login');
-    $edit = array('name' => $user->getUsername(), 'pass' => $user->pass_raw);
-    $this->drupalPostForm(NULL, $edit, t('Log in'));
+    $this->curlCookies = array();
+    $this->loginHttp($user);
     $this->drupalGet($this->httpUrl('admin/config'));
     $this->assertResponse(200);
-    $sid = $this->cookies[$insecure_session_name]['value'];
+    $sid = $this->cookies[$this->insecureSessionName]['value'];
     $this->assertSessionIds($sid, '', 'Session has the correct SID and an empty secure SID.');
 
     // Verify that empty secure SID cannot be used on the secure site.
     $this->curlClose();
-    $cookie = $secure_session_name . '=';
-    $this->drupalGet($this->httpsUrl('admin/config'), array(), array('Cookie: ' . $cookie));
+    $this->curlCookies = array($this->secureSessionName . '=');
+    $this->drupalGet($this->httpsUrl('admin/config'));
     $this->assertResponse(403);
 
     // Clear browser cookie jar.
@@ -109,6 +111,103 @@ public function testHttpsSession() {
   }
 
   /**
+   * Log in a user via HTTP.
+   *
+   * Note that the parents $session_id and $loggedInUser is not updated.
+   */
+  protected function loginHttp(AccountInterface $account) {
+    $this->drupalGet('user/login');
+
+    // Alter the form action to submit the login form through http.php, which
+    // creates a mock HTTP request on HTTPS test environments.
+    $form = $this->xpath('//form[@id="user-login-form"]');
+    $form[0]['action'] = $this->httpUrl('user/login');
+    $edit = array('name' => $account->getUsername(), 'pass' => $account->pass_raw);
+
+    // When posting directly to the HTTP or HTTPS mock front controller, the
+    // location header on the returned response is an absolute URL. That URL
+    // needs to be converted into a request to the respective mock front
+    // controller in order to retrieve the target page. Because the URL in the
+    // location header needs to be modified, it is necessary to disable the
+    // automatic redirects normally performed by parent::curlExec().
+    $maximum_redirects = $this->maximumRedirects;
+    $this->maximumRedirects = 0;
+    $this->drupalPostForm(NULL, $edit, t('Log in'));
+    $this->maximumRedirects = $maximum_redirects;
+
+    // Follow the location header.
+    $path = $this->getPathFromLocationHeader(FALSE);
+    $this->drupalGet($this->httpUrl($path));
+    $this->assertResponse(200);
+  }
+
+  /**
+   * Log in a user via HTTPS.
+   *
+   * Note that the parents $session_id and $loggedInUser is not updated.
+   */
+  protected function loginHttps(AccountInterface $account) {
+    $this->drupalGet('user/login');
+
+    // Alter the form action to submit the login form through https.php, which
+    // creates a mock HTTPS request on HTTP test environments.
+    $form = $this->xpath('//form[@id="user-login-form"]');
+    $form[0]['action'] = $this->httpsUrl('user/login');
+    $edit = array('name' => $account->getUsername(), 'pass' => $account->pass_raw);
+
+    // When posting directly to the HTTP or HTTPS mock front controller, the
+    // location header on the returned response is an absolute URL. That URL
+    // needs to be converted into a request to the respective mock front
+    // controller in order to retrieve the target page. Because the URL in the
+    // location header needs to be modified, it is necessary to disable the
+    // automatic redirects normally performed by parent::curlExec().
+    $maximum_redirects = $this->maximumRedirects;
+    $this->maximumRedirects = 0;
+    $this->drupalPostForm(NULL, $edit, t('Log in'));
+    $this->maximumRedirects = $maximum_redirects;
+
+    // When logging in via the HTTPS mock, the child site will issue a session
+    // cookie with the secure attribute set. While this cookie will be stored in
+    // the curl handle, it will not be used on subsequent requests via the HTTPS
+    // mock, unless when operating in a true HTTPS environment. Therefore it is
+    // necessary to manually collect the session cookie and add it to the
+    // curlCookies property such that it will be used on subsequent requests via
+    // the HTTPS mock.
+    $this->curlCookies = array($this->secureSessionName . '=' . $this->cookies[$this->secureSessionName]['value']);
+
+    // Follow the location header.
+    $path = $this->getPathFromLocationHeader(TRUE);
+    $this->drupalGet($this->httpsUrl($path));
+    $this->assertResponse(200);
+  }
+
+  /**
+   * Extract internal path from the location header on the response.
+   */
+  protected function getPathFromLocationHeader($https = FALSE, $response_code = 303) {
+    // Generate the base_url.
+    $base_url = $this->container->get('url_generator')->generateFromRoute('<front>', [], ['absolute' => TRUE]);
+    if ($https) {
+      $base_url = str_replace('http://', 'https://', $base_url);
+    }
+    else {
+      $base_url = str_replace('https://', 'http://', $base_url);
+    }
+
+    // The mock front controllers (http.php and https.php) add the script name
+    // to $_SERVER['REQEUST_URI'] and friends. Therefore it is necessary to
+    // strip that also.
+    $base_url .= 'index.php/';
+
+    // Extract relative path from location header.
+    $this->assertResponse($response_code);
+    $location = $this->drupalGetHeader('location');
+
+    $this->assertIdentical(strpos($location, $base_url), 0, 'Location header contains expected base URL');
+    return substr($location, strlen($base_url));
+  }
+
+  /**
    * Test that there exists a session with two specific session IDs.
    *
    * @param $sid
@@ -134,12 +233,10 @@ protected function assertSessionIds($sid, $assertion_text) {
    *   A Drupal path such as 'user/login'.
    *
    * @return
-   *   An absolute URL.
+   *   URL prepared for the https.php mock front controller.
    */
   protected function httpsUrl($url) {
-    global $base_url;
-    $this->request->server->set('HTTPS', 'on');
-    return $base_url . '/core/modules/system/tests/https.php/' . $url;
+    return 'core/modules/system/tests/https.php/' . $url;
   }
 
   /**
@@ -149,10 +246,10 @@ protected function httpsUrl($url) {
    *   A Drupal path such as 'user/login'.
    *
    * @return
-   *   An absolute URL.
+   *   URL prepared for the http.php mock front controller.
    */
   protected function httpUrl($url) {
-    global $base_url;
-    return $base_url . '/core/modules/system/tests/http.php/' . $url;
+    return 'core/modules/system/tests/http.php/' . $url;
   }
+
 }
diff --git a/core/modules/system/tests/http.php b/core/modules/system/tests/http.php
index dfb0366..0185636 100644
--- a/core/modules/system/tests/http.php
+++ b/core/modules/system/tests/http.php
@@ -12,9 +12,6 @@
 
 $autoloader = require_once 'autoload.php';
 
-// Set a global variable to indicate a mock HTTP request.
-$is_http_mock = !empty($_SERVER['HTTPS']);
-
 // Change to HTTP.
 $_SERVER['HTTPS'] = NULL;
 ini_set('session.cookie_secure', FALSE);
diff --git a/core/modules/system/tests/https.php b/core/modules/system/tests/https.php
index 038b4e6..95ebed8 100644
--- a/core/modules/system/tests/https.php
+++ b/core/modules/system/tests/https.php
@@ -15,9 +15,6 @@
 
 $autoloader = require_once 'autoload.php';
 
-// Set a global variable to indicate a mock HTTPS request.
-$is_https_mock = empty($_SERVER['HTTPS']);
-
 // Change to HTTPS.
 $_SERVER['HTTPS'] = 'on';
 foreach ($_SERVER as &$value) {
diff --git a/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php b/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php
index a17cd5a..3901cd6 100644
--- a/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php
+++ b/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php
@@ -8,7 +8,6 @@
 namespace Drupal\session_test\EventSubscriber;
 
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -43,20 +42,8 @@ public function onKernelRequestSessionTest(GetResponseEvent $event) {
    *   The Event to process.
    */
   public function onKernelResponseSessionTest(FilterResponseEvent $event) {
-    $response = $event->getResponse();
-    if ($response instanceOf RedirectResponse) {
-      // Force the redirection to go to a non-secure page after being on a
-      // secure page through https.php.
-      global $base_insecure_url, $is_https_mock;
-      // Alter the redirect to use HTTP when using a mock HTTPS request through
-      // https.php because form submissions would otherwise redirect to a
-      // non-existent HTTPS site.
-      if (!empty($is_https_mock)) {
-        $path = $base_insecure_url . '/' . $response->getTargetUrl();
-        $response->setTargetUrl($path);
-      }
-    }
     // Set header for session testing.
+    $response = $event->getResponse();
     $response->headers->set('X-Session-Empty', $this->emptySession);
   }
 
@@ -66,9 +53,9 @@ public function onKernelResponseSessionTest(FilterResponseEvent $event) {
    * @return array
    *   An array of event listener definitions.
    */
-  static function getSubscribedEvents() {
-    $events[KernelEvents::RESPONSE][] = array('onKernelResponseSessionTest', 300);
-    $events[KernelEvents::REQUEST][] = array('onKernelRequestSessionTest', 100);
+  public static function getSubscribedEvents() {
+    $events[KernelEvents::RESPONSE][] = array('onKernelResponseSessionTest');
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestSessionTest');
     return $events;
   }
 
