Fork me on GitHub
#aleph
<
2021-02-24
>
eelke08:02:04

Hello, I have a question. I am trying to set up a server that can receive and process multipart messages. My attempt is with aleph with yada resources. But I have difficulties in processing the manifold.stream in the response. Do you have some tips and tricks?

eelke08:02:44

This is the code I have:

(yada/listener
    ["/some-route"
     (yada/resource {:methods
                     {:post {:consumes "multipart/form-data"
                             :produces "application/json"
                             :response (fn [ctx]
                                         (let [boundary (last (clojure.string/split (get-in ctx [:request :headers "content-type"]) #"="))]
                                           (try   (->> (get-in ctx [:request :body])
                                                       (yada.multipart/parse-multipart boundary 10000 1000)
                                                       (manifold.stream/transform (xf-bytes->content))
                                                       manifold.stream/stream->seq)
                                                  (catch Exception e
                                                    (println (.getMessage e)))))
                                         (clojure.data.json/write-str {:success true}))}}})]
    {:port        1234
     :raw-stream? true
     :executor    (flow/utilization-executor 0.9 64)})

mccraigmccraig08:02:08

what do you want to do with the stream @eelke? note that stream->seq should probably come with a warning - it's a blocking function

eelke08:02:33

Hey @mccraigmccraig, thanks for the response. I would like to process what comes through the stream. I can be that the client sends large multipart requests, containing tens of images or videos, and the server needs to handle this

eelke08:02:12

@(d/chain (get-in ctx [:request :body])
           #(manifold.stream/map bs/to-byte-array %)
           #(manifold.stream/reduce conj [] %)
           bs/to-string)
                                                                      

eelke08:02:02

This does result in a string but it does not always contain everything that was send, I think

mccraigmccraig08:02:25

ha, i'm recalling a very bad evening spent debugging...

mccraigmccraig08:02:15

question - do you have {:raw-stream? true} specified in your aleph.http/start-server opts ?

mccraigmccraig08:02:12

if you don't, flaky multipart parsing ensues

eelke08:02:05

ahah, I can imagine. I have it as an option indeed

eelke08:02:20

you can see it in the map I sent with the listener

eelke08:02:00

I feel like I am close

mccraigmccraig08:02:56

i've not been using the stream-based multipart interface - what does yada.multipart/parse-multipart create a stream of ?

eelke09:02:24

Is there something else you use for multipart?

mccraigmccraig09:02:21

we've been using the PartConsumer interface ... but iirc that's because that came first and we've been using it since the beginning - i would have preferred a stream-based interface

mccraigmccraig09:02:38

i'd have a look around for an example of what the canonical yada resource should do now... PartConsumer wasn't the easiest to get working

eelke09:02:40

ah ok, I'll keep trying