2010-06-20 7 views
8

J'essaie de publier des données sur un serveur dans Haskell et le côté serveur est vide. J'utilise la bibliothèque Network.HTTP pour la demande.Contenu HTTP POST dans Haskell

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

Ce test retourne la chaîne vide comme le corps de réponse du serveur, quand je pense qu'il devrait être en écho à la post « chaîne de test ».

Je voudrais idéalement reproduire la fonctionnalité de:

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

et je suis avec validation des résultats Serverside test.php:

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

ce que je fais mal ou devrais-je simplement essayer un autre bibliothèque?

+0

Je suggère d'essayer et renifler la communication en utilisant "wireshark" ou un programme similaire pour voir le contenu réel être envoyé/reçu. cela vous indiquera le problème beaucoup mieux – yairchu

Répondre

3

Vous devez spécifier un en-tête Content-Length HTTP, dont la valeur doit être la longueur des données affichées brutes:

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

Et avec 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 

Le "Test string", dans l'exemple ci-dessus , est urlEncoded avant d'être posté.

Vous pouvez également définir manuellement la méthode, le type de contenu et le corps de la demande. L'API est la même que dans http-énumérateur un bon exemple est: https://stackoverflow.com/a/5614946