2014-12-07 15 views
0

我有一个自定义的身体解析器,它将请求正文流式传输到Amazon S3实例,并且我想在上传文件之前进行验证。如何使用EssentialAction

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

在阅读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

是的,这正是EssentialAction的用途。它使您能够检查请求标题,但忽略正文,对于您的情况应该足够。
EssentialActions被bascially只是功能采取RequestHeader并返回Iteratee [数组[字节],结果]:

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功能。

+0

感谢您的回答!下班回家后我会尽快检查一下。 – eliot 2014-12-08 18:58:25