diff options
author | adamw <adam@warski.org> | 2017-08-29 14:39:41 +0200 |
---|---|---|
committer | adamw <adam@warski.org> | 2017-08-29 14:39:41 +0200 |
commit | acbf6567533011afe0479dffefa3a918fc570f32 (patch) | |
tree | 1e9d079d08514e1e4f4154198f9bf1e732cc075d /async-http-client-handler/src/main/scala/com | |
parent | 0ff548cbbe6f0c7eb054597ff693f9bfbec3a65b (diff) | |
download | sttp-acbf6567533011afe0479dffefa3a918fc570f32.tar.gz sttp-acbf6567533011afe0479dffefa3a918fc570f32.tar.bz2 sttp-acbf6567533011afe0479dffefa3a918fc570f32.zip |
Multipart support in async http client
Diffstat (limited to 'async-http-client-handler/src/main/scala/com')
-rw-r--r-- | async-http-client-handler/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientHandler.scala | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/async-http-client-handler/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientHandler.scala b/async-http-client-handler/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientHandler.scala index c8f0144..b29eb97 100644 --- a/async-http-client-handler/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientHandler.scala +++ b/async-http-client-handler/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientHandler.scala @@ -1,5 +1,6 @@ package com.softwaremill.sttp.asynchttpclient +import java.io.ByteArrayOutputStream import java.nio.ByteBuffer import java.nio.charset.Charset @@ -7,6 +8,11 @@ import com.softwaremill.sttp.ResponseAs.EagerResponseHandler import com.softwaremill.sttp._ import org.asynchttpclient.AsyncHandler.State import org.asynchttpclient.handler.StreamedAsyncHandler +import org.asynchttpclient.request.body.multipart.{ + ByteArrayPart, + FilePart, + StringPart +} import org.asynchttpclient.{ AsyncCompletionHandler, AsyncHandler, @@ -14,6 +20,7 @@ import org.asynchttpclient.{ HttpResponseBodyPart, HttpResponseHeaders, HttpResponseStatus, + Param, RequestBuilder, Request => AsyncRequest, Response => AsyncResponse @@ -172,7 +179,45 @@ abstract class AsyncHttpClientHandler[R[_], S](asyncHttpClient: AsyncHttpClient, .map(_._2.toLong) .getOrElse(-1L) rb.setBody(streamBodyToPublisher(s), cl) + + case MultipartBody(ps) => + ps.foreach(addMultipartBody(rb, _)) + } + } + + private def addMultipartBody(rb: RequestBuilder, mp: Multipart): Unit = { + // async http client only supports setting file names on file parts. To + // set a file name on an arbitrary part we have to use a small "work + // around", combining the file name with the name (surrounding quotes + // are added by ahc). + def nameWithFilename = mp.fileName.fold(mp.name) { fn => + s"""${mp.name}"; filename="$fn""" + } + + val bodyPart = mp.body match { + case StringBody(b, encoding, _) => + new StringPart(nameWithFilename, + b, + mp.contentType.getOrElse(TextPlainContentType), + Charset.forName(encoding)) + case ByteArrayBody(b, _) => + new ByteArrayPart(nameWithFilename, b) + case ByteBufferBody(b, _) => + new ByteArrayPart(nameWithFilename, b.array()) + case InputStreamBody(b, _) => + // sadly async http client only supports parts that are strings, + // byte arrays or files + val baos = new ByteArrayOutputStream() + transfer(b, baos) + new ByteArrayPart(nameWithFilename, baos.toByteArray) + case PathBody(b, _) => + new FilePart(mp.name, b.toFile, null, null, mp.fileName.orNull) } + + bodyPart.setCustomHeaders( + mp.additionalHeaders.map(h => new Param(h._1, h._2)).toList.asJava) + + rb.addBodyPart(bodyPart) } private def readEagerResponse[T]( |