Open marcomorain opened 5 years ago
For CircleCI reference, this is tracked in Rollbar.
Some relevant dependencies:
amalloy/ring-gzip-middleware "0.1.3-7f5ffd654029fa7c9e90314e2ef0a6fb306c4348"
commons-beanutils "1.9.2"
commons-codec "1.9"
commons-collections "3.2.2"
commons-digester "1.8.1"
commons-fileupload "1.3.3"
commons-io "2.5"
commons-logging "1.2"
commons-validator "1.6"
org.apache.commons/commons-compress "1.3"
org.apache.commons/commons-lang3 "3.3.2"
org.apache.commons/commons-pool2 "2.4.1"
org.apache.commons/commons-text "1.4"
org.apache.httpcomponents/httpclient "4.5.3"
org.apache.httpcomponents/httpcore "4.4.6"
org.apache.httpcomponents/httpmime "4.5.2"
ring "1.3.2"
ring/ring-anti-forgery "1.3.0"
ring/ring-codec "1.0.0"
ring/ring-core "1.3.2"
ring/ring-defaults "0.3.2"
ring/ring-devel "1.3.2"
ring/ring-headers "0.3.0"
ring/ring-servlet "1.3.2"
ring/ring-ssl "0.3.0"
My guess is that this is caused by incoming requests that have a content-type of "multipart/form-data" but have no associated body. The wrap-multipart-params
assumes that if the content type is correct the body should be an input stream. In the case of any servlet-derived adapter this is correct, but it doesn't apply in general, and you're using http-kit.
If I'm right, then the fix is to add a check to this function to ensure that the body is not nil
. I don't have time to spin up a test http-kit environment right now and confirm my guess, so if you want to do that it would be very helpful. I'd also welcome any PRs to address this issue, once the cause has been confirmed.
Hi James, thanks for the pointers.
I can't quite reproduce - I'm getting a similar but different error when setting Content-Type: multipart/form-data
on a GET request:
dev.circlehost | org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
dev.circlehost | at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:990)
dev.circlehost | at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:310)
dev.circlehost | at ring.middleware.multipart_params$file_item_seq.invokeStatic(multipart_params.clj:46)
dev.circlehost | at ring.middleware.multipart_params$file_item_seq.invoke(multipart_params.clj:42)
dev.circlehost | at ring.middleware.multipart_params$parse_multipart_params.invokeStatic(multipart_params.clj:63)
dev.circlehost | at ring.middleware.multipart_params$parse_multipart_params.invoke(multipart_params.clj:59)
dev.circlehost | at ring.middleware.multipart_params$multipart_params_request.invokeStatic(multipart_params.clj:91)
dev.circlehost | at ring.middleware.multipart_params$multipart_params_request.doInvoke(multipart_params.clj:80)
dev.circlehost | at clojure.lang.RestFn.invoke(RestFn.java:423)
dev.circlehost | at ring.middleware.multipart_params$wrap_multipart_params$fn__84567.invoke(multipart_params.clj:118)
dev.circlehost | at circle.http.ssl$wrap_force_ssl$fn__96696.invoke(ssl.clj:39)
dev.circlehost | at circle.http.methods$wrap_deny_unacceptable_methods$fn__95303.invoke(methods.clj:10)
dev.circlehost | at circle.http.exceptions$wrap_exceptions$fn__63267.invoke(exceptions.clj:107)
dev.circlehost | at circle.web.http.errors$wrap_status_pages$fn__84393.invoke(errors.clj:62)
dev.circlehost | at circle.http.logging$wrap_logging$fn__96796$thunk__21931__auto____96797.invoke(logging.clj:209)
dev.circlehost | at circle.http.logging$wrap_logging$fn__96796.invoke(logging.clj:208)
dev.circlehost | at circleci.request_trace.core$wrap_request_id$fn__15483.invoke(core.clj:31)
dev.circlehost | at org.httpkit.server.HttpHandler.run(RingHandler.java:91)
dev.circlehost | at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
dev.circlehost | at java.util.concurrent.FutureTask.run(FutureTask.java:266)
dev.circlehost | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
dev.circlehost | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
dev.circlehost | at java.lang.Thread.run(Thread.java:748)
I'm wondering what the correct way to handle if org.apache.commons.fileupload.FileUploadException
is throws, or the subclasses:
InvalidContentTypeException
IOFileUploadException
SizeException
UnknownSizeException
It's arguable that some of these are 4xx (size, context type) are some are 5xx (IO).
You can reproduce this by creating an empty file such as hoge.bin
and then using the following curl command
curl --data-binary @hoge.bin -H "Content-Type: multipart/form-data; boundary=Boundary+0xAbCdEfGbOuNdArY" localhost:3000/path/with/multipart/middleware
Trying to upload an empty file (Content-Length: 0) 100% results in the exception, so @weavejester's guess about the empty body is correct. (Reproduced with latest clj-commons/aleph)
Hi there,
We are getting an NPE thrown from the
ring.middleware.multipart-params
and I don't know where to start looking to track the problem down. Any help would be appreciated.This happens very rarely, 19 times in the last 7 days, on a HTTP endpoint that is accessed many, many thousands of times per day.
The exception is thrown from the
org.apache.commons.fileupload
library, which is called fromring.middleware.multipart-params
. There are a couple of our middleware items on the callstack, but I don't think these are very likely to be the cause.Callstack
Some context we have gathered:
In all cases, the User Agent is either
PostmanRuntime/7.4.0
orPostmanRuntime/7.3.0
.