如何在POST请求中发送文件?

时间:2009-10-02 11:45:54

标签: lisp clojure

我正在为我的网站构建一个clojure API,它基本上是原始Web API的包装器。我无法实现的功能之一是通过POST请求发送文件,基本上我将使用curl -F foo=bar baz=@bak.jpg foobar.com在shell中执行此操作。

我正在使用clojure-http-client,并且最初尝试使用(resourcefully/post "foobar.com" {} {:foo "bar" :baz (File. "bak.jpg")})形式,但接收脚本忽略了:baz字段,就像我只发送了一样:foo。后来,我尝试将File.更改为FileInputStream,因为client.clj的[第51行] [2]似乎正在检查此特定类,但仍然得到相同的结果。

然后我创建了一个只打印$ _POST的php页面来检查我的请求,显然这些对象的数据是按字面意思发送的。看看:

  

的Clojure => (资源丰富/发布“http://ptchan.org/pttest.php”{} {:foo“bar”:baz“/tmp/bak.jpg”})   {:body-seq(“Array”“(”“[foo] => bar”“[baz] => /tmp/bak.jpg”“)”),: code 200,:msg“OK”, :方法“POST”,:headers {:date(“Fri,2009年10月2日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 with Suhosin-Patch”),:x-powered- by(“PHP / 5.2.6-1 + lenny3”)} ,: get-header#,: cookies nil,:url“http://ptchan.org/pttest.php”}

     

的Clojure => (资源丰富/发布“http://ptchan.org/pttest.php”{} {:foo“bar”:baz(文件。“/ tmp / bak.jpg”)})   {:body-seq(“Array”“(”“[foo] => bar”“[baz] => /tmp/bak.jpg”“)”),: code 200,:msg“OK”, :方法“POST”,:headers {:date(“Fri,2009年10月2日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 with Suhosin-Patch”),:x-powered- by(“PHP / 5.2.6-1 + lenny3”)} ,: get-header#,: cookies nil,:url“http://ptchan.org/pttest.php”}

     

的Clojure => (资源丰富/发布“http://ptchan.org/pttest.php”{} {:foo“bar”:baz(FileInputStream。“/ tmp / bak.jpg”)})   {:body-seq(“Array”“(”“[foo] => bar”“[baz] => java.io.FileInputStream@320f6398”“)”),: code 200,:msg“OK” ,:方法“POST”,:headers {:date(“Fri,2009年10月2日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 with Suhosin-Patch”),:x-powered -by(“PHP / 5.2.6-1 + lenny3”)} ,: get-header#,: cookies nil,:url“http://ptchan.org/pttest.php”}

我不确定如何继续。有什么建议吗?有关调试的一般提示也欢迎!

由于

2 个答案:

答案 0 :(得分:4)

尝试使用clojure-apache-http,一个用于全功能Apache HTTP库的Clojure包装器。它支持multipart / form-data POST。

答案 1 :(得分:3)

我不确定使用clojure-http-client是否可行。据我所知in the source code,如果您将地图作为正文参数传递,它将对每个元素进行URL编码并发送。看起来您只能将文件作为整个主体POST,而不需要任何其他参数。所以nu支持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)))