如何根据Catalyst中的文件大小取消文件上载

时间:2010-06-22 05:51:59

标签: perl catalyst

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

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?
    }
};

这可以正确检测太大的文件,但我不能为我的生活找出如何中止上传。理想情况下,它也应该达到控制器/动作。任何人都可以给我指针吗?非常感谢。

2 个答案:

答案 0 :(得分: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或其他任何内容。它也是可配置的,因为任何插件都应该是。

答案 1 :(得分:0)

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

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