Compojure: getting a body from a POST request from which the Content-Type header was missing

Given this snippet:

(defroutes main-routes (POST "/input/:controller" request (let [buff (ByteArrayOutputStream.)] (copy (request :body) buff) ;; --- snip 

The value buff will be a non-empty byte array if the request has a Content-Type header. The value may not be relevant; the title should be there.

However, I need to reset the body (hm ..., which didn’t work out that way) if the request came without a content type so that the client can track abusive downloads. (Downloading software is not under my control, and its maintainers will not provide anything extra in the headers.)

Thanks for any ideas on how to solve or get around this!

EDIT:

Here are the headers I get from the client:

 { "content-length" "159", "accept" "*/*", "host" (snip), "user-agent" (snip) } 

In addition, I found that Ring, using the Java ServletRequest instance, populates the content type with the standard default, x-www-form-urlencoded. I now assume that HTTPParser, which supplies the body via HTTPParser # Input, cannot parse it correctly.

+4
source share
2 answers

I am facing the same problem. This is definitely one of the middleware that cannot properly parse the body and transform :body . The main problem is that Content-Type assumes that the body should be understandable.

Using ngrep , I found out how curl mixes middleware. The following, while intuitive (or pretty sexy) on the command line, sends the wrong Content-Type , which confuses the middleware:

 curl -nd "Unknown error" http://localhost:3000/event/error T 127.0.0.1:44440 -> 127.0.0.1:3000 [AP] POST /event/error HTTP/1.1. Authorization: Basic SzM5Mjg6ODc2NXJkZmdoam5idmNkOQ==. User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3. Host: localhost:3000. Accept: */*. Content-Length: 13. Content-Type: application/x-www-form-urlencoded. . Unknown error 

The following, however, causes the Content-Type be opaque, and the middleware will not interfere :body .

 curl -nd "Unknown error" -H "Content-Type: application/data" http://localhost:3000/event/error T 127.0.0.1:44441 -> 127.0.0.1:3000 [AP] POST /event/error HTTP/1.1. Authorization: Basic SzM5Mjg6ODc2NXJkZmdoam5idmNkOQ==. User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3. Host: localhost:3000. Accept: */*. Content-Type: application/data. Content-Length: 13. . Unknown error 

I am considering replacing the middleware with a more liberal one, because although the request is incorrect, I would still like to decide what to do with the body. This is a really weird choice for a zero request body when the request does not make sense. I believe that a more correct behavior would be to pass it to an error handler, which will return 400 Bad Request or 406 Not Acceptable by default.

Any thoughts on this? In my case, I could offer a patch for Compojure.

+1
source

In accordance with:

http://mmcgrana.github.com/ring/ring.middleware.content-type-api.html

default content type: application/octet-stream . If you do not actively support this type of content, can you just check if the content type matches this type and then discard everything you need based on this?

+1
source

Source: https://habr.com/ru/post/1382312/


All Articles