aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authoradamw <adam@warski.org>2017-07-24 17:23:32 +0200
committeradamw <adam@warski.org>2017-07-24 17:23:32 +0200
commita568123e2a7959b860faaedb66b358fabd92e317 (patch)
tree308bb70644ed738eef1bfe19f34fa400fb28d90e /core/src
parentfc62bf67b23793b3766f527de5ffac73e78d2d18 (diff)
downloadsttp-a568123e2a7959b860faaedb66b358fabd92e317.tar.gz
sttp-a568123e2a7959b860faaedb66b358fabd92e317.tar.bz2
sttp-a568123e2a7959b860faaedb66b358fabd92e317.zip
Automatically setting content-length, where possible
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/package.scala56
-rw-r--r--core/src/test/scala/com/softwaremill/sttp/RequestTests.scala25
2 files changed, 73 insertions, 8 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala
index f9ee9c6..f55ed9e 100644
--- a/core/src/main/scala/com/softwaremill/sttp/package.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/package.scala
@@ -156,6 +156,8 @@ package object sttp {
header(ContentTypeHeader,
contentTypeWithEncoding(ct, encoding),
replaceExisting = true)
+ def contentLength(l: Long): RequestT[U, T, S] =
+ header(ContentLengthHeader, l.toString, replaceExisting = true)
def header(k: String,
v: String,
replaceExisting: Boolean = false): RequestT[U, T, S] = {
@@ -186,27 +188,39 @@ package object sttp {
/**
* Uses the `utf-8` encoding.
+ *
* If content type is not yet specified, will be set to `text/plain`
* with `utf-8` encoding.
+ *
+ * If content length is not yet specified, will be set to the number of
+ * bytes in the string using the `utf-8` encoding.
*/
def body(b: String): RequestT[U, T, S] = body(b, Utf8)
/**
* If content type is not yet specified, will be set to `text/plain`
* with the given encoding.
+ *
+ * If content length is not yet specified, will be set to the number of
+ * bytes in the string using the given encoding.
*/
def body(b: String, encoding: String): RequestT[U, T, S] =
setContentTypeIfMissing(
contentTypeWithEncoding(TextPlainContentType, encoding))
+ .setContentLengthIfMissing(b.getBytes(encoding).length)
.copy(body = StringBody(b, encoding))
/**
* If content type is not yet specified, will be set to
* `application/octet-stream`.
+ *
+ * If content length is not yet specified, will be set to the length
+ * of the given array.
*/
def body(b: Array[Byte]): RequestT[U, T, S] =
- setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
- body = ByteArrayBody(b))
+ setContentTypeIfMissing(ApplicationOctetStreamContentType)
+ .setContentLengthIfMissing(b.length)
+ .copy(body = ByteArrayBody(b))
/**
* If content type is not yet specified, will be set to
@@ -227,21 +241,32 @@ package object sttp {
/**
* If content type is not yet specified, will be set to
* `application/octet-stream`.
+ *
+ * If content length is not yet specified, will be set to the length
+ * of the given file.
*/
- def body(b: File): RequestT[U, T, S] = body(b.toPath)
+ def body(b: File): RequestT[U, T, S] =
+ body(b.toPath)
/**
* If content type is not yet specified, will be set to
* `application/octet-stream`.
+ *
+ * If content length is not yet specified, will be set to the length
+ * of the given file.
*/
def body(b: Path): RequestT[U, T, S] =
- setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
- body = PathBody(b))
+ setContentTypeIfMissing(ApplicationOctetStreamContentType)
+ .setContentLengthIfMissing(b.toFile.length())
+ .copy(body = PathBody(b))
/**
* Encodes the given parameters as form data using `utf-8`.
* If content type is not yet specified, will be set to
* `application/x-www-form-urlencoded`.
+ *
+ * If content length is not yet specified, will be set to the length
+ * of the number of bytes in the url-encoded parameter string.
*/
def body(fs: Map[String, String]): RequestT[U, T, S] =
formDataBody(fs.toList, Utf8)
@@ -250,6 +275,9 @@ package object sttp {
* Encodes the given parameters as form data.
* If content type is not yet specified, will be set to
* `application/x-www-form-urlencoded`.
+ *
+ * If content length is not yet specified, will be set to the length
+ * of the number of bytes in the url-encoded parameter string.
*/
def body(fs: Map[String, String], encoding: String): RequestT[U, T, S] =
formDataBody(fs.toList, encoding)
@@ -258,6 +286,9 @@ package object sttp {
* Encodes the given parameters as form data using `utf-8`.
* If content type is not yet specified, will be set to
* `application/x-www-form-urlencoded`.
+ *
+ * If content length is not yet specified, will be set to the length
+ * of the number of bytes in the url-encoded parameter string.
*/
def body(fs: (String, String)*): RequestT[U, T, S] =
formDataBody(fs.toList, Utf8)
@@ -266,6 +297,9 @@ package object sttp {
* Encodes the given parameters as form data.
* If content type is not yet specified, will be set to
* `application/x-www-form-urlencoded`.
+ *
+ * If content length is not yet specified, will be set to the length
+ * of the number of bytes in the url-encoded parameter string.
*/
def body(fs: Seq[(String, String)], encoding: String): RequestT[U, T, S] =
formDataBody(fs, encoding)
@@ -306,10 +340,15 @@ package object sttp {
}
private def hasContentType: Boolean =
- headers.exists(_._1.toLowerCase.contains(ContentTypeHeader))
+ headers.exists(_._1.equalsIgnoreCase(ContentTypeHeader))
private def setContentTypeIfMissing(ct: String): RequestT[U, T, S] =
if (hasContentType) this else contentType(ct)
+ private def hasContentLength: Boolean =
+ headers.exists(_._1.equalsIgnoreCase(ContentLengthHeader))
+ private def setContentLengthIfMissing(l: => Long): RequestT[U, T, S] =
+ if (hasContentLength) this else contentLength(l)
+
private def formDataBody(fs: Seq[(String, String)],
encoding: String): RequestT[U, T, S] = {
val b = fs
@@ -318,8 +357,9 @@ package object sttp {
URLEncoder.encode(p._1, encoding) + "=" + URLEncoder
.encode(p._2, encoding))
.mkString("&")
- setContentTypeIfMissing(ApplicationFormContentType).copy(
- body = StringBody(b, encoding))
+ setContentTypeIfMissing(ApplicationFormContentType)
+ .setContentLengthIfMissing(b.getBytes(encoding).length)
+ .copy(body = StringBody(b, encoding))
}
}
diff --git a/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala b/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala
index e6db3d7..c6132c9 100644
--- a/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala
+++ b/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala
@@ -40,4 +40,29 @@ class RequestTests extends FlatSpec with Matchers {
.find(_._1 == CookieHeader)
.map(_._2) should be(Some("k1=v1; k2=v2"))
}
+
+ "content length" should "be automatically set for a string body" in {
+ sttp
+ .body("test")
+ .headers
+ .find(_._1.equalsIgnoreCase(ContentLengthHeader))
+ .map(_._2) should be(Some("4"))
+ }
+
+ it should "be automatically set to the number of utf-8 bytes in a string" in {
+ sttp
+ .body("ąęć")
+ .headers
+ .find(_._1.equalsIgnoreCase(ContentLengthHeader))
+ .map(_._2) should be(Some("6"))
+ }
+
+ it should "not override an already specified content length" in {
+ sttp
+ .contentLength(10)
+ .body("a")
+ .headers
+ .find(_._1.equalsIgnoreCase(ContentLengthHeader))
+ .map(_._2) should be(Some("10"))
+ }
}