Pages: Welcome | Projects

CURL redirection with PUT upon HTTP 301 (and Django)

Tags: [ shell ] [ Today I learned ] [ wtf ]

As part of my job, I'm currently coding a REST API in a Django-based server.

While doing some manual tests on what I wrote, I noticed that my PUT requests contained no HTTP body, and I started to investigate on the reason for it.

After hours of seeking without finding, and thanks to a colleague who stepped in with some help, the reason for it became clear.

First off, let's mention the old problem with paths terminating with /. What is the difference between http://$host/x and http://$host/x/? Well, it depends on who is answering your requests. If you work with Django, not having a trailing / will end up in a 301 redirection towards the same endpoint with a trailing /. This is probably the same with other frameworks.

I'm using curl for my manual testing. As soon as I stumbled into this behaviour I simply added the -L flag to my scripts, so I could automatically follow the redirects even when I forgot the trailing /.

Then I implemented the PUT method for the endpoint I was focusing on, and while verifying it to be working as intended I found that the request body was empty. Not only that, but even the PUT method of other endpoints (implemented by my colleagues) seemed to have the same issue.

It turns out that curl is just dropping the body, and that it is not a bug, it is a feature.

That's how I got to know about the --post301, --post302 and --post303 options in curl.