From f3f933ef834e8a3643cb59961537f73f00c13460 Mon Sep 17 00:00:00 2001 From: "Ross A. Baker" Date: Sat, 11 Jun 2022 21:47:23 -0400 Subject: [PATCH 1/2] Mark the loadXML call as blocking --- .../org/http4s/scalaxml/ElemInstances.scala | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/scala-xml/src/main/scala/org/http4s/scalaxml/ElemInstances.scala b/scala-xml/src/main/scala/org/http4s/scalaxml/ElemInstances.scala index abc5797..c4619d2 100644 --- a/scala-xml/src/main/scala/org/http4s/scalaxml/ElemInstances.scala +++ b/scala-xml/src/main/scala/org/http4s/scalaxml/ElemInstances.scala @@ -17,7 +17,10 @@ package org.http4s package scalaxml +import cats.data.EitherT +import cats.effect.Async import cats.effect.Concurrent +import cats.syntax.all._ import org.http4s.Charset.`UTF-8` import org.http4s.headers.`Content-Type` @@ -49,7 +52,8 @@ trait ElemInstances { * * @return an XML element */ - implicit def xml[F[_]](implicit F: Concurrent[F]): EntityDecoder[F, Elem] = { + @deprecated("Blocks. Use xmlDecoder with an Async constraint.", "0.23.12") + def xml[F[_]](implicit F: Concurrent[F]): EntityDecoder[F, Elem] = { import EntityDecoder._ decodeBy(MediaType.text.xml, MediaType.text.html, MediaType.application.xml) { msg => val source = new InputSource() @@ -67,4 +71,25 @@ trait ElemInstances { } } } + + implicit def xmlDecoder[F[_]](implicit F: Async[F]): EntityDecoder[F, Elem] = { + import EntityDecoder._ + decodeBy(MediaType.text.xml, MediaType.text.html, MediaType.application.xml) { msg => + val source = new InputSource() + msg.charset.foreach(cs => source.setEncoding(cs.nioCharset.name)) + + collectBinary(msg).flatMap[DecodeFailure, Elem] { chunk => + source.setByteStream(new ByteArrayInputStream(chunk.toArray)) + val saxParser = saxFactory.newSAXParser() + EitherT( + F.blocking(XML.loadXML(source, saxParser)) + .map(Either.right[DecodeFailure, Elem](_)) + .recover { case e: SAXParseException => + Left(MalformedMessageBodyFailure("Invalid XML", Some(e))) + } + ) + } + } + } + } From fa536117853bb08ee1f014e5f628342ce960ef1a Mon Sep 17 00:00:00 2001 From: "Ross A. Baker" Date: Sat, 11 Jun 2022 21:52:23 -0400 Subject: [PATCH 2/2] Fix deprecated doc --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index c9e4190..111ff74 100644 --- a/docs/index.md +++ b/docs/index.md @@ -38,7 +38,7 @@ class JsonXmlHttpEndpoint[F[_]](implicit F: Async[F]) extends Http4sDsl[F] { } private def personXmlDecoder: EntityDecoder[F, Person] = - org.http4s.scalaxml.xml[F].map(Person.fromXml) + org.http4s.scalaxml.xmlDecoder[F].map(Person.fromXml) implicit private def jsonXmlDecoder: EntityDecoder[F, Person] = jsonOf[F, Person].orElse(personXmlDecoder) @@ -55,4 +55,4 @@ class JsonXmlHttpEndpoint[F[_]](implicit F: Async[F]) extends Http4sDsl[F] { } } } -``` \ No newline at end of file +```