2009-10-02 17 views
5

Sto costruendo un'API clojure sul mio sito web che è fondamentalmente un wrapper attorno all'API web originale. Una delle funzionalità che non sono in grado di implementare è l'invio di file tramite richieste POST, in pratica ciò che farei in shell con curl -F foo=bar [email protected] foobar.com.Come posso inviare un file in una richiesta POST?

Sto utilizzando clojure-http-client e inizialmente ho provato il modulo (resourcefully/post "foobar.com" {} {:foo "bar" :baz (File. "bak.jpg")}), ma il campo: baz è stato ignorato dallo script di ricezione, come se avessi inviato solo: foo. Più tardi, ho provato a cambiare File. a FileInputStream, poiché [la riga 51] [2] di client.clj sembra controllare questa particolare classe, ma ha comunque ottenuto gli stessi risultati.

Quindi ho creato una pagina php che stampa semplicemente $ _POST per verificare la mia richiesta e apparentemente i dati degli oggetti vengono inviati letteralmente. Date un'occhiata:

Clojure => (ingegnosamente/post "http://ptchan.org/pttest.php" {} {: foo "bar": baz "/tmp/bak.jpg"}) { : corpo-Seq ("array" "(" "[foo] => bar" "[baz] => /tmp/bak.jpg" ")"),: codice 200,: msg "OK",: metodo "POST",: intestazioni {: date ("Ven, 02 Ott 2009 11:41:15 GMT"),: vary ("Accept-Encoding"),: content-length ("53"),: connection ("close"),: content-type (" text/html "),: server (" Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 con Suhosin-Patch "),: x-powered-by (" PHP/5.2.6-1 + lenny3 ")},: get-intestazione #,: biscotti nil,: url" http://ptchan.org/pttest.php "}

Clojure => (ingegnosamente/post" http://ptchan.org/pttest.php "{} {: foo "bar":. baz (file"/tmp/bak.jpg ")}) {: body-seq ("Array" "(" "[foo] => bar" "[baz] => /tmp/bak.jpg" ")"),: codice 200,: msg "OK",: metodo "POST",: intestazioni {: date ("Fri, 02 Ott 2009 11:41:30 GMT"),: vary ("Accept-Encoding"),: content-length ("53"),: connection (" close "),: content-type (" text/html "),: server (" Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 con Suhosin-Patch "),: x-powered-by ("PHP/5.2.6-1 + lenny3")},: get-header #,: cookie nil,: url "http://ptchan.org/pttest.php"}

Clojure => (con risorse/post "http://ptchan.org/pttest.php" {} {: foo "bar": baz (FileInputStream. "/tmp/bak.jpg")}) {: body-seq ("Array" "(" "[foo] => bar" "[baz] => [email protected]" ")") ,: codice 200,: msg "OK",: metodo "POST",: intestazioni {: date ("Fri, 02 Ott 2009 11:41:47 GMT"),: vary ("Accept-Encoding"),: content -length ("73"),: connection ("close"),: content-type ("text/html"),: server ("Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 con Suhosin-Patch "),: x-powered-by (" PHP/5.2.6-1 + lenny3 ")},: get-intestazione #,: biscotti nil,: url" http://ptchan.org/pttest.php "}

I Non sono proprio sicuro di come procedere. Qualche suggerimento? Anche consigli generali sul debugging sono ben accetti!

Grazie

+2

+1 per l'utilizzo di lisp. ^^ – KB22

risposta

4

Provare a utilizzare clojure-apache-http, un wrapper Clojure per le librerie HTTP Apache full-optional. Supporta il POST multipart/form-data.

3

non sono sicuro che sia possibile utilizzando clojure-http-client. Per quanto vedo in the source code, se si passa una mappa come argomento del corpo, l'URL codificherà ogni elemento e lo invierà. Sembra che sia possibile solo i file POST come corpi interi, senza altri argomenti. Quindi supporto per 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))) 
Problemi correlati