2009-10-02 19 views
5

Buduję API clojure na mojej stronie internetowej, które jest w zasadzie opakowaniem oryginalnego web API. Jedną z funkcji, których nie jestem w stanie zaimplementować, jest wysyłanie plików przez żądania POST, w zasadzie to, co zrobiłbym w powłoce z curl -F foo=bar [email protected] foobar.com.Jak wysłać plik w żądaniu POST?

Używam clojure-http-client i początkowo wypróbowałem formularz (resourcefully/post "foobar.com" {} {:foo "bar" :baz (File. "bak.jpg")}), ale pole: baz zostało zignorowane przez skrypt odbierający, tak jakbym wysłał tylko: foo. Później próbowałem zmienić File. na FileInputStream, ponieważ [linia 51] [2] klienta.clj wydaje się sprawdzać dla tej konkretnej klasy, ale wciąż ma te same wyniki.

Następnie utworzyłem stronę php, która po prostu drukuje $ _POST, aby sprawdzić moją prośbę, i najwyraźniej dane obiektów są wysyłane dosłownie. Spójrz:

Clojure => (resourcefully/post "http://ptchan.org/pttest.php" {} {: bla "bar": baz "/tmp/bak.jpg"}) {: SEQ ciała ("macierz" "(" "[foo] => bar" "[baz] => /tmp/bak.jpg" ")"),: kod 200,: msg "OK",: metoda "POST",: nagłówki {: data ("Fri, 02 października 2009 11:41:15 GMT"),: vary ("Accept-Encoding"),: długość treści ("53"),: połączenie ("close"),: content-type (" text/html "),: server (" Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 z łatką Suhosin "),: x-powered-by (" PHP/5.2.6-1 + lenny3 ")},: get-header #,: cookies zero,: url" http://ptchan.org/pttest.php "}

Clojure => (zaradno/post" http://ptchan.org/pttest.php "{} {: foo" bar ": baz (plik."/tmp/bak.jpg ")}) {: body-seq ("Array" "(" "[foo] => bar" "[baz] => /tmp/bak.jpg" ")"),: code 200,: msg "OK",: metoda "POST",: headers {: date ("Fri, 02.10.2009 11:41:30 GMT"),: vary ("Accept-Encoding"),: długość treści ("53"),: połączenie (" close "),: content-type (" text/html "),: server (" Apache/2.2.9 (Debian) PHP/5.2.6-1 + lenny3 z łatką Suhosin "),: x-powered-by ("PHP/5.2.6-1 + lenny3")},: get-header #,: cookie zero,: url "http://ptchan.org/pttest.php"}

Clojure => (zarabianie/post "http://ptchan.org/pttest.php" {} foo "bar": baz (FileInputStream. "/tmp/bak.jpg")}) {: body-seq ("Array" "(" "[foo] => bar" "[baz] => [email protected]" ")") ,: code 200,: msg "OK",: method "POST",: headers {: date ("Fri, 02.10.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 z Suhosin-patch "): x-zasilane przez (" PHP/5.2.6-1 + lenny3 ")}: get-header #,: ciasteczka nil,: url" http://ptchan.org/pttest.php „}

I nie jestem pewien, jak postępować. Jakieś sugestie? Ogólne wskazówki dotyczące debugowania są również mile widziane!

Dzięki

+2

+1 za korzystanie z seplenienia. ^^ – KB22

Odpowiedz

4

Spróbuj użyć clojure-apache-http, otoki Clojure dla pełnego funkcjonalny biblioteki HTTP Apache. Obsługuje POST wielostronicowy/formularz danych.

3

nie jestem pewien, że jest to możliwe przy użyciu Clojure-http-client. O ile widzę in the source code, jeśli przekazujesz mapę jako argument ciała, to URL zakoduje każdy element i wyśle ​​go. Wygląda na to, że możesz tylko pliki POST jako całe obiekty, bez żadnych innych argumentów. Więc nu obsługuje wieloczęściowy.

(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))) 
Powiązane problemy