aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoradamw <adam@warski.org>2017-07-09 09:32:31 +0200
committeradamw <adam@warski.org>2017-07-09 09:32:31 +0200
commit820095216e671888cfa607b329d749ba099a7bc1 (patch)
tree9276e9ec7be44ccc78dfdf9f2a93475deb36d6ff
parent08dd8ea1b55e62925aeee72de5d63a1e1961b060 (diff)
downloadsttp-820095216e671888cfa607b329d749ba099a7bc1.tar.gz
sttp-820095216e671888cfa607b329d749ba099a7bc1.tar.bz2
sttp-820095216e671888cfa607b329d749ba099a7bc1.zip
Source formatting
-rw-r--r--.scalafmt.conf0
-rw-r--r--akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpSttpHandler.scala74
-rw-r--r--akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/package.scala6
-rw-r--r--build.sbt32
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala70
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala21
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/model/package.scala9
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/package.scala142
-rw-r--r--project/plugins.sbt2
-rw-r--r--tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala64
-rw-r--r--tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala2
11 files changed, 273 insertions, 149 deletions
diff --git a/.scalafmt.conf b/.scalafmt.conf
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.scalafmt.conf
diff --git a/akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpSttpHandler.scala b/akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpSttpHandler.scala
index df40fc9..fc2d632 100644
--- a/akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpSttpHandler.scala
+++ b/akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpSttpHandler.scala
@@ -15,7 +15,8 @@ import com.softwaremill.sttp.model._
import scala.concurrent.Future
import scala.util.{Failure, Success, Try}
-class AkkaHttpSttpHandler(actorSystem: ActorSystem) extends SttpHandler[Future, Source[ByteString, Any]] {
+class AkkaHttpSttpHandler(actorSystem: ActorSystem)
+ extends SttpHandler[Future, Source[ByteString, Any]] {
def this() = this(ActorSystem("sttp"))
@@ -23,11 +24,16 @@ class AkkaHttpSttpHandler(actorSystem: ActorSystem) extends SttpHandler[Future,
private implicit val materializer = ActorMaterializer()
import as.dispatcher
- override def send[T](r: Request, responseAs: ResponseAs[T, Source[ByteString, Any]]): Future[Response[T]] = {
- requestToAkka(r).map(setBodyOnAkka(r, r.body, _).get).flatMap(Http().singleRequest(_)).flatMap { hr =>
- val code = hr.status.intValue()
- bodyFromAkka(responseAs, hr).map(Response(code, _))
- }
+ override def send[T](r: Request,
+ responseAs: ResponseAs[T, Source[ByteString, Any]])
+ : Future[Response[T]] = {
+ requestToAkka(r)
+ .map(setBodyOnAkka(r, r.body, _).get)
+ .flatMap(Http().singleRequest(_))
+ .flatMap { hr =>
+ val code = hr.status.intValue()
+ bodyFromAkka(responseAs, hr).map(Response(code, _))
+ }
}
private def methodToAkka(m: Method): HttpMethod = m match {
@@ -43,10 +49,12 @@ class AkkaHttpSttpHandler(actorSystem: ActorSystem) extends SttpHandler[Future,
case _ => HttpMethod.custom(m.m)
}
- private def bodyFromAkka[T](rr: ResponseAs[T, Source[ByteString, Any]], hr: HttpResponse): Future[T] = {
- def asByteArray = hr.entity.dataBytes
- .runFold(ByteString(""))(_ ++ _)
- .map(_.toArray[Byte])
+ private def bodyFromAkka[T](rr: ResponseAs[T, Source[ByteString, Any]],
+ hr: HttpResponse): Future[T] = {
+ def asByteArray =
+ hr.entity.dataBytes
+ .runFold(ByteString(""))(_ ++ _)
+ .map(_.toArray[Byte])
rr match {
case IgnoreResponse =>
@@ -59,14 +67,15 @@ class AkkaHttpSttpHandler(actorSystem: ActorSystem) extends SttpHandler[Future,
case ResponseAsByteArray =>
asByteArray
- case r@ResponseAsStream() =>
+ case r @ ResponseAsStream() =>
Future.successful(r.responseIsStream(hr.entity.dataBytes))
}
}
private def requestToAkka(r: Request): Future[HttpRequest] = {
val ar = HttpRequest(uri = r.uri.toString, method = methodToAkka(r.method))
- val parsed = r.headers.filterNot(isContentType).map(h => HttpHeader.parse(h._1, h._2))
+ val parsed =
+ r.headers.filterNot(isContentType).map(h => HttpHeader.parse(h._1, h._2))
val errors = parsed.collect {
case ParsingResult.Error(e) => e
}
@@ -81,26 +90,34 @@ class AkkaHttpSttpHandler(actorSystem: ActorSystem) extends SttpHandler[Future,
}
}
- private def setBodyOnAkka(r: Request, body: RequestBody, ar: HttpRequest): Try[HttpRequest] = {
+ private def setBodyOnAkka(r: Request,
+ body: RequestBody,
+ ar: HttpRequest): Try[HttpRequest] = {
getContentTypeOrOctetStream(r).map { ct =>
-
def doSet(body: RequestBody): HttpRequest = body match {
case NoBody => ar
case StringBody(b, encoding) =>
- val ctWithEncoding = HttpCharsets.getForKey(encoding).map(hc => ContentType.apply(ct.mediaType, () => hc)).getOrElse(ct)
+ val ctWithEncoding = HttpCharsets
+ .getForKey(encoding)
+ .map(hc => ContentType.apply(ct.mediaType, () => hc))
+ .getOrElse(ct)
ar.withEntity(ctWithEncoding, b.getBytes(encoding))
case ByteArrayBody(b) => ar.withEntity(b)
case ByteBufferBody(b) => ar.withEntity(ByteString(b))
- case InputStreamBody(b) => ar.withEntity(HttpEntity(ct, StreamConverters.fromInputStream(() => b)))
+ case InputStreamBody(b) =>
+ ar.withEntity(
+ HttpEntity(ct, StreamConverters.fromInputStream(() => b)))
case FileBody(b) => ar.withEntity(ct, b.toPath)
case PathBody(b) => ar.withEntity(ct, b)
- case s@SerializableBody(_, _) => doSetSerializable(s)
+ case s @ SerializableBody(_, _) => doSetSerializable(s)
}
- def doSetSerializable[T](body: SerializableBody[T]): HttpRequest = body match {
- case SerializableBody(SourceBodySerializer, t) => ar.withEntity(HttpEntity(ct, t))
- case SerializableBody(f, t) => doSet(f(t))
- }
+ def doSetSerializable[T](body: SerializableBody[T]): HttpRequest =
+ body match {
+ case SerializableBody(SourceBodySerializer, t) =>
+ ar.withEntity(HttpEntity(ct, t))
+ case SerializableBody(f, t) => doSet(f(t))
+ }
doSet(body)
}
@@ -111,16 +128,21 @@ class AkkaHttpSttpHandler(actorSystem: ActorSystem) extends SttpHandler[Future,
.find(isContentType)
.map(_._2)
.map { ct =>
- ContentType.parse(ct).fold(
- errors => Failure(new RuntimeException(s"Cannot parse content type: $errors")),
- Success(_))
+ ContentType
+ .parse(ct)
+ .fold(
+ errors =>
+ Failure(
+ new RuntimeException(s"Cannot parse content type: $errors")),
+ Success(_))
}
.getOrElse(Success(`application/octet-stream`))
}
- private def isContentType(header: (String, String)) = header._1.toLowerCase.contains(`Content-Type`.lowercaseName)
+ private def isContentType(header: (String, String)) =
+ header._1.toLowerCase.contains(`Content-Type`.lowercaseName)
def close(): Future[Terminated] = {
actorSystem.terminate()
}
-} \ No newline at end of file
+}
diff --git a/akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/package.scala b/akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/package.scala
index 669af5e..0357dd8 100644
--- a/akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/package.scala
+++ b/akka-http-handler/src/main/scala/com/softwaremill/sttp/akkahttp/package.scala
@@ -5,10 +5,12 @@ import akka.util.ByteString
import com.softwaremill.sttp.model.{BasicRequestBody, BodySerializer}
package object akkahttp {
- private[akkahttp] case object SourceBodySerializer extends BodySerializer[Source[ByteString, Any]] {
+ private[akkahttp] case object SourceBodySerializer
+ extends BodySerializer[Source[ByteString, Any]] {
def apply(t: Source[ByteString, Any]): BasicRequestBody =
throw new RuntimeException("Can only be used with akka-http handler")
}
- implicit val sourceBodySerializer: BodySerializer[Source[ByteString, Any]] = SourceBodySerializer
+ implicit val sourceBodySerializer: BodySerializer[Source[ByteString, Any]] =
+ SourceBodySerializer
}
diff --git a/build.sbt b/build.sbt
index 09f50d0..3aea1fe 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,26 +1,26 @@
import scalariform.formatter.preferences._
-lazy val commonSettings = scalariformSettings ++ Seq(
+lazy val commonSettings = Seq(
organization := "com.softwaremill.sttp",
version := "0.1",
scalaVersion := "2.12.2",
crossScalaVersions := Seq(scalaVersion.value, "2.11.8"),
scalacOptions ++= Seq("-unchecked", "-deprecation"),
- ScalariformKeys.preferences := ScalariformKeys.preferences.value
- .setPreference(DoubleIndentClassDeclaration, true)
- .setPreference(PreserveSpaceBeforeArguments, true)
- .setPreference(CompactControlReadability, true)
- .setPreference(SpacesAroundMultiImports, false),
+ scalafmtOnCompile := true,
// Sonatype OSS deployment
publishTo := {
val nexus = "https://oss.sonatype.org/"
- val (name, url) = if (isSnapshot.value) ("snapshots", nexus + "content/repositories/snapshots")
- else ("releases", nexus + "service/local/staging/deploy/maven2")
+ val (name, url) =
+ if (isSnapshot.value)
+ ("snapshots", nexus + "content/repositories/snapshots")
+ else ("releases", nexus + "service/local/staging/deploy/maven2")
Some(name at url)
},
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials"),
publishMavenStyle := true,
- pomIncludeRepository := { _ => false },
+ pomIncludeRepository := { _ =>
+ false
+ },
pomExtra := (
<scm>
<url>git@github.com/softwaremill/sttp.git</url>
@@ -33,8 +33,10 @@ lazy val commonSettings = scalariformSettings ++ Seq(
<url>http://www.warski.org</url>
</developer>
</developers>
- ),
- licenses := ("Apache2", new java.net.URL("http://www.apache.org/licenses/LICENSE-2.0.txt")) :: Nil,
+ ),
+ licenses := ("Apache2",
+ new java.net.URL(
+ "http://www.apache.org/licenses/LICENSE-2.0.txt")) :: Nil,
homepage := Some(new java.net.URL("http://softwaremill.com/open-source"))
)
@@ -45,9 +47,7 @@ val scalaTest = "org.scalatest" %% "scalatest" % "3.0.3" % "test"
lazy val rootProject = (project in file("."))
.settings(commonSettings: _*)
- .settings(
- publishArtifact := false,
- name := "sttp")
+ .settings(publishArtifact := false, name := "sttp")
.aggregate(core, akkaHttpHandler, tests)
lazy val core: Project = (project in file("core"))
@@ -67,7 +67,7 @@ lazy val akkaHttpHandler: Project = (project in file("akka-http-handler"))
libraryDependencies ++= Seq(
akkaHttp
)
- ) dependsOn(core)
+ ) dependsOn (core)
lazy val tests: Project = (project in file("tests"))
.settings(commonSettings: _*)
@@ -79,4 +79,4 @@ lazy val tests: Project = (project in file("tests"))
"com.typesafe.scala-logging" %% "scala-logging" % "3.5.0" % "test",
"com.github.pathikrit" %% "better-files" % "3.0.0"
)
- ) dependsOn(core, akkaHttpHandler) \ No newline at end of file
+ ) dependsOn (core, akkaHttpHandler)
diff --git a/core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala b/core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala
index 8d14907..fdbb322 100644
--- a/core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala
@@ -1,6 +1,11 @@
package com.softwaremill.sttp
-import java.io.{ByteArrayOutputStream, InputStream, OutputStream, OutputStreamWriter}
+import java.io.{
+ ByteArrayOutputStream,
+ InputStream,
+ OutputStream,
+ OutputStreamWriter
+}
import java.net.HttpURLConnection
import java.nio.channels.Channels
import java.nio.file.Files
@@ -11,7 +16,8 @@ import scala.annotation.tailrec
import scala.io.Source
object HttpConnectionSttpHandler extends SttpHandler[Id, Nothing] {
- override def send[T](r: Request, responseAs: ResponseAs[T, Nothing]): Response[T] = {
+ override def send[T](r: Request,
+ responseAs: ResponseAs[T, Nothing]): Response[T] = {
val c = r.uri.toURL.openConnection().asInstanceOf[HttpURLConnection]
c.setRequestMethod(r.method.m)
r.headers.foreach { case (k, v) => c.setRequestProperty(k, v) }
@@ -45,14 +51,16 @@ object HttpConnectionSttpHandler extends SttpHandler[Id, Nothing] {
case StringBody(b, encoding) =>
val writer = new OutputStreamWriter(c.getOutputStream, encoding)
- try writer.write(b) finally writer.close()
+ try writer.write(b)
+ finally writer.close()
case ByteArrayBody(b) =>
c.getOutputStream.write(b)
case ByteBufferBody(b) =>
val channel = Channels.newChannel(c.getOutputStream)
- try channel.write(b) finally channel.close()
+ try channel.write(b)
+ finally channel.close()
case InputStreamBody(b) =>
copyStream(b, c.getOutputStream)
@@ -68,34 +76,36 @@ object HttpConnectionSttpHandler extends SttpHandler[Id, Nothing] {
}
}
- private def readResponse[T](is: InputStream, responseAs: ResponseAs[T, Nothing]): T = responseAs match {
- case IgnoreResponse =>
- @tailrec def consume(): Unit = if (is.read() != -1) consume()
- consume()
-
- case ResponseAsString(enc) =>
- Source.fromInputStream(is, enc).mkString
-
- case ResponseAsByteArray =>
- val os = new ByteArrayOutputStream
- var read = 0
- val buf = new Array[Byte](1024)
-
- @tailrec
- def transfer(): Unit = {
- read = is.read(buf, 0, buf.length)
- if (read != -1) {
- os.write(buf, 0, read)
- transfer()
+ private def readResponse[T](is: InputStream,
+ responseAs: ResponseAs[T, Nothing]): T =
+ responseAs match {
+ case IgnoreResponse =>
+ @tailrec def consume(): Unit = if (is.read() != -1) consume()
+ consume()
+
+ case ResponseAsString(enc) =>
+ Source.fromInputStream(is, enc).mkString
+
+ case ResponseAsByteArray =>
+ val os = new ByteArrayOutputStream
+ var read = 0
+ val buf = new Array[Byte](1024)
+
+ @tailrec
+ def transfer(): Unit = {
+ read = is.read(buf, 0, buf.length)
+ if (read != -1) {
+ os.write(buf, 0, read)
+ transfer()
+ }
}
- }
- transfer()
+ transfer()
- os.toByteArray
+ os.toByteArray
- case ResponseAsStream() =>
- // only possible when the user requests the response as a stream of Nothing. Oh well ...
- throw new IllegalStateException()
- }
+ case ResponseAsStream() =>
+ // only possible when the user requests the response as a stream of Nothing. Oh well ...
+ throw new IllegalStateException()
+ }
}
diff --git a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala
index e329630..825985a 100644
--- a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala
@@ -7,23 +7,24 @@ object UriInterpolator {
private val unreserved = {
val alphanum = (('a' to 'z') ++ ('A' to 'Z') ++ ('0' to '9')).toSet
- val mark = Set('-', '_', '.', '!', '~', '*', '\'', '(', ')')
+ val mark = Set('-', '_', '.', '!', '~', '*', '\'', '(', ')')
alphanum ++ mark
}
def interpolate(sc: StringContext, args: String*): URI = {
- val strings = sc.parts.iterator
+ val strings = sc.parts.iterator
val expressions = args.iterator
- val sb = new StringBuffer(strings.next())
+ val sb = new StringBuffer(strings.next())
- while(strings.hasNext){
- for(c <- expressions.next()){
- if(unreserved(c))
+ while (strings.hasNext) {
+ for (c <- expressions.next()) {
+ if (unreserved(c))
sb.append(c)
- else for(b <- c.toString.getBytes("UTF-8")){
- sb.append("%")
- sb.append("%02X".format(b))
- }
+ else
+ for (b <- c.toString.getBytes("UTF-8")) {
+ sb.append("%")
+ sb.append("%02X".format(b))
+ }
}
sb.append(strings.next())
}
diff --git a/core/src/main/scala/com/softwaremill/sttp/model/package.scala b/core/src/main/scala/com/softwaremill/sttp/model/package.scala
index 913e1b9..0e8a5d0 100644
--- a/core/src/main/scala/com/softwaremill/sttp/model/package.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/model/package.scala
@@ -29,7 +29,8 @@ package object model {
sealed trait RequestBody
case object NoBody extends RequestBody
// TODO: extract StreamBody, with request parametrized to match the stream type?
- case class SerializableBody[T](f: BodySerializer[T], t: T) extends RequestBody
+ case class SerializableBody[T](f: BodySerializer[T], t: T)
+ extends RequestBody
sealed trait BasicRequestBody extends RequestBody
case class StringBody(s: String, encoding: String) extends BasicRequestBody
@@ -46,8 +47,10 @@ package object model {
sealed trait ResponseAs[T, +S]
object IgnoreResponse extends ResponseAs[Unit, Nothing]
- case class ResponseAsString(encoding: String) extends ResponseAs[String, Nothing]
+ case class ResponseAsString(encoding: String)
+ extends ResponseAs[String, Nothing]
object ResponseAsByteArray extends ResponseAs[Array[Byte], Nothing]
// response as params
- case class ResponseAsStream[T, S]()(implicit val responseIsStream: S =:= T) extends ResponseAs[T, S]
+ case class ResponseAsStream[T, S]()(implicit val responseIsStream: S =:= T)
+ extends ResponseAs[T, S]
}
diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala
index 3321aa7..d757bc0 100644
--- a/core/src/main/scala/com/softwaremill/sttp/package.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/package.scala
@@ -16,82 +16,125 @@ package object sttp {
type Empty[X] = None.type
def ignoreResponse: ResponseAs[Unit, Nothing] = IgnoreResponse
+
/**
* Uses `utf-8` encoding.
*/
def responseAsString: ResponseAs[String, Nothing] = responseAsString(Utf8)
- def responseAsString(encoding: String): ResponseAs[String, Nothing] = ResponseAsString(encoding)
- def responseAsByteArray: ResponseAs[Array[Byte], Nothing] = ResponseAsByteArray
+ def responseAsString(encoding: String): ResponseAs[String, Nothing] =
+ ResponseAsString(encoding)
+ def responseAsByteArray: ResponseAs[Array[Byte], Nothing] =
+ ResponseAsByteArray
def responseAsStream[S]: ResponseAs[S, S] = ResponseAsStream[S, S]()
/**
* 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, fileName: Option[String] = None,
- contentType: Option[String] = None, additionalHeaders: Map[String, String] = Map()) {
+ case class MultiPart(name: String,
+ data: 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 = copy(additionalHeaders = additionalHeaders + (k -> v))
+ def header(k: String, v: String): MultiPart =
+ copy(additionalHeaders = additionalHeaders + (k -> v))
}
/**
* 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, StringBody(data, Utf8), contentType = Some(contentTypeWithEncoding(TextPlainContentType, Utf8)))
+ MultiPart(name,
+ StringBody(data, Utf8),
+ contentType =
+ Some(contentTypeWithEncoding(TextPlainContentType, Utf8)))
+
/**
* 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, StringBody(data, encoding), contentType = Some(contentTypeWithEncoding(TextPlainContentType, Utf8)))
+ MultiPart(name,
+ StringBody(data, encoding),
+ contentType =
+ Some(contentTypeWithEncoding(TextPlainContentType, Utf8)))
+
/**
* 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, ByteArrayBody(data), contentType = Some(ApplicationOctetStreamContentType))
+ MultiPart(name,
+ ByteArrayBody(data),
+ contentType = Some(ApplicationOctetStreamContentType))
+
/**
* 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, ByteBufferBody(data), contentType = Some(ApplicationOctetStreamContentType))
+ MultiPart(name,
+ ByteBufferBody(data),
+ contentType = Some(ApplicationOctetStreamContentType))
+
/**
* 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, InputStreamBody(data), contentType = Some(ApplicationOctetStreamContentType))
+ MultiPart(name,
+ InputStreamBody(data),
+ contentType = Some(ApplicationOctetStreamContentType))
+
/**
* 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, FileBody(data), fileName = Some(data.getName), contentType = Some(ApplicationOctetStreamContentType))
+ MultiPart(name,
+ FileBody(data),
+ fileName = Some(data.getName),
+ contentType = Some(ApplicationOctetStreamContentType))
+
/**
* 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, PathBody(data), fileName = Some(data.getFileName.toString), contentType = Some(ApplicationOctetStreamContentType))
+ MultiPart(name,
+ PathBody(data),
+ fileName = Some(data.getFileName.toString),
+ contentType = Some(ApplicationOctetStreamContentType))
case class RequestTemplate[U[_]](
- method: U[Method],
- uri: U[URI],
- body: RequestBody,
- headers: Seq[(String, String)]
+ method: U[Method],
+ uri: U[URI],
+ body: RequestBody,
+ headers: Seq[(String, String)]
) {
def get(uri: URI): Request = this.copy[Id](uri = uri, method = Method.GET)
- def head(uri: URI): Request = this.copy[Id](uri = uri, method = Method.HEAD)
- def post(uri: URI): Request = this.copy[Id](uri = uri, method = Method.POST)
+ def head(uri: URI): Request =
+ this.copy[Id](uri = uri, method = Method.HEAD)
+ def post(uri: URI): Request =
+ this.copy[Id](uri = uri, method = Method.POST)
def put(uri: URI): Request = this.copy[Id](uri = uri, method = Method.PUT)
- def delete(uri: URI): Request = this.copy[Id](uri = uri, method = Method.DELETE)
- def options(uri: URI): Request = this.copy[Id](uri = uri, method = Method.OPTIONS)
- def patch(uri: URI): Request = this.copy[Id](uri = uri, method = Method.PATCH)
+ def delete(uri: URI): Request =
+ this.copy[Id](uri = uri, method = Method.DELETE)
+ def options(uri: URI): Request =
+ this.copy[Id](uri = uri, method = Method.OPTIONS)
+ def patch(uri: URI): Request =
+ this.copy[Id](uri = uri, method = Method.PATCH)
def contentType(ct: String): RequestTemplate[U] =
header(ContentTypeHeader, ct, replaceExisting = true)
def contentType(ct: String, encoding: String): RequestTemplate[U] =
- header(ContentTypeHeader, contentTypeWithEncoding(ct, encoding), replaceExisting = true)
- def header(k: String, v: String, replaceExisting: Boolean = false): RequestTemplate[U] = {
+ header(ContentTypeHeader,
+ contentTypeWithEncoding(ct, encoding),
+ replaceExisting = true)
+ def header(k: String,
+ v: String,
+ replaceExisting: Boolean = false): RequestTemplate[U] = {
val kLower = k.toLowerCase
- val current = if (replaceExisting) headers.filterNot(_._1.toLowerCase.contains(kLower)) else headers
+ val current =
+ if (replaceExisting)
+ headers.filterNot(_._1.toLowerCase.contains(kLower))
+ else headers
this.copy(headers = current :+ (k -> v))
}
@@ -99,44 +142,61 @@ package object sttp {
* If content type is not yet specified, will be set to `text/plain` with `utf-8` encoding.
*/
def body(b: String): RequestTemplate[U] = body(b, Utf8)
+
/**
* If content type is not yet specified, will be set to `text/plain` with the given encoding.
*/
def body(b: String, encoding: String): RequestTemplate[U] =
- setContentTypeIfMissing(contentTypeWithEncoding(TextPlainContentType, encoding)).copy(body = StringBody(b, encoding))
+ setContentTypeIfMissing(
+ contentTypeWithEncoding(TextPlainContentType, encoding))
+ .copy(body = StringBody(b, encoding))
+
/**
* If content type is not yet specified, will be set to `application/octet-stream`.
*/
def body(b: Array[Byte]): RequestTemplate[U] =
- setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(body = ByteArrayBody(b))
+ setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
+ body = ByteArrayBody(b))
+
/**
* If content type is not yet specified, will be set to `application/octet-stream`.
*/
def body(b: ByteBuffer): RequestTemplate[U] =
- setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(body = ByteBufferBody(b))
+ setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
+ body = ByteBufferBody(b))
+
/**
* If content type is not yet specified, will be set to `application/octet-stream`.
*/
def body(b: InputStream): RequestTemplate[U] =
- setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(body = InputStreamBody(b))
+ setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
+ body = InputStreamBody(b))
+
/**
* If content type is not yet specified, will be set to `application/octet-stream`.
*/
def body(b: File): RequestTemplate[U] =
- setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(body = FileBody(b))
+ setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
+ body = FileBody(b))
+
/**
* If content type is not yet specified, will be set to `application/octet-stream`.
*/
def body(b: Path): RequestTemplate[U] =
- setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(body = PathBody(b))
+ setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
+ body = PathBody(b))
+
/**
* If content type is not yet specified, will be set to `application/octet-stream`.
*/
def body[T: BodySerializer](b: T): RequestTemplate[U] =
- setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(body = SerializableBody(implicitly[BodySerializer[T]], b))
+ setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
+ body = SerializableBody(implicitly[BodySerializer[T]], b))
- private def hasContentType: Boolean = headers.exists(_._1.toLowerCase.contains(ContentTypeHeader))
- private def setContentTypeIfMissing(ct: String): RequestTemplate[U] = if (hasContentType) this else contentType(ct)
+ private def hasContentType: Boolean =
+ headers.exists(_._1.toLowerCase.contains(ContentTypeHeader))
+ private def setContentTypeIfMissing(ct: String): RequestTemplate[U] =
+ if (hasContentType) this else contentType(ct)
//def formData(fs: Map[String, Seq[String]]): RequestTemplate[U] = ???
def formData(fs: Map[String, String]): RequestTemplate[U] = ???
@@ -151,20 +211,23 @@ package object sttp {
* by the client if such a response type is requested.
*/
def send[R[_], S, T](responseAs: ResponseAs[T, S])(
- implicit handler: SttpHandler[R, S], isRequest: IsRequest[U]): R[Response[T]] = {
-
+ implicit handler: SttpHandler[R, S],
+ isRequest: IsRequest[U]): R[Response[T]] = {
+
handler.send(this, responseAs)
}
}
object RequestTemplate {
- val empty: RequestTemplate[Empty] = RequestTemplate[Empty](None, None, NoBody, Vector())
+ val empty: RequestTemplate[Empty] =
+ RequestTemplate[Empty](None, None, NoBody, Vector())
}
type PartialRequest = RequestTemplate[Empty]
type Request = RequestTemplate[Id]
- @implicitNotFound("This is a partial request, the method & url are not specified. Use .get(...), .post(...) etc. to obtain a non-partial request.")
+ @implicitNotFound(
+ "This is a partial request, the method & url are not specified. Use .get(...), .post(...) etc. to obtain a non-partial request.")
private type IsRequest[U[_]] = RequestTemplate[U] =:= Request
val sttp: RequestTemplate[Empty] = RequestTemplate.empty
@@ -177,9 +240,10 @@ package object sttp {
private val TextPlainContentType = "text/plain"
private val MultipartFormDataContentType = "multipart/form-data"
- private def contentTypeWithEncoding(ct: String, enc: String) = s"$ct; charset=$enc"
+ private def contentTypeWithEncoding(ct: String, enc: String) =
+ s"$ct; charset=$enc"
implicit class UriContext(val sc: StringContext) extends AnyVal {
- def uri(args:String*): URI = UriInterpolator.interpolate(sc, args: _*)
+ def uri(args: String*): URI = UriInterpolator.interpolate(sc, args: _*)
}
}
diff --git a/project/plugins.sbt b/project/plugins.sbt
index d4afe46..a87702c 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,3 +1,3 @@
-addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.4.0")
+addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.7")
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC5")
diff --git a/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala b/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala
index 597c042..39a4b25 100644
--- a/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala
+++ b/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala
@@ -17,20 +17,33 @@ import better.files._
import scala.concurrent.Future
import scala.language.higherKinds
-class BasicTests extends FlatSpec with Matchers with BeforeAndAfterAll with ScalaFutures with StrictLogging with IntegrationPatience {
- private def paramsToString(m: Map[String, String]): String = m.toList.sortBy(_._1).map(p => s"${p._1}=${p._2}").mkString(" ")
+class BasicTests
+ extends FlatSpec
+ with Matchers
+ with BeforeAndAfterAll
+ with ScalaFutures
+ with StrictLogging
+ with IntegrationPatience {
+ private def paramsToString(m: Map[String, String]): String =
+ m.toList.sortBy(_._1).map(p => s"${p._1}=${p._2}").mkString(" ")
private val serverRoutes =
path("echo") {
get {
parameterMap { params =>
- complete(List("GET", "/echo", paramsToString(params)).filter(_.nonEmpty).mkString(" "))
+ complete(
+ List("GET", "/echo", paramsToString(params))
+ .filter(_.nonEmpty)
+ .mkString(" "))
}
} ~
post {
parameterMap { params =>
entity(as[String]) { body: String =>
- complete(List("POST", "/echo", paramsToString(params), body).filter(_.nonEmpty).mkString(" "))
+ complete(
+ List("POST", "/echo", paramsToString(params), body)
+ .filter(_.nonEmpty)
+ .mkString(" "))
}
}
}
@@ -54,14 +67,20 @@ class BasicTests extends FlatSpec with Matchers with BeforeAndAfterAll with Scal
def force[T](wrapped: R[T]): T
}
- runTests("HttpURLConnection", HttpConnectionSttpHandler, new ForceWrappedValue[Id] {
- override def force[T](wrapped: Id[T]): T = wrapped
- })
- runTests("Akka HTTP", new AkkaHttpSttpHandler(actorSystem), new ForceWrappedValue[Future] {
- override def force[T](wrapped: Future[T]): T = wrapped.futureValue
- })
-
- def runTests[R[_]](name: String, handler: SttpHandler[R, Nothing], forceResponse: ForceWrappedValue[R]): Unit = {
+ runTests("HttpURLConnection",
+ HttpConnectionSttpHandler,
+ new ForceWrappedValue[Id] {
+ override def force[T](wrapped: Id[T]): T = wrapped
+ })
+ runTests("Akka HTTP",
+ new AkkaHttpSttpHandler(actorSystem),
+ new ForceWrappedValue[Future] {
+ override def force[T](wrapped: Future[T]): T = wrapped.futureValue
+ })
+
+ def runTests[R[_]](name: String,
+ handler: SttpHandler[R, Nothing],
+ forceResponse: ForceWrappedValue[R]): Unit = {
implicit val h = handler
val postEcho = sttp.post(new URI(endpoint + "/echo"))
@@ -77,13 +96,13 @@ class BasicTests extends FlatSpec with Matchers with BeforeAndAfterAll with Scal
name should "parse response as string" in {
val response = postEcho.body(testBody).send(responseAsString)
val fc = forceResponse.force(response).body
- fc should be (expectedPostEchoResponse)
+ fc should be(expectedPostEchoResponse)
}
name should "parse response as a byte array" in {
val response = postEcho.body(testBody).send(responseAsByteArray)
val fc = new String(forceResponse.force(response).body, "UTF-8")
- fc should be (expectedPostEchoResponse)
+ fc should be(expectedPostEchoResponse)
}
}
@@ -94,7 +113,7 @@ class BasicTests extends FlatSpec with Matchers with BeforeAndAfterAll with Scal
.send(responseAsString)
val fc = forceResponse.force(response).body
- fc should be ("GET /echo p1=v1 p2=v2")
+ fc should be("GET /echo p1=v1 p2=v2")
}
}
@@ -102,25 +121,28 @@ class BasicTests extends FlatSpec with Matchers with BeforeAndAfterAll with Scal
name should "post a string" in {
val response = postEcho.body(testBody).send(responseAsString)
val fc = forceResponse.force(response).body
- fc should be (expectedPostEchoResponse)
+ fc should be(expectedPostEchoResponse)
}
name should "post a byte array" in {
val response = postEcho.body(testBodyBytes).send(responseAsString)
val fc = forceResponse.force(response).body
- fc should be (expectedPostEchoResponse)
+ fc should be(expectedPostEchoResponse)
}
name should "post an input stream" in {
- val response = postEcho.body(new ByteArrayInputStream(testBodyBytes)).send(responseAsString)
+ val response = postEcho
+ .body(new ByteArrayInputStream(testBodyBytes))
+ .send(responseAsString)
val fc = forceResponse.force(response).body
- fc should be (expectedPostEchoResponse)
+ fc should be(expectedPostEchoResponse)
}
name should "post a byte buffer" in {
- val response = postEcho.body(ByteBuffer.wrap(testBodyBytes)).send(responseAsString)
+ val response =
+ postEcho.body(ByteBuffer.wrap(testBodyBytes)).send(responseAsString)
val fc = forceResponse.force(response).body
- fc should be (expectedPostEchoResponse)
+ fc should be(expectedPostEchoResponse)
}
name should "post a file" in {
diff --git a/tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala b/tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala
index 8ad8aea..0f30f8a 100644
--- a/tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala
+++ b/tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala
@@ -20,7 +20,7 @@ class UriInterpolatorTests extends FlatSpec with Matchers {
for (((interpolated, expected), i) <- testData.zipWithIndex) {
it should s"interpolate to $expected ($i)" in {
- interpolated should be (new URI(expected))
+ interpolated should be(new URI(expected))
}
}
}