2012-04-05 9 views
1

Ich verwende LIFT, um eine RESTful-API zu bedienen, und ich möchte, dass diese API Anfragen mit CORS (Cross-Origin Resource Sharing) für POST zulassen. Ich habe CORS mit GET-Anfragen arbeiten.HTTP-OPTIONS Verb-Behandlung mit LIFT

Ich habe Probleme, weil Herkunftsort-POSTs zuerst OPTIONS über die angegebene URL aufrufen, und ich habe nicht herausgefunden, wie man OPTIONS-Anfragen mit LIFT akzeptiert.

Meine Frage ist: Was muss ich mischen oder schreiben Sie an meine serve{} Block, so dass ich das HTTP-Verb OPTIONS für einen bestimmten Pfad in LIFT zulassen kann?

Gerade jetzt mit curl ich:

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

Ich bin mit LIFT 2.4-M5 und Scala 2.9.1

EDIT: Basierend auf pr1001 ‚s Vorschlag, ich habe versucht RestHelper zu verlängern so wie:

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 
} 

ich fühle mich wie diese mehr Arbeit, dann sollte ich tun muss, weil ich will nicht meine eigenen haben verlängern Req mit RequestType impl.

Ich bin definitiv auf der unteren Ebene der Fähigkeiten, wenn es um Scala geht, also hoffe ich, jemand kann eine etwas einfachere Lösung bieten, weil ich sicher bin, dass es etwas gibt, was ich vermisse.

Antwort

1

Verwenden Sie RestHelper? Wenn dies der Fall ist, geben Sie die Art der Anfrage an, auf die Sie antworten möchten, und geben Sie eine LiftResponse zurück. Es gibt keine OptionRequest in Lift (noch) in der Teilfunktion zu verwenden, die Sie an serve() übergeben, aber Sie sollten in der Lage sein, RequestType mit Ihrer eigenen Version zu erweitern. Mit UnknownRequest - wie in UnknownRequest("OPTION") - könnte auch der Trick.

Dies könnte auch wert sein, auf dem mailing list Erziehung, als CORS Unterstützung eine sinnvolle Ergänzung wäre ...

+0

Ja, ich bin mit RestHelper. Ich werde sehen, wie schwer es wäre, RequestType zu erweitern. Das sind sehr gute Ideen, danke! Ich werde diese Antwort in 24 Stunden annehmen, wenn niemand eine bessere/einfachere Antwort gefunden hat. –

+0

Gut. Bitte bringen Sie dies auf die Mailingliste, wenn es funktioniert, da ich denke, dass es eine nützliche Zusatzfunktion wäre. – pr1001

+0

Ich habe die Frage mit meiner eigenen dummen Implementierung aktualisiert, die einen Rat benötigt. Ich poste natürlich auch auf der Mailingliste. –

1

Vielen Dank für seinen Vorschlag pr1001. Ich konnte es mit der folgenden Arbeit bekommen:

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 
    } 
} 

Dann:

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