Fork me on GitHub

@ikitommi (single) file upload added to swagger seems to work... but processing the request-body doesn't seem to work pretty well:

(def image-resource
    {:id ::images
     {:post {:summary "add new images"
             :consumes "multipart/form-data"
             :consumer (fn [ctx _ body-stream]
                         (let [ctx @(process-request-body ctx body-stream "multipart/form-data")]
                           (clojure.pprint/pprint (find-part ctx "image1"))
                           (clojure.pprint/pprint (find-part ctx "image2")))
                         {:something :ok})
             :parameters {:form {:image1
             :response post-images}}})))
I do get the right bodystream (if I print it, it looks as expected), but I can't seem to find the different parts. Basically: how to handle multipart/form-data (I did check, that's where I got the @(process-request-body ...) from)


The result of above code: it hangs on (let [ctx @(process-request-body ctx body-stream "multipart/form-data")


Trying to consume multipart/form-data... :

:consumer (fn [ctx _ body-stream]
                         (with-open [rdr ( body-stream)]
                           (println (clojure.string/join "\n" (line-seq rdr)))))
gives a a multipart message as expected (don't bother the names for now :p) :
Content-Disposition: form-data; name="image1"; filename="xxx"
Content-Type: text/csv

Content-Disposition: form-data; name="image2"; filename="yyy"
Content-Type: application/json



However, when I try to use yada.request-body/process-request-body, things don't seem to work very well:

:consumer (fn [ctx _ body-stream]
                         (let [req (process-request-body ctx body-stream "multipart/form-data")]
                           {:something :ok
                            :image1 (find-part @req "image1")}))
hangs on the line where I deref.


no deref:

:consumer (fn [ctx _ body-stream]
                         (let [req (process-request-body ctx body-stream "multipart/form-data")]
                           {:something :ok
                            :image1 (find-part req "image1")}))
results in:
[manifold-pool-2-1:6510]ERROR:[] at logging.clj:288
   error in HTTP handler: java.lang.AssertionError: Assert failed: (:method-wrapper ctx)
      at yada.interceptors$invoke_method.invokeStatic(interceptors.clj:364)
      at yada.interceptors$invoke_method.invoke(interceptors.clj:360)
      at manifold.deferred$eval8819$chain___8840.invoke(deferred.clj:862)
      at manifold.deferred$eval8819$chain___8840.doInvoke(deferred.clj:886)


How to handle multipart/form-data properly in Yada? Thx.


... all I want to do is get the different parts.


i'm having a weird problem with a DELETE request on yada 1.1.45


if I add the header 'Transfer-encoding: chunked', it responds with a 415 Unsupported media type


the thing is, either our Varnish or Google load balancer adds this header when issueing a non HTTP/2.0 request


any ideas on how to solve this?


ok, I see in yada.interceptors/process-request-body


RFC 7230 section 3.3 states
  "The presence of a message body in a request is signaled by a
  Content-Length or Transfer-Encoding header field. Request message
  framing is independent of method semantics, even if the method does
  not define any use for a message body"


why would a reverse proxy change that header?


and it doesn't do this when sending an HTTP/2 request


it might be a different to what your doing, here i'm streaming uploading files straight to S3


the two parts i deal with are defined there (file and file-metadata), if your parts are simple, you might get a way with the default Part implementations and just list your parts like that


@tcoupland Thanks a lot! I did get it working by now, but I still have to clean it up... I'll certainly have a look at your implementation!