瀏覽代碼

[FrameworkBundle] updated to support 405 Method Not Found responses

Kris Wallsmith 14 年之前
父節點
當前提交
2217a0d7e4

+ 5 - 1
src/Symfony/Bundle/FrameworkBundle/Command/RouterApacheDumperCommand.php

@@ -32,7 +32,8 @@ class RouterApacheDumperCommand extends Command
     {
         $this
             ->setDefinition(array(
-                new InputArgument('script_name', InputArgument::OPTIONAL, 'The script name of the application\'s front controller.')
+                new InputArgument('script_name', InputArgument::OPTIONAL, 'The script name of the application\'s front controller.'),
+                new InputOption('base-uri', null, InputOption::VALUE_REQUIRED, 'The base URI'),
             ))
             ->setName('router:dump-apache')
             ->setDescription('Dumps all routes as Apache rewrite rules')
@@ -58,6 +59,9 @@ EOF
         if ($input->getArgument('script_name')) {
             $dumpOptions['script_name'] = $input->getArgument('script_name');
         }
+        if ($input->getOption('base-uri')) {
+            $dumpOptions['base_uri'] = $input->getOption('base-uri');
+        }
 
         $dumper = new ApacheMatcherDumper($router->getRouteCollection());
 

+ 7 - 17
src/Symfony/Bundle/FrameworkBundle/Controller/ExceptionController.php

@@ -29,10 +29,13 @@ class ExceptionController extends ContainerAware
      * @param FlattenException     $exception A FlattenException instance
      * @param DebugLoggerInterface $logger    A DebugLoggerInterface instance
      * @param string               $format    The format to use for rendering (html, xml, ...)
+     * @param integer              $code      An HTTP response code
+     * @param string               $message   An HTTP response status message
+     * @param array                $headers   HTTP response headers
      *
      * @throws \InvalidArgumentException When the exception template does not exist
      */
-    public function showAction(FlattenException $exception, DebugLoggerInterface $logger = null, $format = 'html')
+    public function showAction(FlattenException $exception, DebugLoggerInterface $logger = null, $format = 'html', $code = 500, $message = null, array $headers = array())
     {
         $this->container->get('request')->setRequestFormat($format);
 
@@ -45,8 +48,6 @@ class ExceptionController extends ContainerAware
             $currentContent .= ob_get_clean();
         }
 
-        $code = $this->getStatusCode($exception);
-
         $name = $this->container->get('kernel')->isDebug() ? 'exception' : 'error';
         if ($this->container->get('kernel')->isDebug() && 'html' == $format) {
             $name = 'exception_full';
@@ -63,27 +64,16 @@ class ExceptionController extends ContainerAware
             $template,
             array(
                 'status_code'    => $code,
-                'status_text'    => Response::$statusTexts[$code],
+                'status_text'    => $message ?: Response::$statusTexts[$code],
                 'exception'      => $exception,
                 'logger'         => $logger,
                 'currentContent' => $currentContent,
             )
         );
 
-        $response->setStatusCode($code);
+        $response->setStatusCode($code, $message);
+        $response->headers->replace($headers);
 
         return $response;
     }
-
-    protected function getStatusCode(FlattenException $exception)
-    {
-        switch ($exception->getClass()) {
-            case 'Symfony\Component\Security\Core\Exception\AccessDeniedException':
-                return 403;
-            case 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException':
-                return 404;
-            default:
-                return 500;
-        }
-    }
 }

+ 20 - 4
src/Symfony/Bundle/FrameworkBundle/RequestListener.php

@@ -14,9 +14,13 @@ namespace Symfony\Bundle\FrameworkBundle;
 use Symfony\Component\HttpKernel\Log\LoggerInterface;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\RouterInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Routing\Matcher\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Matcher\Exception\NotFoundException;
+use Symfony\Component\Routing\RouterInterface;
 
 /**
  * RequestListener.
@@ -83,7 +87,9 @@ class RequestListener
         }
 
         // add attributes based on the path info (routing)
-        if (false !== $parameters = $this->router->match($request->getPathInfo())) {
+        try {
+            $parameters = $this->router->match($request->getPathInfo());
+
             if (null !== $this->logger) {
                 $this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], json_encode($parameters)));
             }
@@ -93,8 +99,18 @@ class RequestListener
             if ($locale = $request->attributes->get('_locale')) {
                 $request->getSession()->setLocale($locale);
             }
-        } elseif (null !== $this->logger) {
-            $this->logger->err(sprintf('No route found for %s', $request->getPathInfo()));
+        } catch (NotFoundException $e) {
+            $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo());
+            if (null !== $this->logger) {
+                $this->logger->err($message);
+            }
+            throw new NotFoundHttpException('Not Found', $message, 0, $e);
+        } catch (MethodNotAllowedException $e) {
+            $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), strtoupper(implode(', ', $e->getAllowedMethods())));
+            if (null !== $this->logger) {
+                $this->logger->err($message);
+            }
+            throw new MethodNotAllowedHttpException($e->getAllowedMethods(), 'Method Not Allowed', $message, 0, $e);
         }
     }
 }