diff --git a/core/core.services.yml b/core/core.services.yml
index 6ad63cf..58c73bf 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -111,7 +111,7 @@ services:
     class: Drupal\Core\Form\FormBuilder
     arguments: ['@module_handler', '@keyvalue.expirable', '@event_dispatcher', '@url_generator', '@string_translation', '@?csrf_token', '@?http_kernel']
     calls:
-      - [setRequest, ['@?request']]
+      - [setRequest, ['@?request=']]
   keyvalue:
     class: Drupal\Core\KeyValueStore\KeyValueFactory
     arguments: ['@service_container', '@settings']
@@ -215,6 +215,7 @@ services:
   request:
     class: Symfony\Component\HttpFoundation\Request
     synthetic: true
+    synchronized: true
   event_dispatcher:
     class: Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher
     arguments: ['@service_container']
@@ -541,7 +542,7 @@ services:
     calls:
       - [setContainer, ['@service_container']]
   exception_listener:
-    class: Symfony\Component\HttpKernel\EventListener\ExceptionListener
+    class: Drupal\Core\EventSubscriber\ExceptionListener
     tags:
       - { name: event_subscriber }
     arguments: [['@exception_controller', execute]]
diff --git a/core/lib/Drupal/Core/Controller/ExceptionController.php b/core/lib/Drupal/Core/Controller/ExceptionController.php
index df5eb07..e33a00a 100644
--- a/core/lib/Drupal/Core/Controller/ExceptionController.php
+++ b/core/lib/Drupal/Core/Controller/ExceptionController.php
@@ -146,7 +146,13 @@ public function on403Html(FlattenException $exception, Request $request) {
         $request->query->set('destination', $system_path);
       }
 
-      $subrequest = Request::create($request->getBaseUrl() . '/' . $path, 'get', array('destination' => $system_path, '_exception_statuscode' => 403), $request->cookies->all(), array(), $request->server->all());
+      if ($request->getMethod() === 'POST') {
+        $subrequest = Request::create($request->getBaseUrl() . '/' . $path, 'POST', array('destination' => $system_path, '_exception_statuscode' => 403) + $request->request->all(), $request->cookies->all(), array(), $request->server->all());
+        $subrequest->query->set('destination', $system_path);
+      }
+      else {
+        $subrequest = Request::create($request->getBaseUrl() . '/' . $path, 'GET', array('destination' => $system_path, '_exception_statuscode' => 403), $request->cookies->all(), array(), $request->server->all());
+      }
 
       // The active trail is being statically cached from the parent request to
       // the subrequest, like any other static.  Unfortunately that means the
@@ -223,7 +229,13 @@ public function on404Html(FlattenException $exception, Request $request) {
       // @todo The create() method expects a slash-prefixed path, but we store a
       //   normal system path in the site_404 variable.
 
-      $subrequest = Request::create($request->getBaseUrl() . '/' . $path, 'get', array('destination' => $system_path, '_exception_statuscode' => 403), $request->cookies->all(), array(), $request->server->all());
+      if ($request->getMethod() === 'POST') {
+        $subrequest = Request::create($request->getBaseUrl() . '/' . $path, 'POST', array('destination' => $system_path, '_exception_statuscode' => 404) + $request->request->all(), $request->cookies->all(), array(), $request->server->all());
+        $subrequest->query->set('destination', $system_path);
+      }
+      else {
+        $subrequest = Request::create($request->getBaseUrl() . '/' . $path, 'GET', array('destination' => $system_path, '_exception_statuscode' => 404), $request->cookies->all(), array(), $request->server->all());
+      }
 
       // The active trail is being statically cached from the parent request to
       // the subrequest, like any other static.  Unfortunately that means the
diff --git a/core/lib/Drupal/Core/EventSubscriber/ExceptionListener.php b/core/lib/Drupal/Core/EventSubscriber/ExceptionListener.php
new file mode 100644
index 0000000..0944703
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionListener.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\EventSubscriber\ExceptionListener.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\Debug\Exception\FlattenException;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\EventListener\ExceptionListener as ExceptionListenerBase;
+use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
+
+/**
+ * Extends the symfony exception listener to support POST subrequests.
+ */
+class ExceptionListener extends ExceptionListenerBase {
+
+  /**
+   * {@inheritdoc}
+   *
+   * In contrast to the symfony base class, do not override POST requests to GET
+   * requests.
+   */
+  protected function duplicateRequest(\Exception $exception, Request $request) {
+    $attributes = array(
+      '_controller' => $this->controller,
+      'exception' => FlattenException::create($exception),
+      'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : NULL,
+      'format' => $request->getRequestFormat(),
+    );
+    return $request->duplicate(NULL, NULL, $attributes);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index cd82931..9e6daad 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -199,7 +199,7 @@ public function buildForm($form_id, array &$form_state) {
     $form_id = $this->getFormId($form_id, $form_state);
 
     if (!isset($form_state['input'])) {
-      $form_state['input'] = $form_state['method'] == 'get' ? $_GET : $_POST;
+      $form_state['input'] = $form_state['method'] == 'get' ? $this->request->query->all() : $this->request->request->all();
     }
 
     if (isset($_SESSION['batch_form_state'])) {
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
index 6dc144c..89376c8 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -67,7 +67,7 @@ public static function getInfo() {
   function setUp() {
     parent::setUp();
 
-    $this->request = Request::create('http://example.com/');
+    $this->request = Request::createFromGlobals();
     $this->container->set('request', $this->request);
 
     $admin_user = $this->drupalCreateUser(array('administer languages', 'translate interface', 'access administration pages', 'administer blocks'));
diff --git a/core/modules/system/lib/Drupal/system/Tests/Session/SessionHttpsTest.php b/core/modules/system/lib/Drupal/system/Tests/Session/SessionHttpsTest.php
index aff57d1..02523d0 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Session/SessionHttpsTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Session/SessionHttpsTest.php
@@ -33,7 +33,7 @@ public static function getInfo() {
 
   public function setUp() {
     parent::setUp();
-    $this->request = Request::create('http://example.com/');
+    $this->request = Request::createFromGlobals();
     $this->container->set('request', $this->request);
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php b/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php
index 02bb177..e7cbdb2 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php
@@ -35,8 +35,7 @@ public function setUp() {
 
     // Flood backends need a request object. Create a dummy one and insert it
     // to the container.
-    $this->request = Request::create('http://example.com/');
-    $this->request->server->set('REMOTE_ADDR', '3.3.3.3');
+    $this->request = Request::createFromGlobals();
     $this->container->set('request', $this->request);
   }
 
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/ExceptionListenerTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/ExceptionListenerTest.php
new file mode 100644
index 0000000..6aa70c9
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/ExceptionListenerTest.php
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\EventSubscriber\ExceptionListenerTest.
+ */
+
+namespace Drupal\Tests\Core\EventSubscriber;
+
+use Drupal\Component\Utility\Url;
+use Drupal\Core\EventSubscriber\ExceptionListener;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
+
+/**
+ * Tests the exception listener.
+ *
+ * @group Drupal
+ * @group Routing
+ *
+ * @see \Drupal\Core\EventSubscriber\ExceptionListener
+ */
+class ExceptionListenerTest extends UnitTestCase {
+
+  /**
+   * The tested exception listener.
+   *
+   * @var \Drupal\Core\EventSubscriber\ExceptionListener
+   */
+  protected $exceptionListener;
+
+  /**
+   * The mocked HTTP kernel.
+   *
+   * @var \Symfony\Component\HttpKernel\HttpKernelInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $kernel;
+
+  /**
+   * The PHP error log settings before the test.
+   *
+   * @var string
+   */
+  protected $errorLog;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Exception listener',
+      'description' => 'Tests the exception listener',
+      'group' => 'Routing',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $this->exceptionListener = new ExceptionListener('example');
+    $this->kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
+
+    // You can't create an exception in PHP without throwing it. Store the
+    // current error_log, and disable it temporarily.
+    $this->errorLog = ini_set('error_log', file_exists('/dev/null') ? '/dev/null' : 'nul');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function tearDown() {
+    ini_set('error_log', $this->errorLog);
+  }
+
+  /**
+   * Tests onHandleException with a POST request.
+   */
+  public function testHandleWithPostRequest() {
+    $request = Request::create('/test', 'POST', array('name' => 'druplicon', 'pass' => '12345'));
+
+    $this->kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) {
+      return new Response($request->getMethod());
+    }));
+
+    $event = new GetResponseForExceptionEvent($this->kernel, $request, 'foo', new \Exception('foo'));
+
+    $this->exceptionListener->onKernelException($event);
+
+    $response = $event->getResponse();
+    $this->assertEquals('POST name=druplicon&pass=12345', $response->getContent() . " " . Url::buildQuery($request->request->all()));
+  }
+
+  /**
+   * Tests onHandleException with a GET request.
+   */
+  public function testHandleWithGetRequest() {
+    $request = Request::create('/test', 'GET', array('name' => 'druplicon', 'pass' => '12345'));
+
+    $this->kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) {
+      return new Response($request->getMethod() . ' ' . Url::buildQuery($request->query->all()));
+    }));
+
+    $event = new GetResponseForExceptionEvent($this->kernel, $request, 'foo', new \Exception('foo'));
+    $this->exceptionListener->onKernelException($event);
+
+    $response = $event->getResponse();
+    $this->assertEquals('GET name=druplicon&pass=12345 ', $response->getContent() . " " . Url::buildQuery($request->request->all()));
+  }
+
+}
