Refactor XML parsing.
authorRoger Braun <roger@rogerbraun.net>
Thu, 27 Apr 2017 07:43:58 +0000 (09:43 +0200)
committerRoger Braun <roger@rogerbraun.net>
Thu, 27 Apr 2017 07:43:58 +0000 (09:43 +0200)
lib/pleroma/web/ostatus/ostatus.ex
lib/pleroma/web/salmon/salmon.ex
lib/pleroma/web/websub/websub.ex
lib/pleroma/web/xml/xml.ex [new file with mode: 0644]
test/web/ostatus/ostatus_test.exs

index 5b68f057e5cbb7df9cd98892f9eb06352f3e63dc..89b4825928fdbd793c286c62a23a9327568f2366 100644 (file)
@@ -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 @@ defmodule Pleroma.Web.OStatus 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 @@ defmodule Pleroma.Web.OStatus 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)
index 24b5eb0d9664426a3c12bc33856845f162ebefa5..99cca1f5518bd625396532218adc0dc3fb789bfb 100644 (file)
@@ -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 @@ defmodule Pleroma.Web.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)
index 03b0aec8fb5531653e4a7b53bdaee1db63b57b5c..5372416e6bc4b88c56fe6274278c1e9d8d7539c3 100644 (file)
@@ -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 (file)
index 0000000..22faf72
--- /dev/null
@@ -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
index 96f2cb4f382b17666f1c1cbf9f4ee09c81a1b381..140b32f367194eb1924374d229906b1e45ea05a2 100644 (file)
@@ -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 @@ defmodule Pleroma.Web.OStatusTest 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 @@ defmodule Pleroma.Web.OStatusTest 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)