Gentlemen,
I have a website thats driven using Compojure. To this site I wanted
to add a backdoor to upload some images to the webserver (dont ask
why). Per Stuart Sierras advice I picked up his http.agent from
Clojure-contrib, hoping that it could simple POST the image file like
so:
user> (http-agent "
http://localhost:8888/backdoor/" :method
"POST" :body (File. "/tmp/mypicture.jpg"))
From the client side, this works fine. The server fails to receive
though. I think because it sees the entire body as URL and tries to
decode it. How do I get around this and pass the file to my upload
function?
(def *max_size* (* 30 1024 1024)) ; 30 Megabytes
(defn upload-file
[request base-path]
(if (ServletFileUpload/isMultipartContent request)
(let [uploader (ServletFileUpload. (DiskFileItemFactory.))
items (.parseRequest uploader request)]
(doseq [item items]
(if (and (not (.isFormField item))
(> *max_size* (.getSize item)))
(try
(let [file (File. (str base-path (.getName item)))]
(log Priority/INFO (str "Receiving " (.getName item)
" (" (.getSize item) "b)")
(.write item file)))
(catch Exception e (println "\nGot exception: " e)))
(log Priority/DEBUG "File upload rejected: Maximum size
exceeded"))))))
I never get that far, this fires soon as the request is made:
2009-08-19 23:44:34.001::WARN: /backdoor/
java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing
escape (%) pattern
at java.net.URLDecoder.decode(URLDecoder.java:187)
at compojure.encodings$urldecode__333.invoke(encodings.clj:25)
at compojure.http.request$parse_params__455$fn__457.invoke
(request.clj:28)
at clojure.core$reduce__3319$fn__3322.invoke(core.clj:539)
at clojure.core$reduce__3319.invoke(core.clj:537)
at compojure.http.request$parse_params__455.invoke(request.clj:31)
at compojure.http.request$parse_form_params__479.invoke(request.clj:
62)
at compojure.http.request$assoc_func__486.invoke(request.clj:76)
at compojure.http.request$assoc_params__490.invoke(request.clj:82)
at compojure.http.request$with_params__493$fn__495.invoke(request.clj:
91)
at compojure.http.request$with_cookies__506$fn__508.invoke
(request.clj:108)
at compojure.http.servlet$request_handler__828.invoke(servlet.clj:
109)
at bestinclass$eval__1639$fn__1641.invoke(boot.clj:24)
at clojure.proxy.javax.servlet.http.HttpServlet.service(Unknown
Source)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:
502)
at org.mortbay.jetty.servlet.ServletHandler.handle
(ServletHandler.java:380)
at org.mortbay.jetty.servlet.SessionHandler.handle
(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle
(ContextHandler.java:765)
at org.mortbay.jetty.handler.HandlerWrapper.handle
(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:
535)
at org.mortbay.jetty.HttpConnection$RequestHandler.content
(HttpConnection.java:880)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:747)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run
(SocketConnector.java:228)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run
(QueuedThreadPool.java:520)