2010-12-20 85 views
4

我有一個奇怪的問題,我正在構建一個小型restlet服務作爲練習。應用程序應該在HTTP POST上響應一些XML(specifically TwiML,因爲它是用於Twilio),並且它對於獨立請求很有效。但是,當Twilio提出要求時,響應從未完成並且超時。在比較來自Twilio的流量和正在工作的流量之後(使用假HTML表單),我將問題隔離到「Connection:close」標題,並且可以使用curl命令行中的任何內容來重現它。這裏是工作的要求:HTTP連接出錯:關閉標題

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

,這裏是剛剛掛了一句:如果我殺了服務器,然後捲曲說

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

「(52)從服務器空答覆」。以下是我在ServerResource中使用的代碼:

@Post 
public Representation hello(Representation repr) 
{ 
    Representation result = new StringRepresentation(("<Response>\n"+ 
      " <Say>Hello. This is a test.</Say>\n"+ 
      "</Response>"), MediaType.APPLICATION_XML); 
    return result; 
} 

我在這裏做什麼顯然是錯誤的?我正在使用restlet-2.0,但也用2.1m1嘗試過,結果相同。我非常感謝快速反應,因爲我正在完成這個練習的最後期限。

回答

4

不確定您是否爲您的錯誤找到解決方案,但我在Restlet V 2.0.4中遇到過同樣的問題。

使用默認服務器運行restlet時。這裏服務器確實認爲響應流不可寫,因此不會響應實體。

由於速戰速決我所在

org.restlet.engine.http.connector.Connection 

,並從原來的

改變的canWrite()方法來

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

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

不知道這是一個很好的修復,但重新編譯restlet模塊後,它現在似乎工作正常。 這似乎是一個問題,當指定HTTP Header'Connection:close'時,流默認處於關閉狀態。

希望幫助

喬伊

看到這裏的問題上的Restlet論壇

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

+0

感謝分享。這是否意味着,restlet從不能很好地處理具有「Connection:close」頭部的連接(這將是一個重要的bug)? – haridsv 2011-01-14 04:13:59

+0

好吧,它似乎是與restlet捆綁在一起的標準restlet服務器的一個人工製品。我會假設,如果你在不同的容器(例如Jetty)中部署你的restlet,它不會遇到這個問題。但同意,這確實是一個錯誤。 – Joey 2011-01-14 13:13:06

+0

它現在是一個官方的錯誤http://restlet.tigris.org/issues/show_bug.cgi?id=1191 – Joey 2011-01-17 23:10:41

0

不知道這是它,但這裏的東西來考慮:

的Restlet非常仔細,準確地實現了REST架構風格。它實現的關鍵REST原則之一是統一接口。在基於HTTP的Web服務中,統一接口按照它們最初打算的方式利用HTTP GET,PUT,POST,DELETE(和其他)操作。因此,要在分配資源名稱時在服務器上創建資源,請使用PUT。要更新該資源,請再次使用PUT。要閱讀它,你使用GET。要刪除它,請使用DELETE。當服務器分配資源名稱時,POST保留用於創建資源。

所以這可能在某種程度上是由於預期的不匹配。 POST通常具有您要發送到服務器的表示,但是此POST不會。您是否正在閱讀完整請求並在服務器端正確關閉連接?

+0

比創建一個應用程序,並以外的成分,我沒有特別的任何具體行動連接,我希望restlet照顧它。關於代表性,我不清楚它是如何工作的,而且我很難找到直接的文檔(我承認,我現在很急),但由於我沒有發送任何表示,我是否必須做任何事情特別?我會檢查如果不讀取表單參數是以某種方式導致restlet進入等待狀態。我檢查了堆棧轉儲,沒有一個堆棧指向甚至是restlet代碼。 – haridsv 2010-12-20 18:33:05