2010-06-20 43 views
8

我想將一些數據發佈到Haskell中的服務器,並且服務器端即將變空。Haskell中的HTTP POST內容

我對請求使用Network.HTTP庫。

module Main (main) where 

import Network.URI (URI (..), parseURI, uriScheme, uriPath, uriQuery, uriFragment) 
import Network.HTTP 
import Network.TCP as TCP 

main = do 
     conn <- TCP.openStream "localhost" 80 
     rawResponse <- sendHTTP conn updateTest 
     body <- getResponseBody rawResponse 
     if body == rqBody updateTest 
      then print "test passed" 
      else print (body ++ " != " ++ (rqBody updateTest)) 

updateURI = case parseURI "http://localhost/test.php" of 
        Just u -> u 

updateTest = Request { rqURI = updateURI :: URI 
        , rqMethod = POST :: RequestMethod 
        , rqHeaders = [ Header HdrContentType "text/plain; charset=utf-8" 
            ] :: [Header] 
        , rqBody = "Test string" 
        } 

該測試返回空字符串作爲從服務器的響應體,當我覺得應該是呼應「測試串」的帖子。

我會非常想複製的功能:

curl http://localhost/test.php -d 'Test string' -H 'Content-type:text/plain; charset=utf-8' 

和我與服務器端驗證test.php的結果:

<?php 
print (@file_get_contents('php://input')); 

難道我這樣做不對或者我應該只是嘗試另圖書館?

+0

我建議嘗試使用「wireshark」或類似程序來嗅探通信,以查看發送/接收的實際內容。這會更好地指出你的問題 – yairchu 2010-06-20 11:11:54

回答

3

需要指定一個Content-Length HTTP標頭,其值必須是原始發佈數據的長度:

updateTest = Request { rqURI  = updateURI 
        , rqMethod = POST 
        , rqHeaders = [ mkHeader HdrContentType "application/x-www-form-urlencoded" 
            , mkHeader HdrContentLength "8" 
            ] 
        , rqBody = "raw data" 
        } 
3

並與http-conduit

{-# LANGUAGE OverloadedStrings #-} 

import Network.HTTP.Conduit 
import qualified Data.ByteString.Lazy as L 

main = do 
    initReq <- parseUrl "http://localhost/test.php" 

    let req = (flip urlEncodedBody) initReq $ 
      [ ("", "Test string") 
--    , 
      ] 

    response <- withManager $ httpLbs req 

    L.putStr $ responseBody response 

"Test string",在上面的例子,在發佈之前是urlEncoded。

您還可以手動設置方法,內容類型和請求正文。這個API與http-enumerator相同,一個很好的例子是: https://stackoverflow.com/a/5614946