Why does Rails try to parse XML received to a controller if mime type sent is "text/xml"

We have a web service to which clients post xml.

One of our clients is using .NET and we receive their data, however if
they
send it as “text/xml” mime type, I receive it at the controller parsed
like:

{“WEB_REQUEST”=>{“AUTHENTICATION”=>{“LOGIN”=>“ft”, “PASSWORD”=>“dir”,
“POSTING_SYSTEM”=>“zzzLending”, “CLIENT_ID”=>“LDAP”},
“REQUEST”=>{“COMPARISON”=>{“ACTION”=>“new”, “DOCUMENT”=>"<RESPONSE_GROUP
MISMOVersionID=“2.3.1” _ID=“RGRept000001”> …

However if they disable the content type in their code – removing this
line: (//web.ContentType = “text/xml”:wink:

Then I get what I need and would expect:
{“<WEB_REQUEST>\n\t\n\t\t<POSTING_SYSTEM>zzzLending</POSTING_SYSTEM>\n\t\t<CLIENT_ID>LDAP</CLIENT_ID>\n\t\tft\n\t\tdir\n\t\n\t\n\t\t\n\t\t\tnew\n\t\t\t<DOCUMENT
format”=>"“MISMO” type=“credit report”><![CDATA[<RESPONSE_GROUP
MISMOVersionID=“2.3.1” _ID=“RGRept000001”> …

Is there a way for me to handle within Rails the situation where they
are
posting the xml mime type? Really, I would expect them to be able to do
so
as it is in fact xml. Can I tell Rails to not do any magic to the
incoming
xml? (just kind of tacky to tell our client ‘I know it is an xml
request,
but dont send it with the xml content type’).

Thanks!

David

David K. wrote in post #962399:

We have a web service to which clients post xml.

One of our clients is using .NET and we receive their data, however if
they
send it as “text/xml” mime type, I receive it at the controller parsed
like:

{“WEB_REQUEST”=>{“AUTHENTICATION”=>{“LOGIN”=>“ft”, “PASSWORD”=>“dir”,
“POSTING_SYSTEM”=>“zzzLending”, “CLIENT_ID”=>“LDAP”},
“REQUEST”=>{“COMPARISON”=>{“ACTION”=>“new”, “DOCUMENT”=>"<RESPONSE_GROUP
MISMOVersionID=“2.3.1” _ID=“RGRept000001”> …

However if they disable the content type in their code – removing this
line: (//web.ContentType = “text/xml”:wink:

Then I get what I need and would expect:

{"<WEB_REQUEST>\n\t\n\t\t<POSTING_SYSTEM>zzzLending</POSTING_SYSTEM>\n\t\t<CLIENT_ID>LDAP</CLIENT_ID>\n\t\tft\n\t\tdir\n\t\n\t\n\t\t\n\t\t\tnew\n\t\t\t<DOCUMENT

format"=>"“MISMO” type=“credit report”><![CDATA[<RESPONSE_GROUP
MISMOVersionID=“2.3.1” _ID=“RGRept000001”> …

Why are you trying to defeat Rails’ XML processing? It seems to me that
it would normally be more efficient to work with it.

[…]

Can I tell Rails to not do any magic to the
incoming
xml? (just kind of tacky to tell our client ‘I know it is an xml
request,
but dont send it with the xml content type’).

Probably. But I wonder if it’s really the right thing to do.

Thanks!

David

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Thu, Nov 18, 2010 at 1:39 PM, Marnen Laibow-Koser
[email protected]wrote:

“REQUEST”=>{“COMPARISON”=>{“ACTION”=>“new”, “DOCUMENT”=>"<RESPONSE_GROUP
MISMOVersionID=“2.3.1” _ID=“RGRept000001”> …

Why are you trying to defeat Rails’ XML processing? It seems to me that
it would normally be more efficient to work with it.

Well, if I realized this before I might have. However I have a parser
built
with Nokogiri which handles my requests very nicely and makes no sense
to
redo it as it is solid and well tested.

I just noticed I can call
params[“WEB_REQUEST”].to_xml

and I get

"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n
\n
xxx\n xxx\n
xxx\n xxx</CLIE

So I could write a hack which (1) adds back the root <WEB_REQUEST>
node,
removes the node… but this is real ugly. Do you have any idea
where I would look to disable this the right way?

The parameter parsing is happing in middleware.

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/params_parser.rb

As you can see in the private method “parse_formatted_parameters(env)”
the parsing of XML, JSON, YML, etc is based on mime-type.

It seems to me like one could possibly write a small custom middleware
that overrides the incoming mime-type and insert that middleware just
before ActionController::ParamsParser.

config.middleware.insert_before(existing_middleware, new_middleware,
args) – Adds the new middleware before the specified existing middleware
in the middleware stack.

Seems like that would effectively disable the automatic parsing of
incoming XML.

On Nov 18, 2010, at 2:47 PM, David K. wrote:

like:
line: (//web.ContentType = “text/xml”:wink:

and I get

"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n
\n xxx\n xxx</
PASSWORD>\n xxx\n xxx</CLIE

So I could write a hack which (1) adds back the root <WEB_REQUEST>
node, removes the node… but this is real ugly. Do you
have any idea where I would look to disable this the right way?

This comment:
Parsing YAML from a POST request
is from two years ago and defines a config:
ActionController::Base.param_parsers[Mime::YAML] = :yaml
which sounds like it is in the same part of the processing that you’re
interested in. I don’t know whether it is supported in whichever
version of rails you’re using, but it certainly seems like a good path
to investigate.

-Rob

For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
.

Rob B.
[email protected] http://AgileConsultingLLC.com/
[email protected] http://GaslightSoftware.com/