reitit

Rolf Rander Næss 2025-05-03T10:25:50.378809Z

I am trying to upload files using this example: https://github.com/metosin/reitit/blob/master/examples/ring-spec-swagger/src/example/server.clj I am limiting filesize to 10MB, which works, giving an exception on larger files. However, the temp-files remain. How can I create an exception-handler (or other middleware) to remove temp-files when processing fails? I have a route defined like this:

["/object/:id/image" {:post {:summary "upload images to an object"
                                  ;:consumes ["multipart/form-data"]
                                  :parameters {:multipart [:map [:file reitit.ring.malli/temp-file-part]]}
                                  :responses {200 {:description "list of image urls"}}
                                  :handler #'echo-handler}}]
This middleware:
:middleware [(exception/create-exception-middleware
                         (merge exception/default-handlers
                                {::exception/default delete-tempfiles})
                         )
                        swagger/swagger-feature
                        muuntaja/format-middleware
                        parameters/parameters-middleware
                        reitit.ring.coercion/coerce-request-middleware
                        (multipart/create-multipart-middleware
                         {:max-file-size (* 10 1024 1024)
                          :max-file-count 1
                          })
                        ]
But the object sent to delete-tempfile doesn't seem to contain a reference to the created tempfile. What would be the best way of achieving this?

opqdonut 2025-05-05T06:54:20.172159Z

you need to add some middleware after create-multipart-middleware so that it'll see the request keys added by create-multipart-middleware

Rolf Rander Næss 2025-05-05T17:56:32.198439Z

I am sorry, I don't quite understand. I tried setting up a simple "logging-middleware" between each of the others to get a sense of whats going on:

[(exception/create-exception-middleware
  (merge exception/default-handlers
         {::exception/default delete-tempfiles}))
 swagger/swagger-feature
 log-multipart-middleware ;1
 muuntaja/format-middleware
 log-multipart-middleware ;2
 (setup-token-auth-middleware config)
 log-multipart-middleware ;3
 reitit.ring.coercion/coerce-request-middleware
 log-multipart-middleware ;4
 (multipart/create-multipart-middleware
                         ; options 
  {:max-file-size (* 10 1024 1024)
   :max-file-count 1
                          ;:store byte-array-store
   })
 log-multipart-middleware ;5
 parameters/parameters-middleware
 log-multipart-middleware ;6
 ]
log-multipart-middleware logs the content of the :parameters-key. When sent a file smaller than 10MB, number 1, 2, 3 logs "nil", 4 logs the path-parameter and 5, 6 also logs the file-parameter including tempfile-reference. However, when sent a file larger than 10MB, number 5 and 6 does not execute at all, because the multipart middleware throws an exception. My problem is that the object sent to my exception-handler delete-tempfiles does not contain any :parameters-key. I can't see what I am supposed to add after create-multipart-middleware that can change this behaviour, this will never be called. Adding the exception-handler itself after the multipart-middleware means that it is not able to intercept the FileUploadByteCountLimitException

Rolf Rander Næss 2025-05-05T18:41:13.947349Z

ok, now I found out that the ring temp-file-store has an :expires-in-parameter and this exception handling is really unneccessary

👍 1
opqdonut 2025-05-06T05:11:17.565379Z

ah, I didn't realise the exception was coming from multipart-middleware! yeah, that would make it difficult. good that you found the timeout.

👍 1