2009-10-02 28 views
5

Estoy creando una API de clojure para mi sitio web que es básicamente una envoltura alrededor de la API web original. Una de las características que no puedo implementar es el envío de archivos a través de solicitudes POST, básicamente lo que haría en shell con curl -F foo=bar [email protected] foobar.com.¿Cómo puedo enviar un archivo en una solicitud POST?

Estoy usando clojure-http-client, e inicialmente probé el formulario (resourcefully/post "foobar.com" {} {:foo "bar" :baz (File. "bak.jpg")}), pero el campo: baz fue ignorado por la secuencia de comandos de recepción, como si hubiera enviado solo: foo. Más tarde, traté de cambiar File. a FileInputStream, ya que [la línea 51] [2] de client.clj parece estar buscando esta clase en particular, pero igual obtuvo los mismos resultados.

Luego creé una página php que simplemente imprime $ _POST para verificar mi solicitud, y aparentemente los datos de los objetos se envían literalmente. Echar un vistazo:

Clojure => (con habilidad/post "http://ptchan.org/pttest.php" {} {: foo "barra": Baz "/tmp/bak.jpg"}) { : cuerpo-SEC ("Matriz" "(" "[foo] => bar" "[baz] => /tmp/bak.jpg" ")"),: código 200,: msg "OK",: método "POST",: encabezados {: date ("Vie, 02 Oct 2009 11:41:15 GMT"),: varía ("Aceptar-Codificar"),: contenido-longitud ("53"),: conexión ("cerrar"),: tipo-contenido (" 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-cabecera #,: galletas nula, url" http://ptchan.org/pttest.php "}

Clojure => (con habilidad/post" http://ptchan.org/pttest.php "{} {: foo "barra":. baz (archivo"/tmp/bak.jpg ")}) {: body-seq ("Array" "(" "[foo] => bar" "[baz] => /tmp/bak.jpg" ")"),: código 200,: msg "OK",: método "POST",: encabezados {: date ("Vie, 02 Oct 2009 11:41:30 GMT"),: vary ("Aceptar-Codificar"),: 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-cabecera #,: galletas nula, url "http://ptchan.org/pttest.php "}

Clojure => (con habilidad/post" http://ptchan.org/pttest.php" {} {: foo "bar": baz (FileInputStream. "/tmp/bak.jpg")}) {: body-seq ("Array" "(" "[foo] => bar" "[baz] => [email protected]" ")") ,: código 200,: msg "OK",: método "POST",: encabezados {: date ("Vie, 02 Oct 2009 11:41:47 GMT"),: vary ("Aceptar-Codificar"),: contenido -length ("73"),: connection ("close"),: content-type ("text/html"),: server ("Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 con suhosin-Patch "),: x-alimentado por (" PHP/5.2.6-1 + lenny3 ")},: get-cabecera #,: galletas nula, url" http://ptchan.org/pttest.php "}

I No estoy seguro de cómo proceder. ¿Cualquier sugerencia? Consejos generales sobre la depuración también son bienvenidos!

Gracias

+2

+1 para usar lisp. ^^ – KB22

Respuesta

4

Intente utilizar clojure-apache-http, un envoltorio de Clojure para las bibliotecas con todas las funciones HTTP Apache. Admite multipart/form-data POST.

3

no estoy seguro de que es posible utilizando clojure-http-cliente. Por lo que veo in the source code, si pasas un mapa como el argumento del cuerpo, el URL codificará cada elemento y lo enviará. Parece que solo puede POSTAR archivos como cuerpos enteros, sin ningún otro argumento. Así que soporte para multiparte.

(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))) 
Cuestiones relacionadas