2010-12-20 5 views
4

Ich habe ein seltsames Problem mit einem kleinen Restlet-Service, den ich als Übung bauen. Die Anwendung soll mit einigem XML (specifically TwiML, wie es für Twilio gemeint ist) auf einem HTTP-POST antworten, und es funktionierte gut für Standalone-Anfragen. Auf Anfrage von Twilio wird die Antwort jedoch nie abgeschlossen und das Zeitlimit überschritten. Nachdem ich den Traffic, der von Twilio kommt, mit dem, der funktioniert, verglichen habe (mit einem gefälschten HTML-Formular), isolierte ich das Problem auf den Header "Connection: close" und konnte es nur mit der curl-Befehlszeile reproduzieren. Hier ist die Anforderung, das funktioniert:Fehler mit HTTP-Verbindung: Schließen Header

curl -i -H 'Connection: keep-alive' -X POST -d "name=value" http://localhost:8020/hello 

und hier ist derjenige, der gerade hängt:

curl -i -H 'Connection: close' -X POST -d "name=value" http://localhost:8020/hello 

Wenn ich den Server dann curl sage „(52) Leere Antwort vom Server“ zu töten. Hier ist der Code, den ich in der ServerResource benutze:

Ist etwas offensichtlich falsch mit dem, was ich hier mache? Ich benutze restlet-2.0, versuchte es aber auch mit 2.1m1 mit dem gleichen Ergebnis. Ich würde mich sehr über eine schnelle Antwort freuen, da ich eine Frist habe, um die Übung zu beenden.

Antwort

4

nicht sicher, ob Sie eine Lösung für Ihren Fehler gefunden haben, aber ich stieß auf das gleiche Problem in Restlet V 2.0.4.

Wenn das Restlet mit dem Standardserver ausgeführt wird. Hier nimmt der Server an, dass der Antwortstream nicht beschreibbar ist und daher nicht mit einer Entität antwortet.

als eine schnelle Lösung der I

org.restlet.engine.http.connector.Connection 

und änderte die die CanWrite() -Methode

public boolean canWrite() { 
    return (
      (getState() == ConnectionState.OPEN) 
        || (getState() == ConnectionState.CLOSING)) 
      && !isOutboundBusy() 
      && (getOutboundMessages().size() > 0); 
} 

von der ursprünglichen

public boolean canWrite() { 
    return (getState() == ConnectionState.OPEN) && !isOutboundBusy() 
      && (getOutboundMessages().size() > 0); 
} 

Nicht sicher, ob das eine gute ist beheben, aber nach dem erneuten Kompilieren des Restlet-Moduls scheint es nun zu funktionieren. Es scheint das Problem zu sein, dass beim Festlegen des HTTP-Headers "Verbindung: Schließen" der Stream standardmäßig im schließenden Status ist.

Hoffnung, die

Joey

Sehen Sie hier für das Problem auf dem Restlet Forum spezifisches alles hilft

http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2698048

+0

Danke für das Teilen. Heißt das, Restlet funktionierte nie gut mit einer Verbindung, die den Header "Connection: close" hat (was ein bedeutender Fehler wäre)? – haridsv

+0

Nun, es scheint ein Artefakt des Standard-Restlet-Servers zu sein, der im Lieferumfang von Restlet enthalten ist. Ich würde annehmen, dass dieses Problem nicht auftritt, wenn Sie Ihr Restlet in einem anderen Container (Jetty zum Beispiel) bereitstellen. Aber einverstanden, es ist definitiv ein Fehler. – Joey

+0

Es ist jetzt ein offizieller Fehler http://restlet.tigris.org/issues/show_bug.cgi?id=1191 – Joey

0

nicht sicher, das ist es, aber hier ist etwas zu beachten:

Restlet sehr sorgfältig und genau implementiert die Architektur REST. Eines der wichtigsten REST-Prinzipien, die es implementiert, ist die einheitliche Schnittstelle. In einem HTTP-basierten Web-Service nutzt die einheitliche Schnittstelle die HTTP-Operationen GET, PUT, POST, DELETE (und andere) so, wie sie ursprünglich vorgesehen waren. Wenn Sie also beim Zuweisen des Ressourcennamens eine Ressource auf dem Server erstellen möchten, verwenden Sie PUT. Um diese Ressource zu aktualisieren, verwenden Sie erneut PUT. Um es zu lesen, verwenden Sie GET. Um es zu löschen, verwenden Sie DELETE. POST ist reserviert für das Erstellen einer Ressource, wenn der Server den Ressourcennamen zuweist.

Also kann dies irgendwie aufgrund einer Unausgewogenheit der Erwartungen sein. Ein POST hat im Allgemeinen eine Repräsentation, die Sie an den Server senden, aber dieser POST nicht. Liest du die vollständige Anfrage ein und schließt die Verbindung auf der Serverseite richtig?

+0

nicht um eine Anwendung zu schaffen und eine Komponente, ich habe nicht besonders tun zu Verbindungen, und ich erwartete, dass Restlet sich darum kümmern würde. In Bezug auf die Darstellung ist mir nicht ganz klar, wie es funktioniert, und ich hatte Schwierigkeiten, eine unkomplizierte Dokumentation zu finden (ich gebe zu, ich habe es gerade eilig), aber da ich keine Repräsentation sende, muss ich irgendetwas tun Besondere? Ich werde prüfen, ob das Lesen von Formularparametern irgendwie dazu führt, dass Restlet in einen Wartezustand geht. Ich habe den Stack-Dump überprüft, keiner der Stacks zeigt auf den Restlet-Code. – haridsv