2009-10-02 7 views
5

Je construis une API clojure sur mon site web qui est essentiellement un emballage autour de l'API web originale. L'une des fonctionnalités que je ne suis pas en mesure de mettre en œuvre est l'envoi de fichiers via des requêtes POST, essentiellement ce que je ferais en shell avec curl -F foo=bar [email protected] foobar.com.Comment puis-je envoyer un fichier dans une requête POST?

J'utilise clojure-http-client, et initialement essayé le formulaire (resourcefully/post "foobar.com" {} {:foo "bar" :baz (File. "bak.jpg")}), mais le champ: baz a été ignoré par le script de réception, comme si j'avais envoyé seulement: foo. Plus tard, j'ai essayé de changer File. en FileInputStream, car [la ligne 51] [2] de client.clj semble vérifier cette classe en particulier, mais obtient toujours les mêmes résultats.

Puis j'ai créé une page php qui imprime simplement $ _POST pour vérifier ma demande, et apparemment les données des objets sont envoyées littéralement. Jetez un oeil:

Clojure => (ingénieusement/post "http://ptchan.org/pttest.php" {} {: foo "bar": baz "/tmp/bak.jpg"}) { : corps-seq ("Array" "(" "[foo] => bar" "[baz] => /tmp/bak.jpg" ")"),: code 200,: msg "OK",: méthode "POST",: en-têtes {: date ("Fri, 02 Oct 2009 11:41:15 GMT"),: vary ("Accept-Encoding"),: content-length ("53"),: connexion ("close"),: content-type (" text/html "),: serveur (" Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 avec Suhosin-Patch "),: x-powered-by (" PHP/5.2.6-1 + lenny3 ")},: get-tête #,: nul cookies,: url" http://ptchan.org/pttest.php "}

Clojure => (ingénieusement/post" http://ptchan.org/pttest.php "{} {: foo "bar". baz (fichier"/tmp/bak.jpg ")}) {: body-seq ("Array" "(" "[foo] => barre" "[baz] => /tmp/bak.jpg" ")"),: code 200,: msg "OK",: méthode "POST",: headers {: date ("Ven, 02 Oct 2009 11:41:30 GMT"),: vary ("Accept-Encoding"),: content-length ("53"),: connection (" close "),: content-type (" text/html "),: serveur (" Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 avec Suhosin-Patch "),: x-powered-by ("PHP/5.2.6-1 + lenny3")},: get-header #,: cookies nil,: url "http://ptchan.org/pttest.php"}

Clojure => (ingénieusement/post "http://ptchan.org/pttest.php" {} {: foo "bar": baz (FileInputStream. "/tmp/bak.jpg")}) {: body-seq ("Array" "(" "[foo] => barre" "[baz] => [email protected]" ")") ,: code 200,: msg "OK",: méthode "POST",: en-têtes {: date ("Ven, 02 Oct 2009 11:41:47 GMT"),: vary ("Accept-Encoding"),: content -length ("73"),: connection ("close"),: content-type ("text/html"),: serveur ("Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 avec suhosin-Patch "),: x-alimenté par (" PHP/5.2.6-1 + lenny3 ")},: get-tête #,: nul cookies,: url" http://ptchan.org/pttest.php « }

I Je ne sais pas vraiment comment procéder. Toute suggestion? Des conseils généraux sur le débogage sont également les bienvenus!

Merci

+2

+1 pour l'utilisation de lisp. ^^ – KB22

Répondre

4

Essayez d'utiliser clojure-apache-http, une enveloppe Clojure pour les bibliothèques HTTP Apache complet. Il supporte le POST multipart/form-data.

3

Je ne suis pas sûr qu'il est possible à l'aide clojure-http-client. Pour autant que je vois in the source code, si vous passez une carte en tant qu'argument de corps, elle va encoder chaque élément et l'envoyer. Il semble que vous ne pouvez POST que des fichiers entiers, sans aucun autre argument. Donc, le support nu pour multipart.

(let [out (.getOutputStream connection)] 
(cond 
    (string? body) (spit out body) 
    (map? body) (spit out (url-encode body)) 
    (instance? InputStream body) 
    (let [bytes (make-array Byte/TYPE 1000)] 
    (loop [#^InputStream stream body 
      bytes-read (.read stream bytes)] 
     (when (pos? bytes-read) 
     (.write out bytes 0 bytes-read) 
     (recur stream (.read stream bytes)))))) 
(.close out))) 
Questions connexes