From d1dce56a85e041f78e1d50900a0c9591610de2b9 Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Thu, 27 Apr 2017 09:43:58 +0200 Subject: [PATCH] Refactor XML parsing. --- lib/pleroma/web/ostatus/ostatus.ex | 13 ++----------- lib/pleroma/web/salmon/salmon.ex | 8 +++++--- lib/pleroma/web/websub/websub.ex | 1 + lib/pleroma/web/xml/xml.ex | 19 +++++++++++++++++++ test/web/ostatus/ostatus_test.exs | 5 +++-- 5 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 lib/pleroma/web/xml/xml.ex diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index 5b68f057e..89b482592 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -1,5 +1,6 @@ defmodule Pleroma.Web.OStatus do import Ecto.Query + import Pleroma.Web.XML require Logger alias Pleroma.{Repo, User, Web} @@ -18,7 +19,7 @@ def salmon_path(user) do end def handle_incoming(xml_string) do - {doc, _rest} = :xmerl_scan.string(to_charlist(xml_string)) + doc = parse_document(xml_string) {:xmlObj, :string, object_type } = :xmerl_xpath.string('string(/entry/activity:object-type[1])', doc) @@ -91,16 +92,6 @@ def find_or_make_user(author_doc) do end end - defp string_from_xpath(xpath, doc) do - {:xmlObj, :string, res} = :xmerl_xpath.string('string(#{xpath})', doc) - - res = res - |> to_string - |> String.trim - - if res == "", do: nil, else: res - end - def make_user(author_doc) do author = string_from_xpath("/author[1]/uri", author_doc) name = string_from_xpath("/author[1]/name", author_doc) diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex index 24b5eb0d9..99cca1f55 100644 --- a/lib/pleroma/web/salmon/salmon.ex +++ b/lib/pleroma/web/salmon/salmon.ex @@ -1,8 +1,9 @@ defmodule Pleroma.Web.Salmon do use Bitwise + alias Pleroma.Web.XML def decode(salmon) do - {doc, _rest} = :xmerl_scan.string(to_charlist(salmon)) + doc = XML.parse_document(salmon) {:xmlObj, :string, data} = :xmerl_xpath.string('string(//me:data[1])', doc) {:xmlObj, :string, sig} = :xmerl_xpath.string('string(//me:sig[1])', doc) @@ -22,16 +23,17 @@ def decode(salmon) do def fetch_magic_key(salmon) do [data, _, _, _, _] = decode(salmon) - {doc, _rest} = :xmerl_scan.string(to_charlist(data)) + doc = XML.parse_document(data) {:xmlObj, :string, uri} = :xmerl_xpath.string('string(//author[1]/uri)', doc) uri = to_string(uri) base = URI.parse(uri).host # TODO: Find out if this endpoint is mandated by the standard. + # At least diaspora does it differently {:ok, response} = HTTPoison.get(base <> "/.well-known/webfinger", ["Accept": "application/xrd+xml"], [params: [resource: uri]]) - {doc, _rest} = :xmerl_scan.string(to_charlist(response.body)) + doc = XML.parse_document(response.body) {:xmlObj, :string, magickey} = :xmerl_xpath.string('string(//Link[@rel="magic-public-key"]/@href)', doc) "data:application/magic-public-key," <> magickey = to_string(magickey) diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex index 03b0aec8f..5372416e6 100644 --- a/lib/pleroma/web/websub/websub.ex +++ b/lib/pleroma/web/websub/websub.ex @@ -3,6 +3,7 @@ defmodule Pleroma.Web.Websub do alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription} alias Pleroma.Web.OStatus.FeedRepresenter alias Pleroma.Web.OStatus + alias Pleroma.Web.XML import Ecto.Query diff --git a/lib/pleroma/web/xml/xml.ex b/lib/pleroma/web/xml/xml.ex new file mode 100644 index 000000000..22faf72df --- /dev/null +++ b/lib/pleroma/web/xml/xml.ex @@ -0,0 +1,19 @@ +defmodule Pleroma.Web.XML do + def string_from_xpath(xpath, doc) do + {:xmlObj, :string, res} = :xmerl_xpath.string('string(#{xpath})', doc) + + res = res + |> to_string + |> String.trim + + if res == "", do: nil, else: res + end + + def parse_document(text) do + {doc, _rest} = text + |> :binary.bin_to_list + |> :xmerl_scan.string + + doc + end +end diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index 96f2cb4f3..140b32f36 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -1,6 +1,7 @@ defmodule Pleroma.Web.OStatusTest do use Pleroma.DataCase alias Pleroma.Web.OStatus + alias Pleroma.Web.XML test "handle incoming notes" do incoming = File.read!("test/fixtures/incoming_note_activity.xml") @@ -26,7 +27,7 @@ test "handle incoming replies" do describe "new remote user creation" do test "make new user or find them based on an 'author' xml doc" do incoming = File.read!("test/fixtures/user_name_only.xml") - {doc, _rest} = :xmerl_scan.string(to_charlist(incoming)) + doc = XML.parse_document(incoming) {:ok, user} = OStatus.find_or_make_user(doc) @@ -44,7 +45,7 @@ test "make new user or find them based on an 'author' xml doc" do test "tries to use the information in poco fields" do incoming = File.read!("test/fixtures/user_full.xml") - {doc, _rest} = :xmerl_scan.string(to_charlist(incoming)) + doc = XML.parse_document(incoming) {:ok, user} = OStatus.find_or_make_user(doc)