parse_formatted_request_parameters does not respect parameters[:format]

I have been working on a project where I need to parse various flavors
of XML that are POSTed from various SMS message aggregators into
request_parameters. I tried to take advantage of the built in
ActionController::Base.param_parsers but ran into some serious
problems.

Since I can't control the aggregators' HTTP Content-Type headers to
resolve the Mime::Type, I need to rely on the ':format' idiom in Rails
routes. So instead of an HTTP POST to '/sms_messages.xml' I POST to '/
sms_messages.clickatell'. Unfortunately the format parameter isn't
parsed out of the request until after the param_parser is selected:

http://github.com/rails/rails/tree/master/actionpack/lib/action_controller/request.rb#L414

It appears that the content_type variable can only resolved from the
Content-Type header at this point and not from params[:format] (or any
other parameters for this matter). I need rails to respect the format
of the request over the Content-Type header on a POST or PUT.

I want to fix this but I'm not sure where to start (I get stuck in the
recognize_path code... go figure). Any suggestions or help would be
greatly appreciated to get me heading down the right path.

Ok I ran into a chicken or egg problem -- I need to have some input
from the core team about the intentions of parsing the _method
parameter.

When I create a POST or PUT request, RouteSet needs to determine the
method (POST, PUT, GET...) of the request. Since browsers only support
POST or GET, rails depends on a _method parameter to determine the
request method for some requests. When Request#request_method is
called, it calls Request#parameters which calls
Request#parse_formatted_request_parameters method to try to find the
_method parameter (be it in XML, JSON, or whatever). At this point in
the request cycle, Request#path_parameters have not yet been
determined so I have no way to figure out the parsing strategy based
on Request#path_parameters[:format] in
Request#parse_formatted_request_parameters. This, coupled with the
memoization of Request#parameters, is causing this chicken/egg format
problem. Ideally I would run
Request#parse_formatted_request_parameters _after_ RouteSet determines
the format of the request.

My question is -- do all formats need to be parsed to support the
_method parameter? It seems that _method was created to make up for
the short comings of web browsers; which implies _method only needs to
be parsed for the :url_encoded_form, and :multipart_form formats. When
would somebody use the _method parameter in JSON, XML, or some other
data format?

Brad

I have been working on a project where I need to parse various flavors
of XML that are POSTed from various SMS message aggregators into
request_parameters. I tried to take advantage of the built in
ActionController::Base.param_parsers but ran into some serious
problems.

Since I can't control the aggregators' HTTP Content-Type headers to
resolve the Mime::Type, I need to rely on the ':format' idiom in Rails
routes. So instead of an HTTP POST to '/sms_messages.xml' I POST to '/
sms_messages.clickatell'. Unfortunately the format parameter isn't
parsed out of the request until after the param_parser is selected:

http://github.com/rails/rails/tree/master/actionpack/lib/action_controller/request.rb#L414

It appears that the content_type variable can only resolved from the
Content-Type header at this point and not from params[:format] (or any
other parameters for this matter). I need rails to respect the format
of the request over the Content-Type header on a POST or PUT.

I want to fix this but I'm not sure where to start (I get stuck in the
recognize_path code... go figure). Any suggestions or help would be
greatly appreciated to get me heading down the right path.

We can't really make the parameter parser depend on params[:format]
because we can't figure it out until after we've parsed the parameters
already. We could make an exception for the case where the route
overrides params[:format] but that doesn't seem particularly tidy.

More fundamentally though, the format in params[:format] is the
*response* format, and the parsers are the request format. Seems a
mistake to couple those two together.