aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authoradamw <adam@warski.org>2017-08-29 12:59:00 +0200
committeradamw <adam@warski.org>2017-08-29 12:59:00 +0200
commit75a010d974aac96e8c96d34e38590c219cdca900 (patch)
tree4b42f6c996b4ac5c69e5a57a63c9d4fe7fa2dc79 /core
parentd30fb75be34d1bbf7a13a43ca4a4ebbb633ab74d (diff)
downloadsttp-75a010d974aac96e8c96d34e38590c219cdca900.tar.gz
sttp-75a010d974aac96e8c96d34e38590c219cdca900.tar.bz2
sttp-75a010d974aac96e8c96d34e38590c219cdca900.zip
Multipart support in Akka handler
Diffstat (limited to 'core')
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/Multipart.scala (renamed from core/src/main/scala/com/softwaremill/sttp/MultiPart.scala)12
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/RequestT.scala19
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/model/RequestBody.scala21
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/package.scala87
4 files changed, 108 insertions, 31 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/MultiPart.scala b/core/src/main/scala/com/softwaremill/sttp/Multipart.scala
index eb7badb..c54c615 100644
--- a/core/src/main/scala/com/softwaremill/sttp/MultiPart.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/Multipart.scala
@@ -3,17 +3,17 @@ package com.softwaremill.sttp
import com.softwaremill.sttp.model.BasicRequestBody
/**
- * Use the factory methods `multiPart` to conveniently create instances of
+ * Use the factory methods `multipart` to conveniently create instances of
* this class. A part can be then further customised using `fileName`,
* `contentType` and `header` methods.
*/
-case class MultiPart(name: String,
- data: BasicRequestBody,
+case class Multipart(name: String,
+ body: BasicRequestBody,
fileName: Option[String] = None,
contentType: Option[String] = None,
additionalHeaders: Map[String, String] = Map()) {
- def fileName(v: String): MultiPart = copy(fileName = Some(v))
- def contentType(v: String): MultiPart = copy(contentType = Some(v))
- def header(k: String, v: String): MultiPart =
+ def fileName(v: String): Multipart = copy(fileName = Some(v))
+ def contentType(v: String): Multipart = copy(contentType = Some(v))
+ def header(k: String, v: String): Multipart =
copy(additionalHeaders = additionalHeaders + (k -> v))
}
diff --git a/core/src/main/scala/com/softwaremill/sttp/RequestT.scala b/core/src/main/scala/com/softwaremill/sttp/RequestT.scala
index b785e7c..1461ac6 100644
--- a/core/src/main/scala/com/softwaremill/sttp/RequestT.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/RequestT.scala
@@ -1,7 +1,6 @@
package com.softwaremill.sttp
import java.io.{File, InputStream}
-import java.net.URLEncoder
import java.nio.ByteBuffer
import java.nio.file.Path
import java.util.Base64
@@ -200,6 +199,12 @@ case class RequestT[U[_], T, +S](
def body[B: BodySerializer](b: B): RequestT[U, T, S] =
withBasicBody(implicitly[BodySerializer[B]].apply(b))
+ def multipartBody(ps: Seq[Multipart]): RequestT[U, T, S] =
+ this.copy(body = MultipartBody(ps))
+
+ def multipartBody(p1: Multipart, ps: Multipart*): RequestT[U, T, S] =
+ this.copy(body = MultipartBody(p1 :: ps.toList))
+
def streamBody[S2 >: S](b: S2): RequestT[U, T, S2] =
copy[U, T, S2](body = StreamBody(b))
@@ -248,16 +253,10 @@ case class RequestT[U[_], T, +S](
private def formDataBody(fs: Seq[(String, String)],
encoding: String): RequestT[U, T, S] = {
- val b = fs
- .map {
- case (key, value) =>
- URLEncoder.encode(key, encoding) + "=" +
- URLEncoder.encode(value, encoding)
- }
- .mkString("&")
+ val b = RequestBody.paramsToStringBody(fs, encoding)
setContentTypeIfMissing(ApplicationFormContentType)
- .setContentLengthIfMissing(b.getBytes(encoding).length)
- .copy(body = StringBody(b, encoding))
+ .setContentLengthIfMissing(b.s.getBytes(encoding).length)
+ .copy(body = b)
}
}
diff --git a/core/src/main/scala/com/softwaremill/sttp/model/RequestBody.scala b/core/src/main/scala/com/softwaremill/sttp/model/RequestBody.scala
index 7499048..5d43298 100644
--- a/core/src/main/scala/com/softwaremill/sttp/model/RequestBody.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/model/RequestBody.scala
@@ -1,11 +1,14 @@
package com.softwaremill.sttp.model
import java.io.InputStream
+import java.net.URLEncoder
import java.nio.ByteBuffer
import java.nio.file.Path
import com.softwaremill.sttp._
+import scala.collection.immutable.Seq
+
sealed trait RequestBody[+S]
case object NoBody extends RequestBody[Nothing]
@@ -40,3 +43,21 @@ case class PathBody(
) extends BasicRequestBody
case class StreamBody[S](s: S) extends RequestBody[S]
+
+case class MultipartBody(parts: Seq[Multipart]) extends RequestBody[Nothing]
+
+object RequestBody {
+ private[sttp] def paramsToStringBody(fs: Seq[(String, String)],
+ encoding: String): StringBody = {
+
+ val b = fs
+ .map {
+ case (key, value) =>
+ URLEncoder.encode(key, encoding) + "=" +
+ URLEncoder.encode(value, encoding)
+ }
+ .mkString("&")
+
+ StringBody(b, encoding)
+ }
+}
diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala
index 884d2f9..bbd777e 100644
--- a/core/src/main/scala/com/softwaremill/sttp/package.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/package.scala
@@ -96,14 +96,14 @@ package object sttp {
overwrite: Boolean = false): ResponseAs[Path, Nothing] =
ResponseAsFile(path.toFile, overwrite).map(_.toPath)
- // multi part factory methods
+ // multipart factory methods
/**
* Content type will be set to `text/plain` with `utf-8` encoding, can be
* overridden later using the `contentType` method.
*/
- def multiPart(name: String, data: String): MultiPart =
- MultiPart(name,
+ def multipart(name: String, data: String): Multipart =
+ Multipart(name,
StringBody(data, Utf8),
contentType =
Some(contentTypeWithEncoding(TextPlainContentType, Utf8)))
@@ -112,8 +112,8 @@ package object sttp {
* Content type will be set to `text/plain` with `utf-8` encoding, can be
* overridden later using the `contentType` method.
*/
- def multiPart(name: String, data: String, encoding: String): MultiPart =
- MultiPart(name,
+ def multipart(name: String, data: String, encoding: String): Multipart =
+ Multipart(name,
StringBody(data, encoding),
contentType =
Some(contentTypeWithEncoding(TextPlainContentType, Utf8)))
@@ -122,8 +122,8 @@ package object sttp {
* Content type will be set to `application/octet-stream`, can be overridden
* later using the `contentType` method.
*/
- def multiPart(name: String, data: Array[Byte]): MultiPart =
- MultiPart(name,
+ def multipart(name: String, data: Array[Byte]): Multipart =
+ Multipart(name,
ByteArrayBody(data),
contentType = Some(ApplicationOctetStreamContentType))
@@ -131,8 +131,8 @@ package object sttp {
* Content type will be set to `application/octet-stream`, can be overridden
* later using the `contentType` method.
*/
- def multiPart(name: String, data: ByteBuffer): MultiPart =
- MultiPart(name,
+ def multipart(name: String, data: ByteBuffer): Multipart =
+ Multipart(name,
ByteBufferBody(data),
contentType = Some(ApplicationOctetStreamContentType))
@@ -140,8 +140,8 @@ package object sttp {
* Content type will be set to `application/octet-stream`, can be overridden
* later using the `contentType` method.
*/
- def multiPart(name: String, data: InputStream): MultiPart =
- MultiPart(name,
+ def multipart(name: String, data: InputStream): Multipart =
+ Multipart(name,
InputStreamBody(data),
contentType = Some(ApplicationOctetStreamContentType))
@@ -149,19 +149,76 @@ package object sttp {
* Content type will be set to `application/octet-stream`, can be overridden
* later using the `contentType` method.
*/
- def multiPart(name: String, data: File): MultiPart =
- multiPart(name, data.toPath)
+ def multipart(name: String, data: File): Multipart =
+ multipart(name, data.toPath)
/**
* Content type will be set to `application/octet-stream`, can be overridden
* later using the `contentType` method.
*/
- def multiPart(name: String, data: Path): MultiPart =
- MultiPart(name,
+ def multipart(name: String, data: Path): Multipart =
+ Multipart(name,
PathBody(data),
fileName = Some(data.getFileName.toString),
contentType = Some(ApplicationOctetStreamContentType))
+ /**
+ * Encodes the given parameters as form data using `utf-8`.
+ *
+ * Content type will be set to `application/x-www-form-urlencoded`, can be
+ * overridden later using the `contentType` method.
+ */
+ def multipart(name: String, fs: Map[String, String]): Multipart =
+ Multipart(name,
+ RequestBody.paramsToStringBody(fs.toList, Utf8),
+ contentType = Some(ApplicationFormContentType))
+
+ /**
+ * Encodes the given parameters as form data.
+ *
+ * Content type will be set to `application/x-www-form-urlencoded`, can be
+ * overridden later using the `contentType` method.
+ */
+ def multipart(name: String,
+ fs: Map[String, String],
+ encoding: String): Multipart =
+ Multipart(name,
+ RequestBody.paramsToStringBody(fs.toList, encoding),
+ contentType = Some(ApplicationFormContentType))
+
+ /**
+ * Encodes the given parameters as form data using `utf-8`.
+ *
+ * Content type will be set to `application/x-www-form-urlencoded`, can be
+ * overridden later using the `contentType` method.
+ */
+ def multipart(name: String, fs: Seq[(String, String)]): Multipart =
+ Multipart(name,
+ RequestBody.paramsToStringBody(fs, Utf8),
+ contentType = Some(ApplicationFormContentType))
+
+ /**
+ * Encodes the given parameters as form data.
+ *
+ * Content type will be set to `application/x-www-form-urlencoded`, can be
+ * overridden later using the `contentType` method.
+ */
+ def multipart(name: String,
+ fs: Seq[(String, String)],
+ encoding: String): Multipart =
+ Multipart(name,
+ RequestBody.paramsToStringBody(fs, encoding),
+ contentType = Some(ApplicationFormContentType))
+
+ /**
+ * Content type will be set to `application/octet-stream`, can be
+ * overridden later using the `contentType` method.
+ */
+ def multipart[B: BodySerializer](name: String, b: B): Multipart =
+ Multipart(name,
+ implicitly[BodySerializer[B]].apply(b),
+ contentType = Some(ApplicationOctetStreamContentType))
+
// util
private[sttp] def contentTypeWithEncoding(ct: String, enc: String) =