I got it following the steps below:
- Change Plug.Parses configuration in endpoint.ex.
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json, :xml],
pass: ["*/*"],
json_decoder: Poison,
xml_decoder: :xmerl_scan
- Like you, I implemented a XML parser too, but I just take care about subtype parameter.
defmodule Plug.Parsers.XML do
@behaviour Plug.Parsers
import Plug.Conn
def parse(conn, _, "xml", _headers, opts) do
decoder = Keyword.get(opts, :xml_decoder) || raise ArgumentError, "XML parser expects a :xml_decoder option"
conn
|> read_body(opts)
|> decode(decoder)
end
def parse(conn, _type, _subtype, _headers, _opts) do
{:next, conn}
end
defp decode({:ok, body, conn}, decoder) do
case decoder.string(String.to_charlist(body)) do
{parsed, []} ->
{:ok, %{xml: parsed}, conn}
error ->
raise "Malformed XML #{error}"
end
rescue
e -> raise Plug.Parsers.ParseError, exception: e
end
end
After these steps, the XML becomes parsed in my Plug connections:
%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{},
before_send: [#Function<1.20934668/1 in Plug.Logger.call/2>,
#Function<0.111727833/1 in Phoenix.LiveReloader.before_send_inject_reloader/2>],
body_params: %{xml: {:xmlElement, :"soapenv:Envelope", :"soapenv:Envelope",
{'soapenv', 'Envelope'},
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]}, [], 1,
[{:xmlAttribute, :"xmlns:soapenv", [], {'xmlns', 'soapenv'}, [],
["soapenv:Envelope": 1], 1, [],
'http://schemas.xmlsoap.org/soap/envelope/', false},
{:xmlAttribute, :"xmlns:use", [], {'xmlns', 'use'}, [],
["soapenv:Envelope": 1], 2, [], 'http://user.auth.ws.util.componente/',
false}],
[{:xmlText, ["soapenv:Envelope": 1], 1, [], '\n ', :text},
{:xmlElement, :"soapenv:Header", :"soapenv:Header", {'soapenv', 'Header'},
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]},
["soapenv:Envelope": 1], 2, [], [], [], '/Users/castilho/elixir/argonath',
:undeclared}, {:xmlText, ["soapenv:Envelope": 1], 3, [], '\n ', :text},
{:xmlElement, :"soapenv:Body", :"soapenv:Body", {'soapenv', 'Body'},
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]},
["soapenv:Envelope": 1], 4, [],
[{:xmlText, ["soapenv:Body": 4, "soapenv:Envelope": 1], 1, [], '\n ',
:text},
{:xmlElement, :"use:signin", :"use:signin", {'use', 'signin'},
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]},
["soapenv:Body": 4, "soapenv:Envelope": 1], 2, [],
[{:xmlText, ["use:signin": 2, "soapenv:Body": 4, "soapenv:Envelope": 1],
1, [], '\n ', :text},
{:xmlElement, :username, :username, [],
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]},
["use:signin": 2, "soapenv:Body": 4, "soapenv:Envelope": 1], 2, [],
[{:xmlText, [...], ...}], [], '/Users/castilho/elixir/argonath', ...},
{:xmlText, ["use:signin": 2, "soapenv:Body": 4, "soapenv:Envelope": 1],
3, [], '\n ', :text},
{:xmlElement, :password, :password, [],
{:xmlNamespace, [], [{'soapenv', ...}, {'use', ...}]},
["use:signin": 2, "soapenv:Body": 4, "soapenv:Envelope": 1], 4, [],
[...], ...},
{:xmlText, ["use:signin": 2, "soapenv:Body": 4, "soapenv:Envelope": 1],
5, [], '\n ', :text}], [], '/Users/castilho/elixir/argonath',
:undeclared},
{:xmlText, ["soapenv:Body": 4, "soapenv:Envelope": 1], 3, [], '\n ',
:text}], [], '/Users/castilho/elixir/argonath', :undeclared},
{:xmlText, ["soapenv:Envelope": 1], 5, [], '\n', :text}], [],
'/Users/castilho/elixir/argonath', :undeclared}},
cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false,
host: "localhost", method: "POST", owner: #PID<0.413.0>,
params: %{:xml => {:xmlElement, :"soapenv:Envelope", :"soapenv:Envelope",
{'soapenv', 'Envelope'},
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]}, [], 1,
[{:xmlAttribute, :"xmlns:soapenv", [], {'xmlns', 'soapenv'}, [],
["soapenv:Envelope": 1], 1, [],
'http://schemas.xmlsoap.org/soap/envelope/', false},
{:xmlAttribute, :"xmlns:use", [], {'xmlns', 'use'}, [],
["soapenv:Envelope": 1], 2, [], 'http://user.auth.ws.util.componente/',
false}],
[{:xmlText, ["soapenv:Envelope": 1], 1, [], '\n ', :text},
{:xmlElement, :"soapenv:Header", :"soapenv:Header", {'soapenv', 'Header'},
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]},
["soapenv:Envelope": 1], 2, [], [], [], '/Users/castilho/elixir/argonath',
:undeclared}, {:xmlText, ["soapenv:Envelope": 1], 3, [], '\n ', :text},
{:xmlElement, :"soapenv:Body", :"soapenv:Body", {'soapenv', 'Body'},
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]},
["soapenv:Envelope": 1], 4, [],
[{:xmlText, ["soapenv:Body": 4, "soapenv:Envelope": 1], 1, [], '\n ',
:text},
{:xmlElement, :"use:signin", :"use:signin", {'use', 'signin'},
{:xmlNamespace, [],
[{'soapenv', :"http://schemas.xmlsoap.org/soap/envelope/"},
{'use', :"http://user.auth.ws.util.componente/"}]},
["soapenv:Body": 4, "soapenv:Envelope": 1], 2, [],
[{:xmlText, ["use:signin": 2, "soapenv:Body": 4, "soapenv:Envelope": 1],
1, [], '\n ', ...},
{:xmlElement, :username, :username, [], ...},
{:xmlText, ["use:signin": 2, ...], 3, ...},
{:xmlElement, :password, ...}, {:xmlText, [...], ...}], [],
'/Users/castilho/elixir/argonath', :undeclared},
{:xmlText, ["soapenv:Body": 4, "soapenv:Envelope": 1], 3, [], '\n ',
:text}], [], '/Users/castilho/elixir/argonath', :undeclared},
{:xmlText, ["soapenv:Envelope": 1], 5, [], '\n', :text}], [],
'/Users/castilho/elixir/argonath', :undeclared},
"path" => ["AutenticadorUsuario", "AutenticadorUsuarioService"]},
path_info: ["AutenticadorUsuario", "AutenticadorUsuarioService"],
path_params: %{}, peer: {{127, 0, 0, 1}, 64668}, port: 4000,
private: %{Argonath.Router => {[], %{}},
:phoenix_endpoint => Argonath.Endpoint, :phoenix_format => "xml",
:phoenix_layout => {Argonath.LayoutView, :simple},
:phoenix_pipelines => [:api],
:phoenix_route => #Function<15.41572747/1 in Argonath.Router.match_route/4>,
:phoenix_router => Argonath.Router,
:plug_session_fetch => #Function<1.131660147/1 in Plug.Session.fetch_session/1>},
query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1},
req_cookies: %Plug.Conn.Unfetched{aspect: :cookies},
req_headers: [{"host", "localhost:4000"}, {"connection", "keep-alive"},
{"content-length", "312"},
{"postman-token", "83a68e53-bc9b-fb4c-3946-22d69cef413c"},
{"cache-control", "no-cache"},
{"origin", "chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop"},
{"soapaction", "\"\""},
{"user-agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36"},
{"content-type", "text/xml"}, {"accept", "*/*"},
{"accept-encoding", "gzip, deflate, br"},
{"accept-language", "en-US,en;q=0.8,pt;q=0.6"}],
request_path: "/AutenticadorUsuario/AutenticadorUsuarioService",
resp_body: nil, resp_cookies: %{},
resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"},
{"x-request-id", "qnat2ltjm71gfj9hkl8lc0q1p760li0k"}], scheme: :http,
script_name: [],
secret_key_base: "WPKMRrd5cIrStaiO1erZu9pW8j1I10gyXzrtU2hy4NR1mgf8U790m9liCIfWqTHP",
state: :unset, status: nil}