Http commons too standard for some web servers

I spent a whole day trying to figure out how to use http components to send a file from a java program mimicking a POST multipart/form-data form.

The problem was that while a common HTML form worked with no problems at all, the POST generated with http commons was always rejected by the server.

So, I decided to dump the HTTP requests sent by the browser and by http components, and here’s what I got.

Request generated from the browser

------WebKitFormBoundaryYuxYFZoJg4fx2Tfu

Content-Disposition: form-data; name="filename"; filename="index.idx"
Content-Type: application/octet-stream
[file content]

------WebKitFormBoundaryYuxYFZoJg4fx2Tfu--

Request generated from http commons

--xFwQ1jzWbqQIKivTUrK68BurHld66kpMCz3Fv9P

Content-Disposition: form-data; name="filename"; filename="index.idx"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
[file content]
--xFwQ1jzWbqQIKivTUrK68BurHld66kpMCz3Fv9P--

As you can see there’s a “Content-Transfer-Encoding: binary” header that is the one that caused the problem in the server. After a while I discover than when you create a new MultipartEntity, you can optionally specify a mode of operation. Currently supported modes are HttpMultipartMode.STRICT and HttpMultipartMode.BROWSER_COMPATIBLE. It’s not worth to mention that the default mode in STRICT, that maybe does not work with old or not fully standard web servers. If BROWSER_COMPATIBLE is specified instead, the data sent by http commons does not contain any Content-Transfer-Encoding header, and the delivery of the file terminates successfully.

Here’s the piece of code:

MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);