2

我正在编写一个文件上传处理程序 Catalyst。我正在尝试限制最大文件大小。为此,我制作了一个插件(基于此处的答案)。这是我检查文件大小的代码:

before 'prepare_body' => sub {
    my $c = shift;

    my $req = $c->request;
    my $length = $req->headers->{"content-length"};
    if ($length > 10000)
    {
        $c->stash->{errors} = "File upload error";
        # how do I abort the upload?
    }
};

这可以正确检测太大的文件,但我一生都无法弄清楚如何中止上传。理想情况下,它也应该到达控制器/动作。谁能给我指点?非常感谢。

4

2 回答 2

2

很简单,您可能不应该这样做。从插件代码到中止处理所做的任何事情都会破坏用户代码以一种很好的方式处理这种情况的能力(例如,通过给出一个验证错误或一个很好的错误页面,而不是一个 Catalyst 异常页面) .

然而,一切都没有丢失。为什么不尝试这样的事情呢?

around 'prepare_body' => sub {
  my ($orig, $self) = (shift, shift);
  my ($c) = @_;

  my $max_length = $c->config->{'Plugin::WhateverMyNameIs'}->{max_request_size};
  $max_length = 1_000_000 unless defined $max_length; # default
  my $length = $c->engine->read_length;
  if ($length <= $max_length) { # ok, go ahead
    $self->$orig(@_);
  } else {
    $c->stash->{request_body_aborted} = 1;
  }
};

如果您的请求过大,这将停止读取,但它会让分派正常进行——这意味着您将希望在您的操作、begin操作或链根中编写一些代码,以检查$c->stash->{request_body_aborted}并做一些适当的事情——无论是设置表单验证错误,还是调用$c->error("Request too large"); $c->detach或其他什么。它也是可配置的,任何插件都应该如此。

于 2010-07-11T22:51:08.203 回答
0

我认为这需要在链条的早期发生。如果您有标头,则数据包已经创建。

也许你可以试试: $c->detach(); 或者可能遍历 $c->stack 数组并删除可能已添加的与您的上传相关的操作。

于 2010-06-30T14:47:24.527 回答