diff --git a/zio-http/jvm/src/test/scala/zio/http/FormSpec.scala b/zio-http/jvm/src/test/scala/zio/http/FormSpec.scala index 65897ad0d5..237594bef1 100644 --- a/zio-http/jvm/src/test/scala/zio/http/FormSpec.scala +++ b/zio-http/jvm/src/test/scala/zio/http/FormSpec.scala @@ -386,6 +386,23 @@ object FormSpec extends ZIOHttpSpec { .runCollect .map { c => assertTrue(c == expected) } }, + test("crlf not stripped") { + val content = "1,2\r\n3,4\r\n" + val form = Form( + Chunk( + FormField.textField("csv", content, MediaType.text.`csv`), + ), + ) + val boundary = Boundary("X-INSOMNIA-BOUNDARY") + val formByteStream = form.multipartBytes(boundary) + val streamingForm = StreamingForm(formByteStream, boundary) + streamingForm.fields.mapZIO { field => + field.asChunk + }.runCollect.map { chunks => + val s = chunks.headOption.map(_.asString) + assertTrue(s.contains(content)) + } + }, ) @@ sequential def spec = diff --git a/zio-http/shared/src/main/scala/zio/http/FormField.scala b/zio-http/shared/src/main/scala/zio/http/FormField.scala index 6e45efc7df..753fd25226 100644 --- a/zio-http/shared/src/main/scala/zio/http/FormField.scala +++ b/zio-http/shared/src/main/scala/zio/http/FormField.scala @@ -149,7 +149,7 @@ object FormField { defaultCharset: Charset = StandardCharsets.UTF_8, ): Either[FormDecodingError, FormField] = { val extract = - ast.foldLeft( + ast.init.foldLeft( ( Option.empty[FormAST.Header], Option.empty[FormAST.Header], @@ -159,6 +159,8 @@ object FormField { ) { case (accum, header: FormAST.Header) if header.name.equalsIgnoreCase("Content-Disposition") => (Some(header), accum._2, accum._3, accum._4) + case (accum, FormAST.EoL) => + (accum._1, accum._2, accum._3, accum._4 :+ FormAST.Content(Chunk[Byte](13, 10))) case (accum, content: FormAST.Content) => (accum._1, accum._2, accum._3, accum._4 :+ content) case (accum, header: FormAST.Header) if header.name.equalsIgnoreCase("Content-Type") =>