如何使用EssentialAction

时间:2014-12-07 18:20:18

标签: scala playframework

我有一个自定义的主体解析器,它将请求主体流式传输到Amazon S3实例,我想在上传文件之前进行验证。

在请求的标头中,我可以访问内容大小和用户的身份验证令牌。通过这两件事,我可以验证用户是否有权上传文件。

阅读Play!的文档后,似乎EssentialActionAction Composition是可行的方法。

这是我的控制器方法,没有任何装饰:

def upload = Action(streamingBodyParser(streamConstructor)) { request =>
   ...
}

我尝试过创建自定义基本操作并在我的身体解析操作之前使用它,但我无法正确理解语法:

class HasEnoughSpace(action: EssentialAction) extends EssentialAction {
  override def apply(request: RequestHeader): EssentialAction = {
    val maybeToken = request.headers.get("X-Auth-Token")
    maybeToken match {
      case Some(t) => {

      }
      case _ => 
    }
  }
}

def upload = HasEnoughSpace { Action(streamingBodyParser(streamConstructor)) { request => 
  ...
}

我也尝试使用新的ActionBuilder方法,但在允许我进行验证之前仍然解析了主体。

有没有办法通过EssentialAction实现这一目标?有没有更好的方法来实现我在解析正文之前验证标题的目标?

1 个答案:

答案 0 :(得分:2)

是的,这正是EssentialAction的用途。它使您能够检查请求标题,但忽略正文,对您的情况应该是什么 EssentialActions基本上只是函数接受RequestHeader并返回Iteratee [Array [Byte],Result]:

trait EssentialAction extends (RequestHeader => Iteratee[Array[Byte], Result]) with Handler

因此,如果将HasEnoughSpace操作重写为创建EssentialAction而不是尝试扩展EssentialAction特征的函数,则会更容易:

 def HasEnoughSpace(action: EssentialAction): EssentialAction =  EssentialAction { request =>
      val token = request.headers.get("X-Auth-Token")
      val contentSize = request.headers.get(play.api.http.HeaderNames.CONTENT_LENGTH)
      (token, contentSize) match {
        // perform validation if both headers are present
        case (Some(_), Some(len)) if validateContentLength(len) => {
          action(request)
        }
        case _ =>
          // replace with your client error
          Done(Unauthorized("401 No Token\n"))
      }
    }

在上面的代码中,您仍然需要编写validateContentLength函数。