\Zend\Http\Request - Uncaught InvalidArgumentException when the request method is not considered valid. #6385
Comments
I'm experiencing this issue too, but in a different way. I've seen an increase of 500 errors in my server logs lately, due to spam bots often sending requests with invalid HTTP methods (e.g. It's not a big problem with It would be nice if it was possible to just return a sane response (i.e. 400 or 405 for HTTP requests) in case a request could not be correctly created. Maybe short circuiting to |
Short circuiting would be great but I'm not sure the Request class should even throw an exception if the HTTP method is not recognized. From the RFC: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
|
I agree with @masom -- we shouldn't likely raise an exception here by default, as the standard indicates that custom methods may be allowed and/or the spec could be amended to add methods. That said, I'd love to also have a listener ala @stefanotorresi, registered by default via the "route" event at high priority that would check against the standard set of request methods, and return a 405 response if it falls outside that range. This would short-circuit the most expensive operations by default, but not be so noisy as to create PHP log messages. Configuration would allow opting out of the listener, as well as defining the methods allowed. Essentially, this might look as follows: namespace Zend\Mvc;
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
class HttpMethodListener extends AbstractListenerAggregate
{
protected $allowedMethods = array(
'DELETE',
'GET',
'HEAD',
'OPTIONS',
'PATCH',
'POST',
'PUT',
);
protected $enabled = true;
public function __construct($enabled = true, array $allowedMethods = null)
{
$this->enabled = (bool) $enabled;
if ($this->enabled && is_array($allowedMethods)) {
$this->allowedMethods = $allowedMethods;
}
}
public function attach(EventManagerInterface $events)
{
if (! $this->enabled) {
return;
}
$this->listeners[] = $events->attach(
MvcEvent::EVENT_ROUTE,
array($this, 'onRoute'),
10000
);
}
public function onRoute(MvcEvent $e)
{
$request = $e->getRequest();
if (! $request
|| ! method_exists($request, 'getMethod')
) {
return;
}
$method = $request->getMethod();
if (in_array($method, $this->allowedMethods)) {
return;
}
$response = $e->getResponse();
$response->setStatusCode(405);
return $response;
}
} With a factory like this: class HttpMethodListenerFactory
{
public function __invoke($services)
{
$config = $services->get('Config');
if (! isset($config['http_methods_listener'])) {
return new HttpMethodListener();
}
$config = $config['http_methods_listener'];
$enabled = array_key_exists('enabled', $config)
? $config['enabled']
: true;
$allowedMethods = (isset($config['allowed_methods']) && is_array($config['allowed_methods']))
? $config['allowed_methods']
: null;
return new HttpMethodListener($enabled, $allowedMethods);
}
} |
Handled in #6385 |
this link goes back to the same issue link |
What does that mean? |
Handled in #6385 points back to this same url |
Oh, right! Linking #6409 instead. Thanks for noticing! |
Our production site hit this when a third-party scanner hit us.
The request parsing seems to happen during the application init before userland code can interact with the exception.
Is there a way to catch the exception / ignore it?
ZF 2.2.7
The text was updated successfully, but these errors were encountered: