diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
index a4ec691..f29e0b0 100644
--- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Language\LanguageManager;
 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
 use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 /**
@@ -41,6 +42,10 @@ public function __construct(LanguageManager $language_manager) {
    *   The event to process.
    */
   public function onRespond(FilterResponseEvent $event) {
+    if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
+      return;
+    }
+
     $response = $event->getResponse();
 
     // Set the X-UA-Compatible HTTP header to force IE to use the most recent
diff --git a/core/lib/Drupal/Core/HtmlPageController.php b/core/lib/Drupal/Core/HtmlPageController.php
index 7d14ac0..31ab5ac 100644
--- a/core/lib/Drupal/Core/HtmlPageController.php
+++ b/core/lib/Drupal/Core/HtmlPageController.php
@@ -52,7 +52,7 @@ public function content(Request $request, $_content) {
     // require an _internal route.  For examples, see:
     // https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml
     // https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.php
-    $attributes = $request->attributes;
+    $attributes = clone($request->attributes);
     $controller = $_content;
 
     // We need to clean off the derived information and such so that the
@@ -62,8 +62,13 @@ public function content(Request $request, $_content) {
 
     $response = $this->container->get('http_kernel')->forward($controller, $attributes->all(), $request->query->all());
 
-    $page_content = $response->getContent();
+    // For successful (HTTP status 200) responses, decorate with blocks.
+    // @todo Are there any other statuses for which we should also do this?
+    if ($response->isOk()) {
+      $page_content = $response->getContent();
+      $response = new Response(drupal_render_page($page_content));
+    }
 
-    return new Response(drupal_render_page($page_content));
+    return $response;
   }
 }
diff --git a/core/lib/Drupal/Core/Routing/PathMatcher.php b/core/lib/Drupal/Core/Routing/PathMatcher.php
index f037d9a..a5fa272 100644
--- a/core/lib/Drupal/Core/Routing/PathMatcher.php
+++ b/core/lib/Drupal/Core/Routing/PathMatcher.php
@@ -56,7 +56,7 @@ public function __construct(Connection $connection, $table = 'router') {
    */
   public function matchRequestPartial(Request $request) {
 
-    $path = rtrim($request->getPathInfo(), '/');
+    $path = '/' . $request->attributes->get('system_path');
 
     $parts = array_slice(array_filter(explode('/', $path)), 0, MatcherDumper::MAX_PARTS);
 
diff --git a/core/modules/user/lib/Drupal/user/UserRouteController.php b/core/modules/user/lib/Drupal/user/UserRouteController.php
new file mode 100644
index 0000000..f095a7e
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/UserRouteController.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\user\UserRouteController.
+ */
+
+namespace Drupal\user;
+
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+
+/**
+ * Returns responses for User module routes.
+ */
+class UserRouteController {
+
+  /**
+   * Returns the user registration form.
+   */
+  function register() {
+    // @todo Remove once access control is integrated with new routing system:
+    //   http://drupal.org/node/1793520.
+    if (!user_register_access()) {
+      throw new AccessDeniedHttpException();
+    }
+
+    $account = entity_create('user', array());
+    return entity_get_form($account, 'register');
+  }
+
+}
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 68b45ea..3c8ed67 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1070,11 +1070,6 @@ function user_is_logged_in() {
   return (bool) $GLOBALS['user']->uid;
 }
 
-function user_register() {
-  $account = entity_create('user', array());
-  return entity_get_form($account, 'register');
-}
-
 function user_register_access() {
   return user_is_anonymous() && (config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY);
 }
@@ -1160,9 +1155,14 @@ function user_menu() {
 
   $items['user/register'] = array(
     'title' => 'Create new account',
-    'page callback' => 'user_register',
-    'access callback' => 'user_register_access',
     'type' => MENU_LOCAL_TASK,
+    // @todo This route is now declared in user.routing.yml, so the below are
+    //   only needed for drupal_valid_path(). Without a non-empty (but not
+    //   necessarily valid) page callback, _menu_router_build() overrides the
+    //   access callback to 0. Remove once drupal_valid_path works with the new
+    //   routing system: http://drupal.org/node/1793520.
+    'page callback' => 'NOT_USED',
+    'access callback' => 'user_register_access',
   );
 
   $items['user/password'] = array(
diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml
new file mode 100644
index 0000000..5e11fab
--- /dev/null
+++ b/core/modules/user/user.routing.yml
@@ -0,0 +1,4 @@
+user_register:
+  pattern: '/user/register'
+  defaults:
+    _content: '\Drupal\user\UserRouteController::register'
