使用LIFT处理HTTP OPTIONS动词

时间:2012-04-05 19:39:57

标签: scala lift options cors

我正在使用LIFT来提供RESTful API,我希望这个API允许使用CORS(跨源资源共享)进行POST的请求。我确实有CORS处理GET请求。

我遇到了麻烦,因为跨源POST首先在给定的URL上调用OPTIONS,我还没想出如何用LIFT接受OPTIONS请求。

我的问题是:我需要混合或写入serve{}块,以便我可以在LIFT中为给定路径提供HTTP谓词OPTIONS?

现在使用curl我得到:

curl -X OPTIONS http://localhost:8080/path => [404]

我正在使用LIFT 2.4-M5和Scala 2.9.1

编辑:根据pr1001的建议,我试图像这样延长RestHelper

import net.liftweb.http.provider._
import net.liftweb.http._

trait RestHelper extends net.liftweb.http.rest.RestHelper {
    protected object Options {
        // Compile error here with options_?
        // because net.liftweb.http.Req uses LIFT's RequestType
        def unapply(r: Req): Option[(List[String], Req)] =
            if (r.requestType.options_?) Some(r.path.partPath -> r) else None
    }
}

@serializable
abstract class RequestType extends net.liftweb.http.RequestType {
    def options_? : Boolean = false
}

@serializable
case object OptionsRequest extends RequestType {
    override def options_? = true
    def method = "OPTIONS"
}

object RequestType extends net.liftweb.http.RequestType {
    def apply(req: HTTPRequest): net.liftweb.http.RequestType = {
        req.method.toUpperCase match {
            case "OPTIONS" => UnknownRequest("OPTIONS")
            case _ => net.liftweb.http.RequestType.apply(req)
        }
    }

    def method = super.method
}

我觉得这是我需要做的更多工作,因为我不想用自己的RequestType impl扩展Req

当谈到Scala时,我肯定处于技能水平较低的水平,所以我希望有人可以提供更简单的解决方案,因为我确信有些东西我不知道。

2 个答案:

答案 0 :(得分:1)

您使用的是RestHelper吗?如果是这样,您可以指定要回复的请求类型并返回LiftResponse。 Lift(尚)中没有OptionRequest用于您传递给serve()的部分函数,​​但您应该可以使用自己的版本扩展RequestType。使用UnknownRequest - 与UnknownRequest("OPTION")一样 - 可能也可以解决问题。

这也可能值得提出mailing list,因为CORS支持将是一个有用的补充......

答案 1 :(得分:1)

非常感谢pr1001的建议。我能够使用以下内容:

import net.liftweb.http._

class RequestTypeImproved(requestType: RequestType) {
    def options_? : Boolean = requestType.method == "OPTIONS"
}

trait RestHelper extends net.liftweb.http.rest.RestHelper {
    implicit def req2ReqImproved(requestType: RequestType): RequestTypeImproved = {
        new RequestTypeImproved(requestType)
    }

    protected object Options {
        def unapply(r: Req): Option[(List[String], Req)] =
            if (r.requestType.options_?) Some(r.path.partPath -> r) else None
    }
}

然后:

serve {
    case req @ "path" Options _ => {
        LiftResponse(...)
    }
}