Fork me on GitHub
#yada
<
2016-12-08
>
kurt-yagram08:12:06

@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
  (yada
   (yada/resource
    {:id ::images
     :methods
     {: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 java.io.File
                                 :image2 java.io.File}}
             :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 https://github.com/juxt/yada/blob/master/test/yada/multipart_test.clj, that's where I got the @(process-request-body ...) from)

kurt-yagram08:12:14

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

kurt-yagram09:12:36

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) :
-----------------------------938581027424650894225881368
Content-Disposition: form-data; name="image1"; filename="xxx"
Content-Type: text/csv
...

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

...
-----------------------------938581027424650894225881368--

kurt-yagram09:12:11

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.

kurt-yagram09:12:29

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:[clojure.tools]clojure.tools.logging.invoke 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)
...

kurt-yagram09:12:30

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

kurt-yagram10:12:47

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

stijn11:12:29

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

stijn11:12:05

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

stijn11:12:07

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

stijn11:12:22

any ideas on how to solve this?

stijn11:12:07

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

stijn11:12:09

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"

stijn11:12:28

why would a reverse proxy change that header?

stijn11:12:50

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

tcoupland15:12:07

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

tcoupland15:12:39

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

kurt-yagram15:12:24

@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!