Archive for the ‘http’ tag
HTTP PUT Rails gotcha
So, I was pretty surprised to learn that Rails PUT requests are required to be “application/x-www-form-urlencoded”. Definitely not expected behavior when I am just consuming someone else’s API. If that isn’t completely true, feel free to enlighten me.
Basically here’s what happened: I was doing a HTTP PUT using C# to an API on Rails. C# looked pretty much like this:
request = (HttpWebRequest) WebRequest.Create(uri);
request.Method = "PUT";
request.ContentType = "text/plain";
request.ContentLength = postData.Length;
using(var writeStream = request.GetRequestStream())
{
var bytes = (new UTF8Encoding()).GetBytes(postData);
writeStream.Write(bytes, 0, bytes.Length);
}
But the code no worky.
After trying a couple of different things, I talked to the people who implemented the API. They said the Rails log indicated that I wasn’t PUTing anything .i.e. they could see the PUT request, but not the data. So, my first instinct was that it must be the content type, but was told it very definitely couldn’t be that.
Mystified, I wrote a quick Ruby script to do the same request. It worked!
Out came Wireshark.
Guess what the differences were ?
- C# has keep-alive set, Ruby didn’t.
- Ruby content-type was “application/x-www-form-urlencoded”.
I figured 1 really wasn’t the problem and since 2 supported my gut reaction, I went with it.
Sure enough, once I set content-type to “application/x-www-form-urlencoded” the c# code worky.
Moral of story:
- Remember Rails requires a PUT to be of Content-type:”application/x-www-form-urlencoded”. Maybe it takes other things, but it doesn’t take text/plain.
- Be very aware how the different layers/libraries interact in your app. All that magic is a double edged sword. There are 3rd party libs out there that do everything. But when you use one, please be sure you know what it does
- When debugging take all assumptions (esp. other people’s
) with a grain of salt.