2012-04-05 6 views
1

Я использую LIFT для обслуживания API RESTful, и я хочу, чтобы этот API разрешал запросы с использованием CORS (совместное использование ресурсов Cross-Origin) для POST. У меня есть CORS, работающий с запросами GET.HTTP OPTIONS обработка глаголов с LIFT

У меня возникли проблемы, потому что отправные POST-запросы с первого начала вызывают OPTIONS на указанном URL-адресе, и я не понял, как принимать запросы OPTIONS с LIFT.

Мой вопрос: Что мне нужно для микширования или записи в моем блоке serve{}, чтобы я мог разрешать опции глагола HTTP для данного пути в LIFT?

Сейчас с помощью локон я получаю:

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

Я использую LIFT 2,4-M5 и Scala 2.9.1

EDIT: На основании предложения pr1001 «s, я пытался продлить 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 
} 

Я чувствую, что это больше работы, то я должен нужно сделать, потому что я не хочу, чтобы продлить Req с моим собственным RequestType impl.

Я определенно на более низком уровне навыков, когда речь заходит о Scala, поэтому я надеюсь, что кто-то может предложить немного более простое решение, потому что я уверен, что чего-то не хватает.

ответ

1

Вы используете RestHelper? Если это так, вы должны указать тип запроса, на который хотите ответить, и вернуть LiftResponse. Нет OptionRequest в Лифт (все же) для использования в частичной функции, которую вы передаете в serve(), но у вас должна быть возможность продлить RequestType с помощью своей собственной версии. Использование UnknownRequest - как в UnknownRequest("OPTION") - также может сделать трюк.

Это также может быть стоит воспитывающим на mailing list, так как поддержка CORS будет полезным дополнением ...

+0

Да, я использую RestHelper. Я посмотрю, как трудно было бы расширить RequestType. Это очень хорошие идеи, спасибо! Я приму этот ответ в течение 24 часов, если никто не придумал лучшего/более легкого ответа. –

+0

Хорошо. Пожалуйста, принесите это в список рассылки, если он работает, так как я думаю, что это было бы полезным дополнением. – pr1001

+0

Я обновил вопрос своей собственной глупой реализацией, которая нуждается в некоторых советах. Конечно, я также отправлю в список рассылки. –

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(...) 
    } 
}