Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play WS - post multipart/form-data from scala - Bad Request

I am trying to post pdf file to external service with multipart/form-data request. I've done this with sample Java Script client so the external service works properly. Hovewer in scala with the following code I got: Bad request:

import akka.stream.scaladsl.FileIO
import akka.stream.scaladsl.Source
import play.api.libs.ws.WSClient
import play.api.mvc.MultipartFormData._

val pathToFile = "./sampleCV.pdf"
val fileName = "sampleCV.pdf"
val futureResponse = ws.url(url).withRequestTimeout(Duration.create(55, TimeUnit.SECONDS))
      .addHttpHeaders("authorization" -> s"bearer $access_token")
      .addHttpHeaders("accept" -> "*/*")
      .addHttpHeaders("content-type" -> "multipart/form-data")
      .post(Source(
        FilePart("File", fileName, Option("application/pdf"), FileIO.fromPath(Paths.get(pathToFile)))  :: List()
      ))

Play version: 2.6.19

Following curl command upload the file properly:

curl -X POST "https://rest_url" -H "accept: */*" -H "Authorization: bearer <TOKEN>" -H "Content-Type: multipart/form-data" -F "[email protected];type=application/pdf"

Did I miss some important parameter in post(...) ? What are appropriate post parameters in ScalaWS which corresponds to this CURL request?

like image 878
Piotr Ładyżyński Avatar asked Dec 15 '25 04:12

Piotr Ładyżyński


1 Answers

When multipart/form-data is used, a boundary parameter is required. The Content-Type header is going to look something like this:

Content-Type: multipart/form-data; boundary=nZaYg9TFHoDaLWhs8w

You set the Content-Type header using addHttpHeaders, but since it lacks the boundary parameter, it doesn't work. The solution is to not set that header manually, in fact you should never need to set that header. Play-WS will add an appropriate Content-Type header based on the type of object that you pass to the post method. When you pass a Source[Part[Source[ByteString, Any]]], it will set the multipart/form-data Content-Type and also add an appropriate boundary parameter.

like image 173
Matthias Berndt Avatar answered Dec 16 '25 20:12

Matthias Berndt