2010-06-20 77 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