Anne van Kesteren

HTTP methods, Web browsers and XMLHttpRequest

As with most features Web browsers support (well, try to) there are interoperability problems with HTTP methods. At least when used with XMLHttpRequest. To test HTTP methods I borrowed an eighty line Python Web server script (uses the socket and asyncore modules) from a collegue and hacked it to support a special request URI /echo-method. Indeed, it prints the request method in the response entity body. I tested in Firefox 3.0a8pre (Firefox), Opera 9.50 Alpha (Opera), and Internet Explorer 7 (IE, I believe it’s not the final version by the way). The methods I tested are in the list of HTTP methods. I also tested lowercase variants from those methods which per HTTP are different methods as HTTP method names are case-sensitive. In addition I tested the custom Foobar and FOOBAR methods and their lowercase variant.

GET and POST work the same everywhere. A case-insensitive match is done for them and they are uppercased when the request is made. Fortunately these are the most frequently used methods so the problem may not be that bad. From a purity perspective it may be annoying that a case-insensitive match is performed, but that’s about dealing with the real world. Not much we can change about that now.

Firefox “supports” the methods from RFC 2616 and RFC 2518, except for TRACE. That method throws an exception for security reasons. All the supported HTTP methods are case-insensitively matched against and uppercased prior to the request. This means that traCe throws as well and that propFIND is identical to PROPFIND. For custom HTTP methods the story is a bit different. The first request I made was to Foobar which resulted in a Foobar request. However, after that foobar, FOOBAR et cetera resulted in a Foobar request too. Firefox probably keeps some kind of hash table around of used and known methods and performs a case-insensitive match between the methods listed in that hash table and the method requested.

Opera has an issue with OPTIONS: the request never finishes loading. (In earlier versions of Opera it is converted to GET.) For known methods it performs a case-insensitive match just like Firefox. The known methods are GET, HEAD, POST, PUT, and DELETE. HEAD and PUT never have a response entity body. All other methods, including custom, result in GET requests.

IE has probably the weirdest implementation. It performs a case-insensitive match against a list of supported methods, just like the other browsers. However, only for GET, POST, and PUT is the input actually uppercased before the request. So get results in GET, but head results in head. In this way, it supports RFC 2616 and RFC 2518 with TRACE and CONNECT as exceptions. If you use HEAD (uppercase) there will not be any response body. Methods not supported by IE will cause an exception to be raised. (This could be different for prior versions of IE.)

In contrast with all this, the XMLHttpRequest draft specification requires browsers to do a case-insensitive match for the OPTIONS, GET, HEAD, POST, PUT, and DELETE HTTP methods. If there is a match they must be uppercased before the request. An exception is raised for insecure methods and every other method is to be used unchanged in the request. (The insecure methods should probably be explicitly listed: TRACE and CONNECT.)

Comments

  1. When I wrote this post I hadn’t discovered the SEARCH method yet. (Added that to the list of HTTP methods now.) Opera supports the method in a case-insensitive way. IE throws. For Firefox it is like any other unknown method.

    Posted by Anne van Kesteren at