 core/core.services.yml                             |  4 ++
 .../EventSubscriber/ExceptionJsonSubscriber.php    | 11 +++++
 core/lib/Drupal/Core/Routing/MethodFilter.php      | 48 ++++++++++++++++++++++
 3 files changed, 63 insertions(+)

diff --git a/core/core.services.yml b/core/core.services.yml
index bbc9e8e..60184b2 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -885,6 +885,10 @@ services:
     class: Drupal\Core\Routing\RequestFormatRouteFilter
     tags:
       - { name: route_filter }
+  method_filter:
+    class: Drupal\Core\Routing\MethodFilter
+    tags:
+      - { name: route_filter }
   content_type_header_matcher:
     class: Drupal\Core\Routing\ContentTypeHeaderMatcher
     tags:
diff --git a/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
index c06adee..399cdb9 100644
--- a/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
@@ -76,4 +76,15 @@ public function on406(GetResponseForExceptionEvent $event) {
     $event->setResponse($response);
   }
 
+  /**
+   * Handles a 415 error for JSON.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
+   *   The event to process.
+   */
+  public function on415(GetResponseForExceptionEvent $event) {
+    $response = new JsonResponse(['message' => $event->getException()->getMessage()], Response::HTTP_UNSUPPORTED_MEDIA_TYPE);
+    $event->setResponse($response);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Routing/MethodFilter.php b/core/lib/Drupal/Core/Routing/MethodFilter.php
new file mode 100644
index 0000000..6d3c2e0
--- /dev/null
+++ b/core/lib/Drupal/Core/Routing/MethodFilter.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Routing\MethodFilter.
+ */
+
+namespace Drupal\Core\Routing;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * Filters routes based on the HTTP method.
+ */
+class MethodFilter implements RouteFilterInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function filter(RouteCollection $collection, Request $request) {
+    $method = $request->getMethod();
+
+    $all_supported_methods = [];
+
+    foreach ($collection as $name => $route) {
+      $supported_methods = $route->getMethods();
+      $all_supported_methods = array_merge($supported_methods, $all_supported_methods);
+      if (!in_array($method, $supported_methods)) {
+        $collection->remove($name);
+      }
+    }
+    if (count($collection)) {
+      return $collection;
+    }
+    throw new MethodNotAllowedException(array_unique($all_supported_methods));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies(Route $route) {
+    return TRUE;
+  }
+
+}
