我有一个自定义的主体解析器,它将请求主体流式传输到Amazon S3实例,我想在上传文件之前进行验证。
在请求的标头中,我可以访问内容大小和用户的身份验证令牌。通过这两件事,我可以验证用户是否有权上传文件。
阅读Play!的文档后,似乎EssentialAction
或Action 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实现这一目标?有没有更好的方法来实现我在解析正文之前验证标题的目标?
答案 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函数。