Permalink
Browse files

! httpx: change default charset for application/x-www-form-urlencoded…

… to utf8, fixes #526

FormData related unmarshallers were collected into `FormDataUnmarshallers`.
  • Loading branch information...
jrudolph committed Sep 23, 2013
1 parent 8f941d5 commit dd51be5d46c2799e8f15f627db16ac4e8fda38cd
@@ -41,12 +41,12 @@ The relevant sources are:
- Deserializer_
- BasicUnmarshallers_
- MetaUnmarshallers_
-- MultipartUnmarshallers_
+- FormDataUnmarshallers_
.. _Deserializer: https://github.com/spray/spray/blob/master/spray-httpx/src/main/scala/spray/httpx/unmarshalling/Deserializer.scala
.. _BasicUnmarshallers: https://github.com/spray/spray/blob/master/spray-httpx/src/main/scala/spray/httpx/unmarshalling/BasicUnmarshallers.scala
.. _MetaUnmarshallers: https://github.com/spray/spray/blob/master/spray-httpx/src/main/scala/spray/httpx/unmarshalling/MetaUnmarshallers.scala
-.. _MultipartUnmarshallers: https://github.com/spray/spray/blob/master/spray-httpx/src/main/scala/spray/httpx/unmarshalling/MultipartUnmarshallers.scala
+.. _FormDataUnmarshallers: https://github.com/spray/spray/blob/master/spray-httpx/src/main/scala/spray/httpx/unmarshalling/FormDataUnmarshallers.scala
Implicit Resolution
@@ -53,20 +53,6 @@ trait BasicUnmarshallers {
case HttpEntity.Empty NodeSeq.Empty
}
//#
-
- implicit val FormDataUnmarshaller =
- Unmarshaller[FormData](`application/x-www-form-urlencoded`) {
- case HttpEntity.Empty FormData.Empty
- case entity: HttpEntity.NonEmpty
- val data = entity.asString
- try {
- val query = Uri.Query(data, entity.contentType.charset.nioCharset)
- FormData(query.toMap)
- } catch {
- case ex: IllegalUriException
- throw new IllegalArgumentException(ex.info.formatPretty.replace("Query,", "form content,"))
- }
- }
}
object BasicUnmarshallers extends BasicUnmarshallers
@@ -33,7 +33,7 @@ object Deserializer extends DeserializerLowerPriorityImplicits
with BasicUnmarshallers
with MetaUnmarshallers
with FromStringDeserializers
- with MultipartUnmarshallers {
+ with FormDataUnmarshallers {
implicit def fromFunction2Converter[A, B](implicit f: A B) =
new Deserializer[A, B] {
@@ -65,4 +65,4 @@ private[unmarshalling] abstract class DeserializerLowerPriorityImplicits {
}
}
}
-}
+}
@@ -29,7 +29,7 @@ import MediaRanges._
import HttpHeaders._
import HttpCharsets._
-trait MultipartUnmarshallers {
+trait FormDataUnmarshallers {
private[this] val mimeParsingConfig = {
val config = new MIMEConfig
@@ -86,6 +86,21 @@ trait MultipartUnmarshallers {
case _ ⇒ None
} getOrElse sys.error("unnamed body part (no Content-Disposition header or no 'name' parameter)")
}
+
+ implicit val UrlEncodedFormDataUnmarshaller: Unmarshaller[FormData] = urlEncodedFormDataUnmarshaller(`UTF-8`)
+ def urlEncodedFormDataUnmarshaller(defaultCharset: HttpCharset): Unmarshaller[FormData] =
+ Unmarshaller[FormData](`application/x-www-form-urlencoded`) {
+ case HttpEntity.Empty ⇒ FormData.Empty
+ case entity: HttpEntity.NonEmpty ⇒
+ val data = entity.asString(defaultCharset)
+ try {
+ val query = Uri.Query(data, entity.contentType.definedCharset.getOrElse(defaultCharset).nioCharset)
+ FormData(query.toMap)
+ } catch {
+ case ex: IllegalUriException ⇒
+ throw new IllegalArgumentException(ex.info.formatPretty.replace("Query,", "form content,"))
+ }
+ }
}
-object MultipartUnmarshallers extends MultipartUnmarshallers
+object FormDataUnmarshallers extends FormDataUnmarshallers
@@ -42,24 +42,6 @@ class BasicUnmarshallersSpec extends Specification {
}
}
- "The FormDataUnmarshaller" should {
- "correctly unmarshal HTML form content with one element" in (
- HttpEntity(ContentType(`application/x-www-form-urlencoded`, `UTF-8`), "secret=h%C3%A4ll%C3%B6").as[FormData] ===
- Right(FormData(Map("secret" -> "hällö"))))
- "correctly unmarshal HTML form content with three fields" in {
- HttpEntity(`application/x-www-form-urlencoded`, "email=test%40there.com&password=&username=dirk").as[FormData] ===
- Right(FormData(Map("email" -> "test@there.com", "password" -> "", "username" -> "dirk")))
- }
- "be lenient on empty key/value pairs" in {
- HttpEntity(`application/x-www-form-urlencoded`, "&key=value&&key2=&").as[FormData] ===
- Right(FormData(Map("" -> "", "key" -> "value", "key2" -> "")))
- }
- "reject illegal form content" in {
- val Left(MalformedContent(msg, _)) = HttpEntity(`application/x-www-form-urlencoded`, "key=really=not_good").as[FormData]
- msg === "Illegal form content, unexpected character '=' at position 10: \nkey=really=not_good\n ^\n"
- }
- }
-
"Unmarshaller.forNonEmpty" should {
"prevent the underlying unmarshaller from unmarshalling empty entities" in {
implicit val um = Unmarshaller.forNonEmpty[String]
@@ -24,7 +24,7 @@ import HttpCharsets._
import HttpHeaders._
import ProtectedHeaderCreation.enable
-class MultipartUnmarshallersSpec extends Specification {
+class FormDataUnmarshallersSpec extends Specification {
"The MultipartContentUnmarshaller" should {
"correctly unmarshal 'multipart/mixed' content with one empty part" in {
@@ -122,4 +122,24 @@ class MultipartUnmarshallersSpec extends Specification {
}
}
-}
+ "The UrlEncodedFormDataUnmarshaller" should {
+ "correctly unmarshal HTML form content with one element" in (
+ HttpEntity(ContentType(`application/x-www-form-urlencoded`, `UTF-8`), "secret=h%C3%A4ll%C3%B6").as[FormData] ===
+ Right(FormData(Map("secret" -> "hällö"))))
+ "correctly unmarshal HTML form content with one element with default encoding utf-8" in (
+ HttpEntity(ContentType(`application/x-www-form-urlencoded`), "secret=h%C3%A4ll%C3%B6").as[FormData] ===
+ Right(FormData(Map("secret" -> "hällö"))))
+ "correctly unmarshal HTML form content with three fields" in {
+ HttpEntity(`application/x-www-form-urlencoded`, "email=test%40there.com&password=&username=dirk").as[FormData] ===
+ Right(FormData(Map("email" -> "test@there.com", "password" -> "", "username" -> "dirk")))
+ }
+ "be lenient on empty key/value pairs" in {
+ HttpEntity(`application/x-www-form-urlencoded`, "&key=value&&key2=&").as[FormData] ===
+ Right(FormData(Map("" -> "", "key" -> "value", "key2" -> "")))
+ }
+ "reject illegal form content" in {
+ val Left(MalformedContent(msg, _)) = HttpEntity(`application/x-www-form-urlencoded`, "key=really=not_good").as[FormData]
+ msg === "Illegal form content, unexpected character '=' at position 10: \nkey=really=not_good\n ^\n"
+ }
+ }
+}

0 comments on commit dd51be5

Please sign in to comment.