Refactor XML parsing.

This commit is contained in:
Roger Braun 2017-04-27 09:43:58 +02:00
parent 9e9d95ec99
commit d1dce56a85
5 changed files with 30 additions and 16 deletions

View File

@ -1,5 +1,6 @@
defmodule Pleroma.Web.OStatus do defmodule Pleroma.Web.OStatus do
import Ecto.Query import Ecto.Query
import Pleroma.Web.XML
require Logger require Logger
alias Pleroma.{Repo, User, Web} alias Pleroma.{Repo, User, Web}
@ -18,7 +19,7 @@ def salmon_path(user) do
end end
def handle_incoming(xml_string) do 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) {: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
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 def make_user(author_doc) do
author = string_from_xpath("/author[1]/uri", author_doc) author = string_from_xpath("/author[1]/uri", author_doc)
name = string_from_xpath("/author[1]/name", author_doc) name = string_from_xpath("/author[1]/name", author_doc)

View File

@ -1,8 +1,9 @@
defmodule Pleroma.Web.Salmon do defmodule Pleroma.Web.Salmon do
use Bitwise use Bitwise
alias Pleroma.Web.XML
def decode(salmon) do 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, data} = :xmerl_xpath.string('string(//me:data[1])', doc)
{:xmlObj, :string, sig} = :xmerl_xpath.string('string(//me:sig[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 def fetch_magic_key(salmon) do
[data, _, _, _, _] = decode(salmon) [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) {:xmlObj, :string, uri} = :xmerl_xpath.string('string(//author[1]/uri)', doc)
uri = to_string(uri) uri = to_string(uri)
base = URI.parse(uri).host base = URI.parse(uri).host
# TODO: Find out if this endpoint is mandated by the standard. # 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]]) {: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) {:xmlObj, :string, magickey} = :xmerl_xpath.string('string(//Link[@rel="magic-public-key"]/@href)', doc)
"data:application/magic-public-key," <> magickey = to_string(magickey) "data:application/magic-public-key," <> magickey = to_string(magickey)

View File

@ -3,6 +3,7 @@ defmodule Pleroma.Web.Websub do
alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription} alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription}
alias Pleroma.Web.OStatus.FeedRepresenter alias Pleroma.Web.OStatus.FeedRepresenter
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
alias Pleroma.Web.XML
import Ecto.Query import Ecto.Query

View File

@ -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

View File

@ -1,6 +1,7 @@
defmodule Pleroma.Web.OStatusTest do defmodule Pleroma.Web.OStatusTest do
use Pleroma.DataCase use Pleroma.DataCase
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
alias Pleroma.Web.XML
test "handle incoming notes" do test "handle incoming notes" do
incoming = File.read!("test/fixtures/incoming_note_activity.xml") incoming = File.read!("test/fixtures/incoming_note_activity.xml")
@ -26,7 +27,7 @@ test "handle incoming replies" do
describe "new remote user creation" do describe "new remote user creation" do
test "make new user or find them based on an 'author' xml doc" do test "make new user or find them based on an 'author' xml doc" do
incoming = File.read!("test/fixtures/user_name_only.xml") 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) {: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 test "tries to use the information in poco fields" do
incoming = File.read!("test/fixtures/user_full.xml") 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) {:ok, user} = OStatus.find_or_make_user(doc)