2010-06-20 34 views
8

Estoy intentando publicar algunos datos en un servidor en Haskell y el lado del servidor está vacío.Contenido HTTP POST en Haskell

Estoy utilizando la biblioteca Network.HTTP para la solicitud.

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" 
        } 

Esta prueba está devolviendo la cadena vacía como el cuerpo de la respuesta del servidor, cuando yo creo que debe ser eco del mensaje "cadena de prueba".

que lo ideal sería replicar la funcionalidad de:

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

y estoy validando los resultados con prueba.php serverside:

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

estoy haciendo esto mal o debo estar intentando otra ¿biblioteca?

+0

Sugiero probar y oler la comunicación usando "wireshark" o un programa similar para ver el contenido real que se envía/recibe. esto te señalará el problema mucho mejor – yairchu

Respuesta

3

es necesario especificar un encabezado Content-Length HTTP, cuyo valor debe ser la longitud de los datos publicado en bruto:

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

Y con 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 

El "Test string", en el ejemplo anterior , está urlEncoded antes de publicarse.

También puede establecer manualmente el método, el tipo de contenido y el cuerpo de la solicitud. La API es la misma que en http-enumerator. Un buen ejemplo es: https://stackoverflow.com/a/5614946