2012-06-30 6 views
7

Sto provando a utilizzare haxr 3000.8.5 per caricare immagini in un blog WordPress utilizzando l'API metaWeblog --- in particolare, il Metodo newMediaObject.Eccezione ErrorClosed da Network.HTTP.simpleHTTP - tentativo di caricare immagini via XML-RPC con haxr

Ho ottenuto il lavoro per piccole immagini, avendo caricato con successo icone 20x20 in entrambi i formati PNG e JPG. Tuttavia, quando provo immagini di medie dimensioni (ad esempio, 300x300) ottengo un'eccezione ErrorClosed, presumibilmente dal pacchetto HTTP (ho fatto un po 'di immersione sorgente e ho scoperto che haxr alla fine chiama Network.HTTP.simpleHTTP).

Qualcuno può far luce sui motivi per cui una chiamata a simpleHTTP potrebbe non riuscire con ErrorClosed? Sono anche benvenuti suggerimenti su cose da provare e potenziali soluzioni alternative.

Ecco i collegamenti a full tcpdump output from a successful upload e from an unsuccessful upload.

Il codice (igienizzato) è anche mostrato di seguito, nel caso sia di qualche utilità.

import   Network.XmlRpc.Client  (remote) 
import   Network.XmlRpc.Internals (Value(..), toValue) 
import   Data.Char     (toLower) 
import   System.FilePath   (takeFileName, takeExtension) 
import qualified Data.ByteString.Char8 as B 
import   Data.Functor    ((<$>)) 

uploadMediaObject :: FilePath -> IO Value 
uploadMediaObject file = do 
    media <- mkMediaObject file 
    remote "http://someblog.wordpress.com/xmlrpc.php" "metaWeblog.newMediaObject" 
    "default" "username" "password" media 

-- Create the required struct representing the image. 
mkMediaObject :: FilePath -> IO Value 
mkMediaObject filePath = do 
    bits <- B.unpack <$> B.readFile filePath 
    return $ ValueStruct 
    [ ("name", toValue fileName) 
    , ("type", toValue fileType) 
    , ("bits", ValueBase64 bits) 
    ] 
    where 
    fileName = takeFileName filePath 
    fileType = case (map toLower . drop 1 . takeExtension) fileName of 
       "png" -> "image/png" 
       "jpg" -> "image/jpeg" 
       "jpeg" -> "image/jpeg" 
       "gif" -> "image/gif" 

main = do 
    v <- uploadMediaObject "images/puppy.png" 
    print v 
+1

Hai provato a utilizzare tcpdump o wireshark per ispezionare la sessione HTTP? –

+0

Grazie per il suggerimento. So davvero molto poco del networking, specialmente quando si tratta di eseguire il debug. Ho aggiunto alcuni output tcpdump alla domanda. –

+0

@ BrentYorgey: Penso che vorrai modificare quell'output nella tua domanda. È molto più facile leggerlo correttamente formattato lì, anche se riesce a inserirsi nello spazio limitato che si ottiene in un commento. –

risposta

4
21:59:56.813021 IP 192.168.1.148.39571 > ..http: Flags [.] 
22:00:01.922598 IP ..http > 192.168.1.148.39571: Flags [F.] 

la connessione viene chiusa dal server dopo un timeout 3-4 sec come il client non ha inviato alcun dato, per prevenire slowloris e attacchi DDoS simili. (F è il flag FIN, per chiudere una direzione della connessione bidirezionale).

Il server non attende che il client chiuda la connessione (attendere eof/0 == recv (fd)) ma usa il syscall close(); il kernel sul server risponderà con i pacchetti [R] eset se riceve ulteriori dati, come puoi vedere alla fine del tuo dump.

Immagino che il client prima apra la connessione http e quindi prepari i dati che impiegano troppo tempo.

+0

Grazie, questo è esattamente quello che dovevo sapere! È venuto fuori che la pigrizia di Haskell mi stava mordendo in modo grandioso. La correzione è non banale (richiede patching haxr), ma ho ottenuto che funzioni ora. –

Problemi correlati