2014-12-06 43 views
1

也許是一個愚蠢的做事方式,但在這裏。我想分割處理響應的HTTP請求發送/接收。管道獲取Network.Socket.ByteString.recv:失敗(未知錯誤)

import Pipes 
import qualified Pipes.HTTP as HTTP 
import Pipes.Core 
import qualified Pipes.ByteString as PB 
import Network.Socket (withSocketsDo) 

fetch m url = do 
    req <- lift $ HTTP.parseUrl url 
    resp <- lift $ HTTP.withHTTP req m return 
    url' <- respond $ HTTP.responseBody resp 
    fetch m url' 

client :: Client String (Producer PB.ByteString IO()) IO() 
client = do 
      b <- request "http://www.google.com" 
      lift $ runEffect $ b >-> PB.stdout 

main = withSocketsDo $ HTTP.withManager HTTP.tlsManagerSettings $ \m -> 
    runEffect $ fetch m +>> client 

似乎是合法的。但我得到部分響應打印和「Network.Socket.ByteString.recv:失敗(未知錯誤)」。我需要做什麼改變?

+1

相關類別:http://stackoverflow.com/questions/9406463/withfile-vs-openfile – user3237465 2014-12-07 04:50:10

回答

3

的錯誤是這一部分:

HTTP.withHTTP req m return 

有個約定(不通過類型強制),當一個函數,你不能讓它分配逃脫的資源的話with開始它包含的塊。這是因爲這些函數在塊完成時處理資源,所以資源在該點之後無效。

所以發生了什麼是你試圖returnwithHTTP塊的響應,但是通過下一行代碼,響應已經被處理掉了。解決方案是使用pipes-safe,它允許您使用Pipes.Safe.bracket在管道內安全地獲取資源。所有你需要做的是提供一個開放和關閉動作:

fetch m url = do 
    req <- lift $ HTTP.parseUrl url 
    url' <- bracket openSomething closeSomething $ \resp -> do 
     respond $ HTTP.responseBody resp 
    fetch m url' 

這將確保resp不會被釋放,直到respond完成之後。

+0

謝謝。有沒有一個標準的方法來找出打開/關閉的內容? (在這種情況下,我確實挖掘出'withHTTP'是'withResponse'內部,然後'withResponse'解釋說: – 2014-12-07 09:28:06

+0

通常它們將被提供在與'with'函數相同的模塊中。另外,請檢查'resourcet'包,它提供'Resource'類型。這種類型可以讓你將'open'和'close'動作捆綁在一起,以便以後再次恢復它們。 – 2014-12-08 01:13:20

相關問題