From 52017e118df6cf22b95f4c10b6abe4162801a1ef Mon Sep 17 00:00:00 2001 From: adamw Date: Tue, 20 Feb 2018 12:24:10 +0100 Subject: New scalafmt settings --- .scalafmt.conf | 1 + .../sttp/akkahttp/AkkaHttpBackend.scala | 112 +++++++-------------- .../cats/AsyncHttpClientCatsBackend.scala | 60 ++++------- .../fs2/AsyncHttpClientFs2Backend.scala | 47 +++------ .../future/AsyncHttpClientFutureBackend.scala | 51 +++------- .../monix/AsyncHttpClientMonixBackend.scala | 65 ++++-------- .../scalaz/AsyncHttpClientScalazBackend.scala | 53 +++------- .../asynchttpclient/AsyncHttpClientBackend.scala | 79 ++++----------- .../softwaremill/sttp/FollowRedirectsBackend.scala | 13 +-- .../sttp/HttpURLConnectionBackend.scala | 41 +++----- .../scala/com/softwaremill/sttp/MonadError.scala | 20 ++-- .../scala/com/softwaremill/sttp/RequestBody.scala | 3 +- .../scala/com/softwaremill/sttp/RequestT.scala | 18 +--- .../scala/com/softwaremill/sttp/Response.scala | 3 +- .../scala/com/softwaremill/sttp/ResponseAs.scala | 28 ++---- .../com/softwaremill/sttp/SttpBackendOptions.scala | 5 +- .../scala/com/softwaremill/sttp/TryBackend.scala | 6 +- .../src/main/scala/com/softwaremill/sttp/Uri.scala | 71 ++++++------- .../com/softwaremill/sttp/UriInterpolator.scala | 83 +++++---------- .../main/scala/com/softwaremill/sttp/package.scala | 74 ++++---------- .../sttp/testing/SttpBackendStub.scala | 43 +++----- .../scala/com/softwaremill/sttp/RequestTests.scala | 6 +- .../softwaremill/sttp/UriInterpolatorTests.scala | 65 ++++-------- .../scala/com/softwaremill/sttp/UriTests.scala | 36 ++----- .../sttp/testing/SttpBackendStubTests.scala | 19 +--- .../com/softwaremill/sttp/circe/package.scala | 3 +- .../scala/com/softwaremill/sttp/CirceTests.scala | 6 +- .../com/softwaremill/sttp/json4s/package.scala | 6 +- .../scala/com/softwaremill/sttp/Json4sTests.scala | 6 +- .../com/softwaremill/sttp/brave/BraveBackend.scala | 26 ++--- .../softwaremill/sttp/brave/BraveBackendTest.scala | 16 +-- .../sttp/okhttp/monix/OkHttpMonixBackend.scala | 43 +++----- .../softwaremill/sttp/okhttp/OkHttpBackend.scala | 84 +++++----------- .../scala/com/softwaremill/sttp/BasicTests.scala | 77 ++++---------- .../com/softwaremill/sttp/IllTypedTests.scala | 6 +- .../com/softwaremill/sttp/StreamingTests.scala | 4 +- .../sttp/streaming/AkkaHttpStreamingTests.scala | 3 +- .../AsyncHttpClientFs2StreamingTests.scala | 3 +- .../sttp/streaming/MonixBaseBackend.scala | 6 +- .../scala/com/softwaremill/sttp/testHelpers.scala | 5 +- 40 files changed, 404 insertions(+), 892 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index e69de29..e661d6c 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -0,0 +1 @@ +maxColumn = 120 \ No newline at end of file diff --git a/akka-http-backend/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpBackend.scala b/akka-http-backend/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpBackend.scala index 5956793..0dabac7 100644 --- a/akka-http-backend/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpBackend.scala +++ b/akka-http-backend/src/main/scala/com/softwaremill/sttp/akkahttp/AkkaHttpBackend.scala @@ -4,18 +4,13 @@ import java.io.{File, IOException, UnsupportedEncodingException} import akka.actor.ActorSystem import akka.event.LoggingAdapter -import akka.http.scaladsl.{ClientTransport, Http, HttpsConnectionContext} import akka.http.scaladsl.coding.{Deflate, Gzip, NoCoding} import akka.http.scaladsl.model.ContentTypes.`application/octet-stream` import akka.http.scaladsl.model.HttpHeader.ParsingResult -import akka.http.scaladsl.model.headers.{ - HttpEncodings, - `Content-Length`, - `Content-Type` -} +import akka.http.scaladsl.model.headers.{HttpEncodings, `Content-Length`, `Content-Type`} import akka.http.scaladsl.model.{Multipart => AkkaMultipart, _} -import akka.http.scaladsl.settings.ClientConnectionSettings -import akka.http.scaladsl.settings.ConnectionPoolSettings +import akka.http.scaladsl.settings.{ClientConnectionSettings, ConnectionPoolSettings} +import akka.http.scaladsl.{ClientTransport, Http, HttpsConnectionContext} import akka.stream.ActorMaterializer import akka.stream.scaladsl.{FileIO, Source, StreamConverters} import akka.util.ByteString @@ -25,14 +20,13 @@ import scala.collection.immutable.Seq import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Success, Try} -class AkkaHttpBackend private ( - actorSystem: ActorSystem, - ec: ExecutionContext, - terminateActorSystemOnClose: Boolean, - opts: SttpBackendOptions, - customHttpsContext: Option[HttpsConnectionContext], - customConnectionPoolSettings: Option[ConnectionPoolSettings], - customLog: Option[LoggingAdapter]) +class AkkaHttpBackend private (actorSystem: ActorSystem, + ec: ExecutionContext, + terminateActorSystemOnClose: Boolean, + opts: SttpBackendOptions, + customHttpsContext: Option[HttpsConnectionContext], + customConnectionPoolSettings: Option[ConnectionPoolSettings], + customLog: Option[LoggingAdapter]) extends SttpBackend[Future, Source[ByteString, Any]] { // the supported stream type @@ -47,8 +41,7 @@ class AkkaHttpBackend private ( .withConnectingTimeout(opts.connectionTimeout) private val connectionPoolSettings = { - val base = customConnectionPoolSettings.getOrElse( - ConnectionPoolSettings(actorSystem)) + val base = customConnectionPoolSettings.getOrElse(ConnectionPoolSettings(actorSystem)) opts.proxy match { case None => base case Some(p) => @@ -60,8 +53,7 @@ class AkkaHttpBackend private ( implicit val ec: ExecutionContext = this.ec val settings = connectionPoolSettings - .withConnectionSettings( - connectionSettings.withIdleTimeout(r.options.readTimeout)) + .withConnectionSettings(connectionSettings.withIdleTimeout(r.options.readTimeout)) requestToAkka(r) .flatMap(setBodyOnAkka(r, r.body, _)) @@ -70,8 +62,7 @@ class AkkaHttpBackend private ( req => http.singleRequest(req, settings = settings, - connectionContext = customHttpsContext.getOrElse( - http.defaultClientHttpsContext), + connectionContext = customHttpsContext.getOrElse(http.defaultClientHttpsContext), log = customLog.getOrElse(actorSystem.log))) .flatMap { hr => val code = hr.status.intValue() @@ -110,9 +101,7 @@ class AkkaHttpBackend private ( case _ => HttpMethod.custom(m.m) } - private def bodyFromAkka[T](rr: ResponseAs[T, S], - hr: HttpResponse, - charsetFromHeaders: Option[String]): Future[T] = { + private def bodyFromAkka[T](rr: ResponseAs[T, S], hr: HttpResponse, charsetFromHeaders: Option[String]): Future[T] = { implicit val ec: ExecutionContext = this.ec @@ -126,8 +115,7 @@ class AkkaHttpBackend private ( file.getParentFile.mkdirs() file.createNewFile() } else if (!overwrite) { - throw new IOException( - s"File ${file.getAbsolutePath} exists - overwriting prohibited") + throw new IOException(s"File ${file.getAbsolutePath} exists - overwriting prohibited") } hr.entity.dataBytes.runWith(FileIO.toPath(file.toPath)) @@ -168,8 +156,7 @@ class AkkaHttpBackend private ( headersToAkka(r.headers).map(ar.withHeaders) } - private def headersToAkka( - headers: Seq[(String, String)]): Try[Seq[HttpHeader]] = { + private def headersToAkka(headers: Seq[(String, String)]): Try[Seq[HttpHeader]] = { // content-type and content-length headers have to be set via the body // entity, not as headers val parsed = @@ -200,9 +187,7 @@ class AkkaHttpBackend private ( else Failure[Seq[T]](fs.head.exception) } - private def setBodyOnAkka(r: Request[_, S], - body: RequestBody[S], - ar: HttpRequest): Try[HttpRequest] = { + private def setBodyOnAkka(r: Request[_, S], body: RequestBody[S], ar: HttpRequest): Try[HttpRequest] = { def ctWithEncoding(ct: ContentType, encoding: String) = HttpCharsets .getForKey(encoding) @@ -226,13 +211,9 @@ class AkkaHttpBackend private ( headers <- headersToAkka(mp.additionalHeaders.toList) } yield { val dispositionParams = - mp.fileName.fold(Map.empty[String, String])(fn => - Map("filename" -> fn)) + mp.fileName.fold(Map.empty[String, String])(fn => Map("filename" -> fn)) - AkkaMultipart.FormData.BodyPart(mp.name, - entity(ct), - dispositionParams, - headers) + AkkaMultipart.FormData.BodyPart(mp.name, entity(ct), dispositionParams, headers) } } @@ -240,44 +221,34 @@ class AkkaHttpBackend private ( body match { case NoBody => Success(ar) case StringBody(b, encoding, _) => - Success( - ar.withEntity(ctWithEncoding(ct, encoding), b.getBytes(encoding))) + Success(ar.withEntity(ctWithEncoding(ct, encoding), b.getBytes(encoding))) case ByteArrayBody(b, _) => Success(ar.withEntity(HttpEntity(ct, b))) case ByteBufferBody(b, _) => Success(ar.withEntity(HttpEntity(ct, ByteString(b)))) case InputStreamBody(b, _) => - Success( - ar.withEntity( - HttpEntity(ct, StreamConverters.fromInputStream(() => b)))) + Success(ar.withEntity(HttpEntity(ct, StreamConverters.fromInputStream(() => b)))) case PathBody(b, _) => Success(ar.withEntity(ct, b)) case StreamBody(s) => Success(ar.withEntity(HttpEntity(ct, s))) case MultipartBody(ps) => traverseTry(ps.map(toBodyPart)) - .map(bodyParts => - ar.withEntity(AkkaMultipart.FormData(bodyParts: _*).toEntity())) + .map(bodyParts => ar.withEntity(AkkaMultipart.FormData(bodyParts: _*).toEntity())) } } } - private def parseContentTypeOrOctetStream( - r: Request[_, S]): Try[ContentType] = { + private def parseContentTypeOrOctetStream(r: Request[_, S]): Try[ContentType] = { parseContentTypeOrOctetStream( r.headers .find(isContentType) .map(_._2)) } - private def parseContentTypeOrOctetStream( - ctHeader: Option[String]): Try[ContentType] = { + private def parseContentTypeOrOctetStream(ctHeader: Option[String]): Try[ContentType] = { ctHeader .map { ct => ContentType .parse(ct) - .fold( - errors => - Failure( - new RuntimeException(s"Cannot parse content type: $errors")), - Success(_)) + .fold(errors => Failure(new RuntimeException(s"Cannot parse content type: $errors")), Success(_)) } .getOrElse(Success(`application/octet-stream`)) } @@ -314,15 +285,13 @@ class AkkaHttpBackend private ( } object AkkaHttpBackend { - private def apply( - actorSystem: ActorSystem, - ec: ExecutionContext, - terminateActorSystemOnClose: Boolean, - options: SttpBackendOptions, - customHttpsContext: Option[HttpsConnectionContext], - customConnectionPoolSettings: Option[ConnectionPoolSettings], - customLog: Option[LoggingAdapter]) - : SttpBackend[Future, Source[ByteString, Any]] = + private def apply(actorSystem: ActorSystem, + ec: ExecutionContext, + terminateActorSystemOnClose: Boolean, + options: SttpBackendOptions, + customHttpsContext: Option[HttpsConnectionContext], + customConnectionPoolSettings: Option[ConnectionPoolSettings], + customLog: Option[LoggingAdapter]): SttpBackend[Future, Source[ByteString, Any]] = new FollowRedirectsBackend( new AkkaHttpBackend(actorSystem, ec, @@ -341,8 +310,7 @@ object AkkaHttpBackend { customHttpsContext: Option[HttpsConnectionContext] = None, customConnectionPoolSettings: Option[ConnectionPoolSettings] = None, customLog: Option[LoggingAdapter] = None)( - implicit ec: ExecutionContext = ExecutionContext.Implicits.global) - : SttpBackend[Future, Source[ByteString, Any]] = + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[Future, Source[ByteString, Any]] = AkkaHttpBackend(ActorSystem("sttp"), ec, terminateActorSystemOnClose = true, @@ -358,14 +326,12 @@ object AkkaHttpBackend { * e.g. mapping responses. Defaults to the global execution * context. */ - def usingActorSystem( - actorSystem: ActorSystem, - options: SttpBackendOptions = SttpBackendOptions.Default, - customHttpsContext: Option[HttpsConnectionContext] = None, - customConnectionPoolSettings: Option[ConnectionPoolSettings] = None, - customLog: Option[LoggingAdapter] = None)( - implicit ec: ExecutionContext = ExecutionContext.Implicits.global) - : SttpBackend[Future, Source[ByteString, Any]] = + def usingActorSystem(actorSystem: ActorSystem, + options: SttpBackendOptions = SttpBackendOptions.Default, + customHttpsContext: Option[HttpsConnectionContext] = None, + customConnectionPoolSettings: Option[ConnectionPoolSettings] = None, + customLog: Option[LoggingAdapter] = None)( + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[Future, Source[ByteString, Any]] = AkkaHttpBackend(actorSystem, ec, terminateActorSystemOnClose = false, diff --git a/async-http-client-backend/cats/src/main/scala/com/softwaremill/sttp/asynchttpclient/cats/AsyncHttpClientCatsBackend.scala b/async-http-client-backend/cats/src/main/scala/com/softwaremill/sttp/asynchttpclient/cats/AsyncHttpClientCatsBackend.scala index 471d26c..9d7ed88 100644 --- a/async-http-client-backend/cats/src/main/scala/com/softwaremill/sttp/asynchttpclient/cats/AsyncHttpClientCatsBackend.scala +++ b/async-http-client-backend/cats/src/main/scala/com/softwaremill/sttp/asynchttpclient/cats/AsyncHttpClientCatsBackend.scala @@ -4,17 +4,8 @@ import java.nio.ByteBuffer import cats.effect._ import com.softwaremill.sttp.asynchttpclient.AsyncHttpClientBackend -import com.softwaremill.sttp.{ - FollowRedirectsBackend, - MonadAsyncError, - SttpBackend, - SttpBackendOptions -} -import org.asynchttpclient.{ - AsyncHttpClient, - AsyncHttpClientConfig, - DefaultAsyncHttpClient -} +import com.softwaremill.sttp.{FollowRedirectsBackend, MonadAsyncError, SttpBackend, SttpBackendOptions} +import org.asynchttpclient.{AsyncHttpClient, AsyncHttpClientConfig, DefaultAsyncHttpClient} import org.reactivestreams.Publisher import scala.language.higherKinds @@ -27,47 +18,33 @@ class AsyncHttpClientCatsBackend[F[_]: Async] private ( new AsyncMonad, closeClient ) { - override protected def streamBodyToPublisher( - s: Nothing): Publisher[ByteBuffer] = s // nothing is everything + override protected def streamBodyToPublisher(s: Nothing): Publisher[ByteBuffer] = s // nothing is everything - override protected def publisherToStreamBody( - p: Publisher[ByteBuffer]): Nothing = + override protected def publisherToStreamBody(p: Publisher[ByteBuffer]): Nothing = throw new IllegalStateException("This backend does not support streaming") - override protected def publisherToString( - p: Publisher[ByteBuffer]): F[String] = + override protected def publisherToString(p: Publisher[ByteBuffer]): F[String] = throw new IllegalStateException("This backend does not support streaming") } object AsyncHttpClientCatsBackend { - private def apply[F[_]: Async]( - asyncHttpClient: AsyncHttpClient, - closeClient: Boolean): SttpBackend[F, Nothing] = - new FollowRedirectsBackend[F, Nothing]( - new AsyncHttpClientCatsBackend(asyncHttpClient, closeClient)) - - def apply[F[_]: Async]( - options: SttpBackendOptions = SttpBackendOptions.Default) - : SttpBackend[F, Nothing] = - AsyncHttpClientCatsBackend(AsyncHttpClientBackend.defaultClient(options), - closeClient = true) - - def usingConfig[F[_]: Async]( - cfg: AsyncHttpClientConfig): SttpBackend[F, Nothing] = - AsyncHttpClientCatsBackend(new DefaultAsyncHttpClient(cfg), - closeClient = true) - - def usingClient[F[_]: Async]( - client: AsyncHttpClient): SttpBackend[F, Nothing] = + private def apply[F[_]: Async](asyncHttpClient: AsyncHttpClient, closeClient: Boolean): SttpBackend[F, Nothing] = + new FollowRedirectsBackend[F, Nothing](new AsyncHttpClientCatsBackend(asyncHttpClient, closeClient)) + + def apply[F[_]: Async](options: SttpBackendOptions = SttpBackendOptions.Default): SttpBackend[F, Nothing] = + AsyncHttpClientCatsBackend(AsyncHttpClientBackend.defaultClient(options), closeClient = true) + + def usingConfig[F[_]: Async](cfg: AsyncHttpClientConfig): SttpBackend[F, Nothing] = + AsyncHttpClientCatsBackend(new DefaultAsyncHttpClient(cfg), closeClient = true) + + def usingClient[F[_]: Async](client: AsyncHttpClient): SttpBackend[F, Nothing] = AsyncHttpClientCatsBackend(client, closeClient = false) } -private[cats] class AsyncMonad[F[_]](implicit F: Async[F]) - extends MonadAsyncError[F] { +private[cats] class AsyncMonad[F[_]](implicit F: Async[F]) extends MonadAsyncError[F] { - override def async[T]( - register: ((Either[Throwable, T]) => Unit) => Unit): F[T] = + override def async[T](register: ((Either[Throwable, T]) => Unit) => Unit): F[T] = F.async(register) override def unit[T](t: T): F[T] = F.pure(t) @@ -79,7 +56,6 @@ private[cats] class AsyncMonad[F[_]](implicit F: Async[F]) override def error[T](t: Throwable): F[T] = F.raiseError(t) - override protected def handleWrappedError[T](rt: F[T])( - h: PartialFunction[Throwable, F[T]]): F[T] = + override protected def handleWrappedError[T](rt: F[T])(h: PartialFunction[Throwable, F[T]]): F[T] = F.recoverWith(rt)(h) } diff --git a/async-http-client-backend/fs2/src/main/scala/com/softwaremill/sttp/asynchttpclient/fs2/AsyncHttpClientFs2Backend.scala b/async-http-client-backend/fs2/src/main/scala/com/softwaremill/sttp/asynchttpclient/fs2/AsyncHttpClientFs2Backend.scala index 4c6dc71..e608499 100644 --- a/async-http-client-backend/fs2/src/main/scala/com/softwaremill/sttp/asynchttpclient/fs2/AsyncHttpClientFs2Backend.scala +++ b/async-http-client-backend/fs2/src/main/scala/com/softwaremill/sttp/asynchttpclient/fs2/AsyncHttpClientFs2Backend.scala @@ -13,25 +13,21 @@ import org.reactivestreams.Publisher import scala.concurrent.ExecutionContext import scala.language.higherKinds -class AsyncHttpClientFs2Backend[F[_]: Effect] private ( - asyncHttpClient: AsyncHttpClient, - closeClient: Boolean)(implicit ec: ExecutionContext) +class AsyncHttpClientFs2Backend[F[_]: Effect] private (asyncHttpClient: AsyncHttpClient, closeClient: Boolean)( + implicit ec: ExecutionContext) extends AsyncHttpClientBackend[F, Stream[F, ByteBuffer]]( asyncHttpClient, new EffectMonad, closeClient ) { - override protected def streamBodyToPublisher( - s: Stream[F, ByteBuffer]): Publisher[ByteBuffer] = + override protected def streamBodyToPublisher(s: Stream[F, ByteBuffer]): Publisher[ByteBuffer] = s.toUnicastPublisher - override protected def publisherToStreamBody( - p: Publisher[ByteBuffer]): Stream[F, ByteBuffer] = + override protected def publisherToStreamBody(p: Publisher[ByteBuffer]): Stream[F, ByteBuffer] = p.toStream[F] - override protected def publisherToString( - p: Publisher[ByteBuffer]): F[String] = { + override protected def publisherToString(p: Publisher[ByteBuffer]): F[String] = { val bytes = p .toStream[F] .compile @@ -43,23 +39,18 @@ class AsyncHttpClientFs2Backend[F[_]: Effect] private ( object AsyncHttpClientFs2Backend { - private def apply[F[_]: Effect](asyncHttpClient: AsyncHttpClient, - closeClient: Boolean)( + private def apply[F[_]: Effect](asyncHttpClient: AsyncHttpClient, closeClient: Boolean)( implicit ec: ExecutionContext): SttpBackend[F, Stream[F, ByteBuffer]] = - new FollowRedirectsBackend( - new AsyncHttpClientFs2Backend(asyncHttpClient, closeClient)) + new FollowRedirectsBackend(new AsyncHttpClientFs2Backend(asyncHttpClient, closeClient)) /** * @param ec The execution context for running non-network related operations, * e.g. mapping responses. Defaults to the global execution * context. */ - def apply[F[_]: Effect](options: SttpBackendOptions = - SttpBackendOptions.Default)( - implicit ec: ExecutionContext = ExecutionContext.Implicits.global) - : SttpBackend[F, Stream[F, ByteBuffer]] = - AsyncHttpClientFs2Backend[F](AsyncHttpClientBackend.defaultClient(options), - closeClient = true) + def apply[F[_]: Effect](options: SttpBackendOptions = SttpBackendOptions.Default)( + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[F, Stream[F, ByteBuffer]] = + AsyncHttpClientFs2Backend[F](AsyncHttpClientBackend.defaultClient(options), closeClient = true) /** * @param ec The execution context for running non-network related operations, @@ -67,10 +58,8 @@ object AsyncHttpClientFs2Backend { * context. */ def usingConfig[F[_]: Effect](cfg: AsyncHttpClientConfig)( - implicit ec: ExecutionContext = ExecutionContext.Implicits.global) - : SttpBackend[F, Stream[F, ByteBuffer]] = - AsyncHttpClientFs2Backend[F](new DefaultAsyncHttpClient(cfg), - closeClient = true) + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[F, Stream[F, ByteBuffer]] = + AsyncHttpClientFs2Backend[F](new DefaultAsyncHttpClient(cfg), closeClient = true) /** * @param ec The execution context for running non-network related operations, @@ -78,16 +67,13 @@ object AsyncHttpClientFs2Backend { * context. */ def usingClient[F[_]: Effect](client: AsyncHttpClient)( - implicit ec: ExecutionContext = ExecutionContext.Implicits.global) - : SttpBackend[F, Stream[F, ByteBuffer]] = + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[F, Stream[F, ByteBuffer]] = AsyncHttpClientFs2Backend[F](client, closeClient = false) } -private[fs2] class EffectMonad[F[_]](implicit F: Effect[F]) - extends MonadAsyncError[F] { +private[fs2] class EffectMonad[F[_]](implicit F: Effect[F]) extends MonadAsyncError[F] { - override def async[T]( - register: ((Either[Throwable, T]) => Unit) => Unit): F[T] = + override def async[T](register: ((Either[Throwable, T]) => Unit) => Unit): F[T] = F.async(register) override def unit[T](t: T): F[T] = F.pure(t) @@ -99,7 +85,6 @@ private[fs2] class EffectMonad[F[_]](implicit F: Effect[F]) override def error[T](t: Throwable): F[T] = F.raiseError(t) - override protected def handleWrappedError[T](rt: F[T])( - h: PartialFunction[Throwable, F[T]]): F[T] = + override protected def handleWrappedError[T](rt: F[T])(h: PartialFunction[Throwable, F[T]]): F[T] = F.recoverWith(rt)(h) } diff --git a/async-http-client-backend/future/src/main/scala/com/softwaremill/sttp/asynchttpclient/future/AsyncHttpClientFutureBackend.scala b/async-http-client-backend/future/src/main/scala/com/softwaremill/sttp/asynchttpclient/future/AsyncHttpClientFutureBackend.scala index 6778fa0..d91f404 100644 --- a/async-http-client-backend/future/src/main/scala/com/softwaremill/sttp/asynchttpclient/future/AsyncHttpClientFutureBackend.scala +++ b/async-http-client-backend/future/src/main/scala/com/softwaremill/sttp/asynchttpclient/future/AsyncHttpClientFutureBackend.scala @@ -3,37 +3,22 @@ package com.softwaremill.sttp.asynchttpclient.future import java.nio.ByteBuffer import com.softwaremill.sttp.asynchttpclient.AsyncHttpClientBackend -import com.softwaremill.sttp.{ - FollowRedirectsBackend, - FutureMonad, - SttpBackend, - SttpBackendOptions -} -import org.asynchttpclient.{ - AsyncHttpClient, - AsyncHttpClientConfig, - DefaultAsyncHttpClient -} +import com.softwaremill.sttp.{FollowRedirectsBackend, FutureMonad, SttpBackend, SttpBackendOptions} +import org.asynchttpclient.{AsyncHttpClient, AsyncHttpClientConfig, DefaultAsyncHttpClient} import org.reactivestreams.Publisher import scala.concurrent.{ExecutionContext, Future} -class AsyncHttpClientFutureBackend private ( - asyncHttpClient: AsyncHttpClient, - closeClient: Boolean)(implicit ec: ExecutionContext) - extends AsyncHttpClientBackend[Future, Nothing](asyncHttpClient, - new FutureMonad, - closeClient) { +class AsyncHttpClientFutureBackend private (asyncHttpClient: AsyncHttpClient, closeClient: Boolean)( + implicit ec: ExecutionContext) + extends AsyncHttpClientBackend[Future, Nothing](asyncHttpClient, new FutureMonad, closeClient) { - override protected def streamBodyToPublisher( - s: Nothing): Publisher[ByteBuffer] = s // nothing is everything + override protected def streamBodyToPublisher(s: Nothing): Publisher[ByteBuffer] = s // nothing is everything - override protected def publisherToStreamBody( - p: Publisher[ByteBuffer]): Nothing = + override protected def publisherToStreamBody(p: Publisher[ByteBuffer]): Nothing = throw new IllegalStateException("This backend does not support streaming") - override protected def publisherToString( - p: Publisher[ByteBuffer]): Future[String] = + override protected def publisherToString(p: Publisher[ByteBuffer]): Future[String] = throw new IllegalStateException("This backend does not support streaming") } @@ -41,8 +26,7 @@ object AsyncHttpClientFutureBackend { private def apply(asyncHttpClient: AsyncHttpClient, closeClient: Boolean)( implicit ec: ExecutionContext): SttpBackend[Future, Nothing] = - new FollowRedirectsBackend[Future, Nothing]( - new AsyncHttpClientFutureBackend(asyncHttpClient, closeClient)) + new FollowRedirectsBackend[Future, Nothing](new AsyncHttpClientFutureBackend(asyncHttpClient, closeClient)) /** * @param ec The execution context for running non-network related operations, @@ -50,10 +34,8 @@ object AsyncHttpClientFutureBackend { * context. */ def apply(options: SttpBackendOptions = SttpBackendOptions.Default)( - implicit ec: ExecutionContext = ExecutionContext.Implicits.global) - : SttpBackend[Future, Nothing] = - AsyncHttpClientFutureBackend(AsyncHttpClientBackend.defaultClient(options), - closeClient = true) + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[Future, Nothing] = + AsyncHttpClientFutureBackend(AsyncHttpClientBackend.defaultClient(options), closeClient = true) /** * @param ec The execution context for running non-network related operations, @@ -61,18 +43,15 @@ object AsyncHttpClientFutureBackend { * context. */ def usingConfig(cfg: AsyncHttpClientConfig)( - implicit ec: ExecutionContext = ExecutionContext.Implicits.global) - : SttpBackend[Future, Nothing] = - AsyncHttpClientFutureBackend(new DefaultAsyncHttpClient(cfg), - closeClient = true) + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[Future, Nothing] = + AsyncHttpClientFutureBackend(new DefaultAsyncHttpClient(cfg), closeClient = true) /** * @param ec The execution context for running non-network related operations, * e.g. mapping responses. Defaults to the global execution * context. */ - def usingClient(client: AsyncHttpClient)(implicit ec: ExecutionContext = - ExecutionContext.Implicits.global) - : SttpBackend[Future, Nothing] = + def usingClient(client: AsyncHttpClient)( + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[Future, Nothing] = AsyncHttpClientFutureBackend(client, closeClient = false) } diff --git a/async-http-client-backend/monix/src/main/scala/com/softwaremill/sttp/asynchttpclient/monix/AsyncHttpClientMonixBackend.scala b/async-http-client-backend/monix/src/main/scala/com/softwaremill/sttp/asynchttpclient/monix/AsyncHttpClientMonixBackend.scala index 04df4ed..03d4d09 100644 --- a/async-http-client-backend/monix/src/main/scala/com/softwaremill/sttp/asynchttpclient/monix/AsyncHttpClientMonixBackend.scala +++ b/async-http-client-backend/monix/src/main/scala/com/softwaremill/sttp/asynchttpclient/monix/AsyncHttpClientMonixBackend.scala @@ -2,45 +2,27 @@ package com.softwaremill.sttp.asynchttpclient.monix import java.nio.ByteBuffer -import com.softwaremill.sttp.{ - FollowRedirectsBackend, - MonadAsyncError, - SttpBackend, - SttpBackendOptions, - Utf8, - concatByteBuffers -} import com.softwaremill.sttp.asynchttpclient.AsyncHttpClientBackend +import com.softwaremill.sttp.{FollowRedirectsBackend, MonadAsyncError, SttpBackend, SttpBackendOptions, Utf8, concatByteBuffers} import monix.eval.Task import monix.execution.{Cancelable, Scheduler} import monix.reactive.Observable -import org.asynchttpclient.{ - AsyncHttpClient, - AsyncHttpClientConfig, - DefaultAsyncHttpClient -} +import org.asynchttpclient.{AsyncHttpClient, AsyncHttpClientConfig, DefaultAsyncHttpClient} import org.reactivestreams.Publisher import scala.util.{Failure, Success} -class AsyncHttpClientMonixBackend private ( - asyncHttpClient: AsyncHttpClient, - closeClient: Boolean)(implicit scheduler: Scheduler) - extends AsyncHttpClientBackend[Task, Observable[ByteBuffer]]( - asyncHttpClient, - TaskMonad, - closeClient) { +class AsyncHttpClientMonixBackend private (asyncHttpClient: AsyncHttpClient, closeClient: Boolean)( + implicit scheduler: Scheduler) + extends AsyncHttpClientBackend[Task, Observable[ByteBuffer]](asyncHttpClient, TaskMonad, closeClient) { - override protected def streamBodyToPublisher( - s: Observable[ByteBuffer]): Publisher[ByteBuffer] = + override protected def streamBodyToPublisher(s: Observable[ByteBuffer]): Publisher[ByteBuffer] = s.toReactivePublisher - override protected def publisherToStreamBody( - p: Publisher[ByteBuffer]): Observable[ByteBuffer] = + override protected def publisherToStreamBody(p: Publisher[ByteBuffer]): Observable[ByteBuffer] = Observable.fromReactivePublisher(p) - override protected def publisherToString( - p: Publisher[ByteBuffer]): Task[String] = { + override protected def publisherToString(p: Publisher[ByteBuffer]): Task[String] = { val bytes = Observable .fromReactivePublisher(p) @@ -53,38 +35,31 @@ class AsyncHttpClientMonixBackend private ( object AsyncHttpClientMonixBackend { private def apply(asyncHttpClient: AsyncHttpClient, closeClient: Boolean)( - implicit scheduler: Scheduler) - : SttpBackend[Task, Observable[ByteBuffer]] = - new FollowRedirectsBackend( - new AsyncHttpClientMonixBackend(asyncHttpClient, closeClient)) + implicit scheduler: Scheduler): SttpBackend[Task, Observable[ByteBuffer]] = + new FollowRedirectsBackend(new AsyncHttpClientMonixBackend(asyncHttpClient, closeClient)) /** * @param s The scheduler used for streaming request bodies. Defaults to the * global scheduler. */ def apply(options: SttpBackendOptions = SttpBackendOptions.Default)( - implicit s: Scheduler = Scheduler.Implicits.global) - : SttpBackend[Task, Observable[ByteBuffer]] = - AsyncHttpClientMonixBackend(AsyncHttpClientBackend.defaultClient(options), - closeClient = true) + implicit s: Scheduler = Scheduler.Implicits.global): SttpBackend[Task, Observable[ByteBuffer]] = + AsyncHttpClientMonixBackend(AsyncHttpClientBackend.defaultClient(options), closeClient = true) /** * @param s The scheduler used for streaming request bodies. Defaults to the * global scheduler. */ - def usingConfig(cfg: AsyncHttpClientConfig)(implicit s: Scheduler = - Scheduler.Implicits.global) - : SttpBackend[Task, Observable[ByteBuffer]] = - AsyncHttpClientMonixBackend(new DefaultAsyncHttpClient(cfg), - closeClient = true) + def usingConfig(cfg: AsyncHttpClientConfig)( + implicit s: Scheduler = Scheduler.Implicits.global): SttpBackend[Task, Observable[ByteBuffer]] = + AsyncHttpClientMonixBackend(new DefaultAsyncHttpClient(cfg), closeClient = true) /** * @param s The scheduler used for streaming request bodies. Defaults to the * global scheduler. */ - def usingClient(client: AsyncHttpClient)(implicit s: Scheduler = - Scheduler.Implicits.global) - : SttpBackend[Task, Observable[ByteBuffer]] = + def usingClient(client: AsyncHttpClient)( + implicit s: Scheduler = Scheduler.Implicits.global): SttpBackend[Task, Observable[ByteBuffer]] = AsyncHttpClientMonixBackend(client, closeClient = false) } @@ -96,8 +71,7 @@ private[monix] object TaskMonad extends MonadAsyncError[Task] { override def flatMap[T, T2](fa: Task[T])(f: (T) => Task[T2]): Task[T2] = fa.flatMap(f) - override def async[T]( - register: ((Either[Throwable, T]) => Unit) => Unit): Task[T] = + override def async[T](register: ((Either[Throwable, T]) => Unit) => Unit): Task[T] = Task.async { (_, cb) => register { case Left(t) => cb(Failure(t)) @@ -109,7 +83,6 @@ private[monix] object TaskMonad extends MonadAsyncError[Task] { override def error[T](t: Throwable): Task[T] = Task.raiseError(t) - override protected def handleWrappedError[T](rt: Task[T])( - h: PartialFunction[Throwable, Task[T]]): Task[T] = + override protected def handleWrappedError[T](rt: Task[T])(h: PartialFunction[Throwable, Task[T]]): Task[T] = rt.onErrorRecoverWith(h) } diff --git a/async-http-client-backend/scalaz/src/main/scala/com/softwaremill/sttp/asynchttpclient/scalaz/AsyncHttpClientScalazBackend.scala b/async-http-client-backend/scalaz/src/main/scala/com/softwaremill/sttp/asynchttpclient/scalaz/AsyncHttpClientScalazBackend.scala index 3828233..cdb45c3 100644 --- a/async-http-client-backend/scalaz/src/main/scala/com/softwaremill/sttp/asynchttpclient/scalaz/AsyncHttpClientScalazBackend.scala +++ b/async-http-client-backend/scalaz/src/main/scala/com/softwaremill/sttp/asynchttpclient/scalaz/AsyncHttpClientScalazBackend.scala @@ -2,55 +2,35 @@ package com.softwaremill.sttp.asynchttpclient.scalaz import java.nio.ByteBuffer -import com.softwaremill.sttp.{ - FollowRedirectsBackend, - MonadAsyncError, - SttpBackend, - SttpBackendOptions -} import com.softwaremill.sttp.asynchttpclient.AsyncHttpClientBackend -import org.asynchttpclient.{ - AsyncHttpClient, - AsyncHttpClientConfig, - DefaultAsyncHttpClient -} +import com.softwaremill.sttp.{FollowRedirectsBackend, MonadAsyncError, SttpBackend, SttpBackendOptions} +import org.asynchttpclient.{AsyncHttpClient, AsyncHttpClientConfig, DefaultAsyncHttpClient} import org.reactivestreams.Publisher -import scalaz.{-\/, \/-} import scalaz.concurrent.Task +import scalaz.{-\/, \/-} -class AsyncHttpClientScalazBackend private (asyncHttpClient: AsyncHttpClient, - closeClient: Boolean) - extends AsyncHttpClientBackend[Task, Nothing](asyncHttpClient, - TaskMonad, - closeClient) { +class AsyncHttpClientScalazBackend private (asyncHttpClient: AsyncHttpClient, closeClient: Boolean) + extends AsyncHttpClientBackend[Task, Nothing](asyncHttpClient, TaskMonad, closeClient) { - override protected def streamBodyToPublisher( - s: Nothing): Publisher[ByteBuffer] = s // nothing is everything + override protected def streamBodyToPublisher(s: Nothing): Publisher[ByteBuffer] = s // nothing is everything - override protected def publisherToStreamBody( - p: Publisher[ByteBuffer]): Nothing = + override protected def publisherToStreamBody(p: Publisher[ByteBuffer]): Nothing = throw new IllegalStateException("This backend does not support streaming") - override protected def publisherToString( - p: Publisher[ByteBuffer]): Task[String] = + override protected def publisherToString(p: Publisher[ByteBuffer]): Task[String] = throw new IllegalStateException("This backend does not support streaming") } object AsyncHttpClientScalazBackend { - private def apply(asyncHttpClient: AsyncHttpClient, - closeClient: Boolean): SttpBackend[Task, Nothing] = - new FollowRedirectsBackend[Task, Nothing]( - new AsyncHttpClientScalazBackend(asyncHttpClient, closeClient)) + private def apply(asyncHttpClient: AsyncHttpClient, closeClient: Boolean): SttpBackend[Task, Nothing] = + new FollowRedirectsBackend[Task, Nothing](new AsyncHttpClientScalazBackend(asyncHttpClient, closeClient)) - def apply(options: SttpBackendOptions = SttpBackendOptions.Default) - : SttpBackend[Task, Nothing] = - AsyncHttpClientScalazBackend(AsyncHttpClientBackend.defaultClient(options), - closeClient = true) + def apply(options: SttpBackendOptions = SttpBackendOptions.Default): SttpBackend[Task, Nothing] = + AsyncHttpClientScalazBackend(AsyncHttpClientBackend.defaultClient(options), closeClient = true) def usingConfig(cfg: AsyncHttpClientConfig): SttpBackend[Task, Nothing] = - AsyncHttpClientScalazBackend(new DefaultAsyncHttpClient(cfg), - closeClient = true) + AsyncHttpClientScalazBackend(new DefaultAsyncHttpClient(cfg), closeClient = true) def usingClient(client: AsyncHttpClient): SttpBackend[Task, Nothing] = AsyncHttpClientScalazBackend(client, closeClient = false) @@ -64,8 +44,7 @@ private[scalaz] object TaskMonad extends MonadAsyncError[Task] { override def flatMap[T, T2](fa: Task[T])(f: (T) => Task[T2]): Task[T2] = fa.flatMap(f) - override def async[T]( - register: ((Either[Throwable, T]) => Unit) => Unit): Task[T] = + override def async[T](register: ((Either[Throwable, T]) => Unit) => Unit): Task[T] = Task.async { cb => register { case Left(t) => cb(-\/(t)) @@ -75,6 +54,6 @@ private[scalaz] object TaskMonad extends MonadAsyncError[Task] { override def error[T](t: Throwable): Task[T] = Task.fail(t) - override protected def handleWrappedError[T](rt: Task[T])( - h: PartialFunction[Throwable, Task[T]]): Task[T] = rt.handleWith(h) + override protected def handleWrappedError[T](rt: Task[T])(h: PartialFunction[Throwable, Task[T]]): Task[T] = + rt.handleWith(h) } diff --git a/async-http-client-backend/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientBackend.scala b/async-http-client-backend/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientBackend.scala index fb0f780..d804f08 100644 --- a/async-http-client-backend/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientBackend.scala +++ b/async-http-client-backend/src/main/scala/com/softwaremill/sttp/asynchttpclient/AsyncHttpClientBackend.scala @@ -8,25 +8,8 @@ import com.softwaremill.sttp._ import org.asynchttpclient.AsyncHandler.State import org.asynchttpclient.handler.StreamedAsyncHandler import org.asynchttpclient.proxy.ProxyServer -import org.asynchttpclient.request.body.multipart.{ - ByteArrayPart, - FilePart, - StringPart -} -import org.asynchttpclient.{ - AsyncCompletionHandler, - AsyncHandler, - AsyncHttpClient, - DefaultAsyncHttpClient, - DefaultAsyncHttpClientConfig, - HttpResponseBodyPart, - HttpResponseHeaders, - HttpResponseStatus, - Param, - RequestBuilder, - Request => AsyncRequest, - Response => AsyncResponse -} +import org.asynchttpclient.request.body.multipart.{ByteArrayPart, FilePart, StringPart} +import org.asynchttpclient.{AsyncCompletionHandler, AsyncHandler, AsyncHttpClient, DefaultAsyncHttpClient, DefaultAsyncHttpClientConfig, HttpResponseBodyPart, HttpResponseHeaders, HttpResponseStatus, Param, RequestBuilder, Request => AsyncRequest, Response => AsyncResponse} import org.reactivestreams.{Publisher, Subscriber, Subscription} import scala.collection.JavaConverters._ @@ -66,10 +49,9 @@ abstract class AsyncHttpClientBackend[R[_], S](asyncHttpClient: AsyncHttpClient, protected def publisherToString(p: Publisher[ByteBuffer]): R[String] - private def eagerAsyncHandler[T]( - responseAs: ResponseAs[T, S], - success: R[Response[T]] => Unit, - error: Throwable => Unit): AsyncHandler[Unit] = { + private def eagerAsyncHandler[T](responseAs: ResponseAs[T, S], + success: R[Response[T]] => Unit, + error: Throwable => Unit): AsyncHandler[Unit] = { new AsyncCompletionHandler[Unit] { override def onCompleted(response: AsyncResponse): Unit = @@ -79,17 +61,15 @@ abstract class AsyncHttpClientBackend[R[_], S](asyncHttpClient: AsyncHttpClient, } } - private def streamingAsyncHandler[T]( - responseAs: ResponseAsStream[T, S], - success: R[Response[T]] => Unit, - error: Throwable => Unit): AsyncHandler[Unit] = { + private def streamingAsyncHandler[T](responseAs: ResponseAsStream[T, S], + success: R[Response[T]] => Unit, + error: Throwable => Unit): AsyncHandler[Unit] = { new StreamedAsyncHandler[Unit] { private val builder = new AsyncResponse.ResponseBuilder() private var publisher: Option[Publisher[ByteBuffer]] = None private var completed = false - override def onStream( - p: Publisher[HttpResponseBodyPart]): AsyncHandler.State = { + override def onStream(p: Publisher[HttpResponseBodyPart]): AsyncHandler.State = { // Sadly we don't have .map on Publisher publisher = Some(new Publisher[ByteBuffer] { override def subscribe(s: Subscriber[_ >: ByteBuffer]): Unit = @@ -109,19 +89,15 @@ abstract class AsyncHttpClientBackend[R[_], S](asyncHttpClient: AsyncHttpClient, State.CONTINUE } - override def onBodyPartReceived( - bodyPart: HttpResponseBodyPart): AsyncHandler.State = - throw new IllegalStateException( - "Requested a streaming backend, unexpected eager body parts.") + override def onBodyPartReceived(bodyPart: HttpResponseBodyPart): AsyncHandler.State = + throw new IllegalStateException("Requested a streaming backend, unexpected eager body parts.") - override def onHeadersReceived( - headers: HttpResponseHeaders): AsyncHandler.State = { + override def onHeadersReceived(headers: HttpResponseHeaders): AsyncHandler.State = { builder.accumulate(headers) State.CONTINUE } - override def onStatusReceived( - responseStatus: HttpResponseStatus): AsyncHandler.State = { + override def onStatusReceived(responseStatus: HttpResponseStatus): AsyncHandler.State = { builder.accumulate(responseStatus) State.CONTINUE } @@ -160,16 +136,13 @@ abstract class AsyncHttpClientBackend[R[_], S](asyncHttpClient: AsyncHttpClient, val readTimeout = r.options.readTimeout val rb = new RequestBuilder(r.method.m) .setUrl(r.uri.toString) - .setRequestTimeout( - if (readTimeout.isFinite()) readTimeout.toMillis.toInt else -1) + .setRequestTimeout(if (readTimeout.isFinite()) readTimeout.toMillis.toInt else -1) r.headers.foreach { case (k, v) => rb.setHeader(k, v) } setBody(r, r.body, rb) rb.build() } - private def setBody(r: Request[_, S], - body: RequestBody[S], - rb: RequestBuilder): Unit = { + private def setBody(r: Request[_, S], body: RequestBody[S], rb: RequestBuilder): Unit = { body match { case NoBody => // skip @@ -211,10 +184,7 @@ abstract class AsyncHttpClientBackend[R[_], S](asyncHttpClient: AsyncHttpClient, val bodyPart = mp.body match { case StringBody(b, encoding, _) => - new StringPart(nameWithFilename, - b, - mp.contentType.getOrElse(TextPlainContentType), - Charset.forName(encoding)) + new StringPart(nameWithFilename, b, mp.contentType.getOrElse(TextPlainContentType), Charset.forName(encoding)) case ByteArrayBody(b, _) => new ByteArrayPart(nameWithFilename, b) case ByteBufferBody(b, _) => @@ -227,15 +197,12 @@ abstract class AsyncHttpClientBackend[R[_], S](asyncHttpClient: AsyncHttpClient, 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) + bodyPart.setCustomHeaders(mp.additionalHeaders.map(h => new Param(h._1, h._2)).toList.asJava) rb.addBodyPart(bodyPart) } - private def readEagerResponse[T]( - response: AsyncResponse, - responseAs: ResponseAs[T, S]): R[Response[T]] = { + private def readEagerResponse[T](response: AsyncResponse, responseAs: ResponseAs[T, S]): R[Response[T]] = { val base = readResponseNoBody(response) val body = if (codeIsSuccess(base.code)) { @@ -280,9 +247,7 @@ abstract class AsyncHttpClientBackend[R[_], S](asyncHttpClient: AsyncHttpClient, Try(response.getResponseBodyAsBytes) case ResponseAsStream() => - Failure( - new IllegalStateException( - "Requested a streaming response, trying to read eagerly.")) + Failure(new IllegalStateException("Requested a streaming response, trying to read eagerly.")) case ResponseAsFile(file, overwrite) => Try( @@ -299,8 +264,7 @@ abstract class AsyncHttpClientBackend[R[_], S](asyncHttpClient: AsyncHttpClient, object AsyncHttpClientBackend { - private[asynchttpclient] def defaultClient( - options: SttpBackendOptions): AsyncHttpClient = { + private[asynchttpclient] def defaultClient(options: SttpBackendOptions): AsyncHttpClient = { var configBuilder = new DefaultAsyncHttpClientConfig.Builder() .setConnectTimeout(options.connectionTimeout.toMillis.toInt) @@ -308,8 +272,7 @@ object AsyncHttpClientBackend { configBuilder = options.proxy match { case None => configBuilder case Some(p) => - configBuilder.setProxyServer( - new ProxyServer.Builder(p.host, p.port).build()) + configBuilder.setProxyServer(new ProxyServer.Builder(p.host, p.port).build()) } new DefaultAsyncHttpClient(configBuilder.build()) diff --git a/core/src/main/scala/com/softwaremill/sttp/FollowRedirectsBackend.scala b/core/src/main/scala/com/softwaremill/sttp/FollowRedirectsBackend.scala index 942f792..96c0213 100644 --- a/core/src/main/scala/com/softwaremill/sttp/FollowRedirectsBackend.scala +++ b/core/src/main/scala/com/softwaremill/sttp/FollowRedirectsBackend.scala @@ -4,15 +4,13 @@ import java.net.URI import scala.language.higherKinds -class FollowRedirectsBackend[R[_], S](delegate: SttpBackend[R, S]) - extends SttpBackend[R, S] { +class FollowRedirectsBackend[R[_], S](delegate: SttpBackend[R, S]) extends SttpBackend[R, S] { def send[T](request: Request[T, S]): R[Response[T]] = { sendWithCounter(request, 0) } - private def sendWithCounter[T](request: Request[T, S], - redirects: Int): R[Response[T]] = { + private def sendWithCounter[T](request: Request[T, S], redirects: Int): R[Response[T]] = { // if there are nested follow redirect backends, disabling them and handling redirects here val resp = delegate.send(request.followRedirects(false)) if (request.options.followRedirects) { @@ -28,14 +26,11 @@ class FollowRedirectsBackend[R[_], S](delegate: SttpBackend[R, S]) } } - private def followRedirect[T](request: Request[T, S], - response: Response[T], - redirects: Int): R[Response[T]] = { + private def followRedirect[T](request: Request[T, S], response: Response[T], redirects: Int): R[Response[T]] = { response.header(LocationHeader).fold(responseMonad.unit(response)) { loc => if (redirects >= FollowRedirectsBackend.MaxRedirects) { - responseMonad.unit( - Response(Left("Too many redirects"), 0, "", Nil, Nil)) + responseMonad.unit(Response(Left("Too many redirects"), 0, "", Nil, Nil)) } else { followRedirect(request, response, redirects, loc) } diff --git a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala index 113ce48..4eca5dd 100644 --- a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala +++ b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala @@ -13,9 +13,7 @@ import scala.collection.JavaConverters._ import scala.concurrent.duration.Duration import scala.io.Source -class HttpURLConnectionBackend private ( - opts: SttpBackendOptions, - customizeConnection: HttpURLConnection => Unit) +class HttpURLConnectionBackend private (opts: SttpBackendOptions, customizeConnection: HttpURLConnection => Unit) extends SttpBackend[Id, Nothing] { override def send[T](r: Request[T, Nothing]): Response[T] = { @@ -66,8 +64,7 @@ class HttpURLConnectionBackend private ( conn.asInstanceOf[HttpURLConnection] } - private def writeBody(body: RequestBody[Nothing], - c: HttpURLConnection): Option[OutputStream] = { + private def writeBody(body: RequestBody[Nothing], c: HttpURLConnection): Option[OutputStream] = { body match { case NoBody => // skip @@ -118,8 +115,7 @@ class HttpURLConnectionBackend private ( private val BoundaryChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray - private def setMultipartBody(mp: MultipartBody, - c: HttpURLConnection): Option[OutputStream] = { + private def setMultipartBody(mp: MultipartBody, c: HttpURLConnection): Option[OutputStream] = { val boundary = { val tlr = ThreadLocalRandom.current() List @@ -160,16 +156,14 @@ class HttpURLConnectionBackend private ( val headersLen = headers.getBytes(Iso88591).length - bodyLen.map(bl => - dashesLen + boundaryLen + crLfLen + headersLen + crLfLen + crLfLen + bl + crLfLen) + bodyLen.map(bl => dashesLen + boundaryLen + crLfLen + headersLen + crLfLen + crLfLen + bl + crLfLen) } .foldLeft(Option(finalBoundaryLen)) { case (Some(acc), Some(l)) => Some(acc + l) case _ => None } - c.setRequestProperty(ContentTypeHeader, - "multipart/form-data; boundary=" + boundary) + c.setRequestProperty(ContentTypeHeader, "multipart/form-data; boundary=" + boundary) contentLength.foreach { cl => c.setFixedLengthStreamingMode(cl) @@ -205,10 +199,9 @@ class HttpURLConnectionBackend private ( Some(os) } - private def readResponse[T]( - c: HttpURLConnection, - is: InputStream, - responseAs: ResponseAs[T, Nothing]): Response[T] = { + private def readResponse[T](c: HttpURLConnection, + is: InputStream, + responseAs: ResponseAs[T, Nothing]): Response[T] = { val headers = c.getHeaderFields.asScala.toVector .filter(_._1 != null) @@ -229,9 +222,7 @@ class HttpURLConnectionBackend private ( Response(body, code, c.getResponseMessage, headers, Nil) } - private def readResponseBody[T](is: InputStream, - responseAs: ResponseAs[T, Nothing], - charset: Option[String]): T = { + private def readResponseBody[T](is: InputStream, responseAs: ResponseAs[T, Nothing], charset: Option[String]): T = { def asString(enc: String) = Source.fromInputStream(is, charset.getOrElse(enc)).mkString @@ -266,8 +257,7 @@ class HttpURLConnectionBackend private ( else is - private def wrapInput(contentEncoding: Option[String], - is: InputStream): InputStream = + private def wrapInput(contentEncoding: Option[String], is: InputStream): InputStream = contentEncoding.map(_.toLowerCase) match { case None => is case Some("gzip") => new GZIPInputStream(is) @@ -281,10 +271,9 @@ class HttpURLConnectionBackend private ( object HttpURLConnectionBackend { - def apply(options: SttpBackendOptions = SttpBackendOptions.Default, - customizeConnection: HttpURLConnection => Unit = { _ => - () - }): SttpBackend[Id, Nothing] = - new FollowRedirectsBackend[Id, Nothing]( - new HttpURLConnectionBackend(options, customizeConnection)) + def apply(options: SttpBackendOptions = SttpBackendOptions.Default, customizeConnection: HttpURLConnection => Unit = { + _ => + () + }): SttpBackend[Id, Nothing] = + new FollowRedirectsBackend[Id, Nothing](new HttpURLConnectionBackend(options, customizeConnection)) } diff --git a/core/src/main/scala/com/softwaremill/sttp/MonadError.scala b/core/src/main/scala/com/softwaremill/sttp/MonadError.scala index 5751382..a783765 100644 --- a/core/src/main/scala/com/softwaremill/sttp/MonadError.scala +++ b/core/src/main/scala/com/softwaremill/sttp/MonadError.scala @@ -10,8 +10,7 @@ trait MonadError[R[_]] { def flatMap[T, T2](fa: R[T])(f: T => R[T2]): R[T2] def error[T](t: Throwable): R[T] - protected def handleWrappedError[T](rt: R[T])( - h: PartialFunction[Throwable, R[T]]): R[T] + protected def handleWrappedError[T](rt: R[T])(h: PartialFunction[Throwable, R[T]]): R[T] def handleError[T](rt: => R[T])(h: PartialFunction[Throwable, R[T]]): R[T] = { Try(rt) match { case Success(v) => handleWrappedError(v)(h) @@ -38,8 +37,7 @@ object IdMonad extends MonadError[Id] { override def flatMap[T, T2](fa: Id[T])(f: (T) => Id[T2]): Id[T2] = f(fa) override def error[T](t: Throwable): Id[T] = throw t - override protected def handleWrappedError[T](rt: Id[T])( - h: PartialFunction[Throwable, Id[T]]): Id[T] = rt + override protected def handleWrappedError[T](rt: Id[T])(h: PartialFunction[Throwable, Id[T]]): Id[T] = rt } object TryMonad extends MonadError[Try] { override def unit[T](t: T): Try[T] = Success(t) @@ -48,11 +46,10 @@ object TryMonad extends MonadError[Try] { fa.flatMap(f) override def error[T](t: Throwable): Try[T] = Failure(t) - override protected def handleWrappedError[T](rt: Try[T])( - h: PartialFunction[Throwable, Try[T]]): Try[T] = rt.recoverWith(h) + override protected def handleWrappedError[T](rt: Try[T])(h: PartialFunction[Throwable, Try[T]]): Try[T] = + rt.recoverWith(h) } -class FutureMonad(implicit ec: ExecutionContext) - extends MonadAsyncError[Future] { +class FutureMonad(implicit ec: ExecutionContext) extends MonadAsyncError[Future] { override def unit[T](t: T): Future[T] = Future.successful(t) override def map[T, T2](fa: Future[T])(f: (T) => T2): Future[T2] = fa.map(f) @@ -60,11 +57,10 @@ class FutureMonad(implicit ec: ExecutionContext) fa.flatMap(f) override def error[T](t: Throwable): Future[T] = Future.failed(t) - override protected def handleWrappedError[T](rt: Future[T])( - h: PartialFunction[Throwable, Future[T]]): Future[T] = rt.recoverWith(h) + override protected def handleWrappedError[T](rt: Future[T])(h: PartialFunction[Throwable, Future[T]]): Future[T] = + rt.recoverWith(h) - override def async[T]( - register: ((Either[Throwable, T]) => Unit) => Unit): Future[T] = { + override def async[T](register: ((Either[Throwable, T]) => Unit) => Unit): Future[T] = { val p = Promise[T]() register { case Left(t) => p.failure(t) diff --git a/core/src/main/scala/com/softwaremill/sttp/RequestBody.scala b/core/src/main/scala/com/softwaremill/sttp/RequestBody.scala index a8be76b..a95a38b 100644 --- a/core/src/main/scala/com/softwaremill/sttp/RequestBody.scala +++ b/core/src/main/scala/com/softwaremill/sttp/RequestBody.scala @@ -45,8 +45,7 @@ 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 = { + private[sttp] def paramsToStringBody(fs: Seq[(String, String)], encoding: String): StringBody = { val b = fs .map { diff --git a/core/src/main/scala/com/softwaremill/sttp/RequestT.scala b/core/src/main/scala/com/softwaremill/sttp/RequestT.scala index 320efef..26eb0f1 100644 --- a/core/src/main/scala/com/softwaremill/sttp/RequestT.scala +++ b/core/src/main/scala/com/softwaremill/sttp/RequestT.scala @@ -55,14 +55,10 @@ case class RequestT[U[_], T, +S]( def contentType(ct: String): RequestT[U, T, S] = header(ContentTypeHeader, ct, replaceExisting = true) def contentType(ct: String, encoding: String): RequestT[U, T, S] = - header(ContentTypeHeader, - contentTypeWithEncoding(ct, encoding), - replaceExisting = true) + 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] = { + def header(k: String, v: String, replaceExisting: Boolean = false): RequestT[U, T, S] = { val current = if (replaceExisting) headers.filterNot(_._1.equalsIgnoreCase(k)) @@ -233,8 +229,7 @@ case class RequestT[U[_], T, +S]( def tag(k: String): Option[Any] = tags.get(k) - def send[R[_]]()(implicit backend: SttpBackend[R, S], - isIdInRequest: IsIdInRequest[U]): R[Response[T]] = { + def send[R[_]]()(implicit backend: SttpBackend[R, S], isIdInRequest: IsIdInRequest[U]): R[Response[T]] = { // we could avoid the asInstanceOf by creating an artificial copy // changing the method & url fields using `isIdInRequest`, but that // would be only to satisfy the type checker, and a needless copy at @@ -263,8 +258,7 @@ case class RequestT[U[_], T, +S]( 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] = { + private def formDataBody(fs: Seq[(String, String)], encoding: String): RequestT[U, T, S] = { val b = RequestBody.paramsToStringBody(fs, encoding) setContentTypeIfMissing(ApplicationFormContentType) .setContentLengthIfMissing(b.s.getBytes(encoding).length) @@ -274,9 +268,7 @@ case class RequestT[U[_], T, +S]( class SpecifyAuthScheme[U[_], T, +S](hn: String, rt: RequestT[U, T, S]) { def basic(user: String, password: String): RequestT[U, T, S] = { - val c = new String( - Base64.getEncoder.encode(s"$user:$password".getBytes(Utf8)), - Utf8) + val c = new String(Base64.getEncoder.encode(s"$user:$password".getBytes(Utf8)), Utf8) rt.header(hn, s"Basic $c") } diff --git a/core/src/main/scala/com/softwaremill/sttp/Response.scala b/core/src/main/scala/com/softwaremill/sttp/Response.scala index e38ae4a..5762845 100644 --- a/core/src/main/scala/com/softwaremill/sttp/Response.scala +++ b/core/src/main/scala/com/softwaremill/sttp/Response.scala @@ -105,8 +105,7 @@ object Cookie { * Modified version of `HttpCookie.expiryDate2DeltaSeconds` to return a * `ZonedDateTime`, not a second-delta. */ - private def expiryDate2ZonedDateTime( - dateString: String): Option[ZonedDateTime] = { + private def expiryDate2ZonedDateTime(dateString: String): Option[ZonedDateTime] = { val cal = new GregorianCalendar(Gmt) CookieDateFormats.foreach { format => val df = new SimpleDateFormat(format, Locale.US) diff --git a/core/src/main/scala/com/softwaremill/sttp/ResponseAs.scala b/core/src/main/scala/com/softwaremill/sttp/ResponseAs.scala index 2bf4c35..2916043 100644 --- a/core/src/main/scala/com/softwaremill/sttp/ResponseAs.scala +++ b/core/src/main/scala/com/softwaremill/sttp/ResponseAs.scala @@ -25,44 +25,35 @@ sealed trait BasicResponseAs[T, +S] extends ResponseAs[T, S] { } case object IgnoreResponse extends BasicResponseAs[Unit, Nothing] -case class ResponseAsString(encoding: String) - extends BasicResponseAs[String, Nothing] +case class ResponseAsString(encoding: String) extends BasicResponseAs[String, Nothing] case object ResponseAsByteArray extends BasicResponseAs[Array[Byte], Nothing] -case class ResponseAsStream[T, S]()(implicit val responseIsStream: S =:= T) - extends BasicResponseAs[T, S] +case class ResponseAsStream[T, S]()(implicit val responseIsStream: S =:= T) extends BasicResponseAs[T, S] -case class MappedResponseAs[T, T2, S](raw: BasicResponseAs[T, S], g: T => T2) - extends ResponseAs[T2, S] { +case class MappedResponseAs[T, T2, S](raw: BasicResponseAs[T, S], g: T => T2) extends ResponseAs[T2, S] { override def map[T3](f: T2 => T3): ResponseAs[T3, S] = MappedResponseAs[T, T3, S](raw, g andThen f) } -case class ResponseAsFile(output: File, overwrite: Boolean) - extends BasicResponseAs[File, Nothing] +case class ResponseAsFile(output: File, overwrite: Boolean) extends BasicResponseAs[File, Nothing] object ResponseAs { - private[sttp] def parseParams(s: String, - encoding: String): Seq[(String, String)] = { + private[sttp] def parseParams(s: String, encoding: String): Seq[(String, String)] = { s.split("&") .toList .flatMap(kv => kv.split("=", 2) match { case Array(k, v) => - Some( - (URLDecoder.decode(k, encoding), URLDecoder.decode(v, encoding))) + Some((URLDecoder.decode(k, encoding), URLDecoder.decode(v, encoding))) case _ => None }) } - private[sttp] def saveFile(file: File, - is: InputStream, - overwrite: Boolean): File = { + private[sttp] def saveFile(file: File, is: InputStream, overwrite: Boolean): File = { if (!file.exists()) { file.getParentFile.mkdirs() file.createNewFile() } else if (!overwrite) { - throw new IOException( - s"File ${file.getAbsolutePath} exists - overwriting prohibited") + throw new IOException(s"File ${file.getAbsolutePath} exists - overwriting prohibited") } val os = new FileOutputStream(file) @@ -80,8 +71,7 @@ object ResponseAs { private[sttp] trait EagerResponseHandler[S] { def handleBasic[T](bra: BasicResponseAs[T, S]): Try[T] - def handle[T, R[_]](responseAs: ResponseAs[T, S], - responseMonad: MonadError[R]): R[T] = { + def handle[T, R[_]](responseAs: ResponseAs[T, S], responseMonad: MonadError[R]): R[T] = { responseAs match { case mra @ MappedResponseAs(raw, g) => diff --git a/core/src/main/scala/com/softwaremill/sttp/SttpBackendOptions.scala b/core/src/main/scala/com/softwaremill/sttp/SttpBackendOptions.scala index 026d4d0..89fb542 100644 --- a/core/src/main/scala/com/softwaremill/sttp/SttpBackendOptions.scala +++ b/core/src/main/scala/com/softwaremill/sttp/SttpBackendOptions.scala @@ -56,10 +56,7 @@ object SttpBackendOptions { Empty.socksProxy(host, port) private def loadSystemProxy: Option[Proxy] = { - def system(hostProp: String, - portProp: String, - make: (String, Int) => Proxy, - defaultPort: Int) = { + def system(hostProp: String, portProp: String, make: (String, Int) => Proxy, defaultPort: Int) = { val host = Option(System.getProperty(hostProp)) def port = Try(System.getProperty(portProp).toInt).getOrElse(defaultPort) host.map(make(_, port)) diff --git a/core/src/main/scala/com/softwaremill/sttp/TryBackend.scala b/core/src/main/scala/com/softwaremill/sttp/TryBackend.scala index 58e9548..9e56aef 100644 --- a/core/src/main/scala/com/softwaremill/sttp/TryBackend.scala +++ b/core/src/main/scala/com/softwaremill/sttp/TryBackend.scala @@ -21,8 +21,6 @@ class TryBackend[-S](delegate: SttpBackend[Id, S]) extends SttpBackend[Try, S] { object TryHttpURLConnectionBackend { def apply(options: SttpBackendOptions = SttpBackendOptions.Default, - customizeConnection: HttpURLConnection => Unit = _ => ()) - : SttpBackend[Try, Nothing] = - new TryBackend[Nothing]( - HttpURLConnectionBackend(options, customizeConnection)) + customizeConnection: HttpURLConnection => Unit = _ => ()): SttpBackend[Try, Nothing] = + new TryBackend[Nothing](HttpURLConnectionBackend(options, customizeConnection)) } diff --git a/core/src/main/scala/com/softwaremill/sttp/Uri.scala b/core/src/main/scala/com/softwaremill/sttp/Uri.scala index 16936cc..7ae0013 100644 --- a/core/src/main/scala/com/softwaremill/sttp/Uri.scala +++ b/core/src/main/scala/com/softwaremill/sttp/Uri.scala @@ -96,30 +96,26 @@ case class Uri(scheme: String, override def toString: String = { def encodeUserInfo(ui: UserInfo): String = - encode(Rfc3986.UserInfo)(ui.username) + ui.password.fold("")( - ":" + encode(Rfc3986.UserInfo)(_)) + encode(Rfc3986.UserInfo)(ui.username) + ui.password.fold("")(":" + encode(Rfc3986.UserInfo)(_)) @tailrec - def encodeQueryFragments(qfs: List[QueryFragment], - previousWasPlain: Boolean, - sb: StringBuilder): String = qfs match { - case Nil => sb.toString() - - case Plain(v, re) :: t => - encodeQueryFragments(t, - previousWasPlain = true, - sb.append(encodeQuery(v, re))) - - case Value(v, re) :: t => - if (!previousWasPlain) sb.append("&") - sb.append(encodeQuery(v, re)) - encodeQueryFragments(t, previousWasPlain = false, sb) - - case KeyValue(k, v, reK, reV) :: t => - if (!previousWasPlain) sb.append("&") - sb.append(encodeQuery(k, reK)).append("=").append(encodeQuery(v, reV)) - encodeQueryFragments(t, previousWasPlain = false, sb) - } + def encodeQueryFragments(qfs: List[QueryFragment], previousWasPlain: Boolean, sb: StringBuilder): String = + qfs match { + case Nil => sb.toString() + + case Plain(v, re) :: t => + encodeQueryFragments(t, previousWasPlain = true, sb.append(encodeQuery(v, re))) + + case Value(v, re) :: t => + if (!previousWasPlain) sb.append("&") + sb.append(encodeQuery(v, re)) + encodeQueryFragments(t, previousWasPlain = false, sb) + + case KeyValue(k, v, reK, reV) :: t => + if (!previousWasPlain) sb.append("&") + sb.append(encodeQuery(k, reK)).append("=").append(encodeQuery(v, reV)) + encodeQueryFragments(t, previousWasPlain = false, sb) + } val schemeS = encode(Rfc3986.Scheme)(scheme) val userInfoS = userInfo.fold("")(encodeUserInfo(_) + "@") @@ -129,9 +125,7 @@ case class Uri(scheme: String, val pathS = path.map(encode(Rfc3986.PathSegment)).mkString("/") val queryPrefixS = if (queryFragments.isEmpty) "" else "?" - val queryS = encodeQueryFragments(queryFragments.toList, - previousWasPlain = true, - new StringBuilder()) + val queryS = encodeQueryFragments(queryFragments.toList, previousWasPlain = true, new StringBuilder()) // https://stackoverflow.com/questions/2053132/is-a-colon-safe-for-friendly-url-use/2053640#2053640 val fragS = fragment.fold("")("#" + encode(Rfc3986.Fragment)(_)) @@ -143,9 +137,7 @@ case class Uri(scheme: String, e match { case QueryFragmentEncoding.All => URLEncoder.encode(s, "UTF-8") case QueryFragmentEncoding.Standard => - encode(Rfc3986.QueryNoStandardDelims, - spaceAsPlus = true, - encodePlus = true)(s) + encode(Rfc3986.QueryNoStandardDelims, spaceAsPlus = true, encodePlus = true)(s) case QueryFragmentEncoding.Relaxed => encode(Rfc3986.Query, spaceAsPlus = true)(s) } @@ -182,9 +174,8 @@ case class Uri(scheme: String, * @param encodePlus Should `+` (which is the encoded form of space * in the query) be %-encoded. */ - private def encode(allowedCharacters: Set[Char], - spaceAsPlus: Boolean = false, - encodePlus: Boolean = false)(s: String): String = { + private def encode(allowedCharacters: Set[Char], spaceAsPlus: Boolean = false, encodePlus: Boolean = false)( + s: String): String = { val sb = new StringBuilder() // based on https://gist.github.com/teigen/5865923 for (c <- s) { @@ -226,19 +217,16 @@ object Uri { * @param keyEncoding See [[Plain.encoding]] * @param valueEncoding See [[Plain.encoding]] */ - case class KeyValue( - k: String, - v: String, - keyEncoding: QueryFragmentEncoding = QueryFragmentEncoding.Standard, - valueEncoding: QueryFragmentEncoding = QueryFragmentEncoding.Standard) + case class KeyValue(k: String, + v: String, + keyEncoding: QueryFragmentEncoding = QueryFragmentEncoding.Standard, + valueEncoding: QueryFragmentEncoding = QueryFragmentEncoding.Standard) extends QueryFragment /** * A query fragment which contains only the value, without a key. */ - case class Value(v: String, - relaxedEncoding: QueryFragmentEncoding = - QueryFragmentEncoding.Standard) + case class Value(v: String, relaxedEncoding: QueryFragmentEncoding = QueryFragmentEncoding.Standard) extends QueryFragment /** @@ -256,10 +244,7 @@ object Uri { * [[https://stackoverflow.com/questions/2322764/what-characters-must-be-escaped-in-an-http-query-string]] * [[https://stackoverflow.com/questions/2366260/whats-valid-and-whats-not-in-a-uri-query]] */ - case class Plain(v: String, - encoding: QueryFragmentEncoding = - QueryFragmentEncoding.Standard) - extends QueryFragment + case class Plain(v: String, encoding: QueryFragmentEncoding = QueryFragmentEncoding.Standard) extends QueryFragment } sealed trait QueryFragmentEncoding diff --git a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala index 8d0024a..be3edb6 100644 --- a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala +++ b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala @@ -27,8 +27,7 @@ object UriInterpolator { } if (leftTokens.nonEmpty) { - throw new IllegalStateException( - s"Tokens left after building the whole uri: $leftTokens, result so far: $uri") + throw new IllegalStateException(s"Tokens left after building the whole uri: $leftTokens, result so far: $uri") } uri @@ -50,8 +49,7 @@ object UriInterpolator { // way it's possible to extend existing URIs. Without special-casing // the embedded URI would be escaped and become part of the host // as a whole. - if (tokens == Vector(StringToken("")) && nextExpressionStr.contains( - "://")) { + if (tokens == Vector(StringToken("")) && nextExpressionStr.contains("://")) { def tokenizeExpressionAsString(): Unit = { val (nextTokenizer, nextTokens) = tokenizer.tokenize(nextExpression.toString) @@ -145,9 +143,7 @@ object UriInterpolator { s, this, Set('/', '?', '#'), - Map(':' -> ColonInAuthority, - '@' -> AtInAuthority, - '.' -> DotInAuthority), + Map(':' -> ColonInAuthority, '@' -> AtInAuthority, '.' -> DotInAuthority), ipv6parser ) } @@ -193,8 +189,7 @@ object UriInterpolator { current: Tokenizer, terminators: Set[Char], separatorsToTokens: Map[Char, Token], - extraFragmentParser: String => Option[Vector[Token]] = _ => None) - : (Tokenizer, Vector[Token]) = { + extraFragmentParser: String => Option[Vector[Token]] = _ => None): (Tokenizer, Vector[Token]) = { def tokenizeFragment(f: String): Vector[Token] = { extraFragmentParser(f) match { @@ -222,26 +217,23 @@ object UriInterpolator { } } - private def tokenizeAfterSeparator( - beforeSeparatorTokens: Vector[Token], - separator: Char, - s: String): (Tokenizer, Vector[Token]) = { + private def tokenizeAfterSeparator(beforeSeparatorTokens: Vector[Token], + separator: Char, + s: String): (Tokenizer, Vector[Token]) = { val (next, separatorToken) = separatorTokenizerAndToken(separator) val (nextNext, nextTokens) = next.tokenize(s) (nextNext, beforeSeparatorTokens ++ Vector(separatorToken) ++ nextTokens) } - private def separatorTokenizerAndToken( - separator: Char): (Tokenizer, Token) = + private def separatorTokenizerAndToken(separator: Char): (Tokenizer, Token) = separator match { case '/' => (Path, PathStart) case '?' => (Query, QueryStart) case '#' => (Fragment, FragmentStart) } - private def splitPreserveSeparators(s: String, - sep: Set[Char]): Vector[String] = { + private def splitPreserveSeparators(s: String, sep: Set[Char]): Vector[String] = { @tailrec def doSplit(s: String, acc: Vector[String]): Vector[String] = { split(s, sep) match { @@ -254,9 +246,7 @@ object UriInterpolator { doSplit(s, Vector.empty) } - private def split( - s: String, - sep: Set[Char]): Either[String, (String, Char, String)] = { + private def split(s: String, sep: Set[Char]): Either[String, (String, Char, String)] = { val i = s.indexWhere(sep.contains) if (i == -1) Left(s) else Right((s.substring(0, i), s.charAt(i), s.substring(i + 1))) @@ -270,8 +260,7 @@ object UriInterpolator { object UriBuilder { case object Scheme extends UriBuilder { - override def fromTokens(u: Uri, - t: Vector[Token]): (Uri, Vector[Token]) = { + override def fromTokens(u: Uri, t: Vector[Token]): (Uri, Vector[Token]) = { split(t, Set[Token](SchemeEnd)) match { case Left(tt) => (u.scheme("http"), tt) case Right((schemeTokens, _, otherTokens)) => @@ -282,8 +271,7 @@ object UriInterpolator { } case object UserInfo extends UriBuilder { - override def fromTokens(u: Uri, - t: Vector[Token]): (Uri, Vector[Token]) = { + override def fromTokens(u: Uri, t: Vector[Token]): (Uri, Vector[Token]) = { split(t, Set[Token](AtInAuthority)) match { case Left(tt) => (u, tt) case Right((uiTokens, _, otherTokens)) => @@ -303,9 +291,7 @@ object UriInterpolator { } } - private def uiFromTokens(u: Uri, - usernameTokens: Vector[Token], - passwordTokens: Vector[Token]): Uri = { + private def uiFromTokens(u: Uri, usernameTokens: Vector[Token], passwordTokens: Vector[Token]): Uri = { (tokensToStringOpt(usernameTokens), tokensToStringOpt(passwordTokens)) match { case (Some(un), Some(p)) => u.userInfo(un, p) @@ -317,8 +303,7 @@ object UriInterpolator { } case object HostPort extends UriBuilder { - override def fromTokens(u: Uri, - t: Vector[Token]): (Uri, Vector[Token]) = { + override def fromTokens(u: Uri, t: Vector[Token]): (Uri, Vector[Token]) = { split(t, Set[Token](PathStart, QueryStart, FragmentStart)) match { case Left(tt) => (hostPortFromTokens(u, tt), Vector.empty) @@ -327,8 +312,7 @@ object UriInterpolator { } } - private def hostPortFromTokens(u: Uri, - rawHpTokens: Vector[Token]): Uri = { + private def hostPortFromTokens(u: Uri, rawHpTokens: Vector[Token]): Uri = { // Special case: if the host/port part contains an expression token, // which has a string representation which contains a colon (:), then // we assume that the intention was to embed the port and host separately, @@ -367,11 +351,7 @@ object UriInterpolator { case object Path extends UriBuilder { override def fromTokens(u: Uri, t: Vector[Token]): (Uri, Vector[Token]) = - fromStartingToken(u, - t, - PathStart, - Set[Token](QueryStart, FragmentStart), - pathFromTokens) + fromStartingToken(u, t, PathStart, Set[Token](QueryStart, FragmentStart), pathFromTokens) private def pathFromTokens(u: Uri, tokens: Vector[Token]): Uri = { u.path(tokensToStringSeq(tokens)) @@ -383,11 +363,7 @@ object UriInterpolator { import com.softwaremill.sttp.Uri.{QueryFragment => QF} override def fromTokens(u: Uri, t: Vector[Token]): (Uri, Vector[Token]) = - fromStartingToken(u, - t, - QueryStart, - Set[Token](FragmentStart), - queryFromTokens) + fromStartingToken(u, t, QueryStart, Set[Token](FragmentStart), queryFromTokens) private def queryFromTokens(u: Uri, tokens: Vector[Token]): Uri = { val qfs = @@ -398,8 +374,7 @@ object UriInterpolator { } private def queryMappingsFromTokens(tokens: Vector[Token]): Vector[QF] = { - def expressionPairToQueryFragment(ke: Any, - ve: Any): Option[QF.KeyValue] = + def expressionPairToQueryFragment(ke: Any, ve: Any): Option[QF.KeyValue] = for { k <- anyToStringOpt(ke) v <- anyToStringOpt(ve) @@ -431,8 +406,7 @@ object UriInterpolator { } case object Fragment extends UriBuilder { - override def fromTokens(u: Uri, - t: Vector[Token]): (Uri, Vector[Token]) = { + override def fromTokens(u: Uri, t: Vector[Token]): (Uri, Vector[Token]) = { t match { case FragmentStart +: tt => (u.fragment(tokensToStringOpt(tt)), Vector.empty) @@ -449,13 +423,11 @@ object UriInterpolator { * * The component is terminated by any of `nextComponentTokens`. */ - private def fromStartingToken( - u: Uri, - t: Vector[Token], - startingToken: Token, - nextComponentTokens: Set[Token], - componentFromTokens: (Uri, Vector[Token]) => Uri) - : (Uri, Vector[Token]) = { + private def fromStartingToken(u: Uri, + t: Vector[Token], + startingToken: Token, + nextComponentTokens: Set[Token], + componentFromTokens: (Uri, Vector[Token]) => Uri): (Uri, Vector[Token]) = { t match { case `startingToken` +: tt => @@ -536,9 +508,7 @@ object UriInterpolator { } .mkString("") - private def split[T]( - v: Vector[T], - sep: Set[T]): Either[Vector[T], (Vector[T], T, Vector[T])] = { + private def split[T](v: Vector[T], sep: Set[T]): Either[Vector[T], (Vector[T], T, Vector[T])] = { val i = v.indexWhere(sep.contains) if (i == -1) Left(v) else Right((v.take(i), v(i), v.drop(i + 1))) } @@ -567,8 +537,7 @@ object UriInterpolator { * These empty string tokens need to be removed so that e.g. extra key-value * mappings are not generated. */ - private def removeEmptyTokensAroundExp( - tokens: Vector[Token]): Vector[Token] = { + private def removeEmptyTokensAroundExp(tokens: Vector[Token]): Vector[Token] = { def doRemove(t: Vector[Token], acc: Vector[Token]): Vector[Token] = t match { case StringToken("") +: (e: ExpressionToken) +: tail => diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala index f47e113..8bd6a4b 100644 --- a/core/src/main/scala/com/softwaremill/sttp/package.scala +++ b/core/src/main/scala/com/softwaremill/sttp/package.scala @@ -59,14 +59,13 @@ package object sttp { * An empty request with no headers. */ val emptyRequest: RequestT[Empty, String, Nothing] = - RequestT[Empty, String, Nothing]( - None, - None, - NoBody, - Vector(), - asString, - RequestOptions(followRedirects = true, readTimeout = DefaultReadTimeout), - Map()) + RequestT[Empty, String, Nothing](None, + None, + NoBody, + Vector(), + asString, + RequestOptions(followRedirects = true, readTimeout = DefaultReadTimeout), + Map()) /** * A starting request, with the following modifications comparing to @@ -109,12 +108,10 @@ package object sttp { def asStream[S]: ResponseAs[S, S] = ResponseAsStream[S, S]() - def asFile(file: File, - overwrite: Boolean = false): ResponseAs[File, Nothing] = + def asFile(file: File, overwrite: Boolean = false): ResponseAs[File, Nothing] = ResponseAsFile(file, overwrite) - def asPath(path: Path, - overwrite: Boolean = false): ResponseAs[Path, Nothing] = + def asPath(path: Path, overwrite: Boolean = false): ResponseAs[Path, Nothing] = ResponseAsFile(path.toFile, overwrite).map(_.toPath) // multipart factory methods @@ -124,47 +121,35 @@ package object sttp { * 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 @@ -194,9 +179,7 @@ package object sttp { * 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)) + Multipart(name, RequestBody.paramsToStringBody(fs.toList, Utf8), contentType = Some(ApplicationFormContentType)) /** * Encodes the given parameters as form data. @@ -204,12 +187,8 @@ package object sttp { * 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)) + 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`. @@ -218,9 +197,7 @@ package object sttp { * overridden later using the `contentType` method. */ def multipart(name: String, fs: Seq[(String, String)]): Multipart = - Multipart(name, - RequestBody.paramsToStringBody(fs, Utf8), - contentType = Some(ApplicationFormContentType)) + Multipart(name, RequestBody.paramsToStringBody(fs, Utf8), contentType = Some(ApplicationFormContentType)) /** * Encodes the given parameters as form data. @@ -228,21 +205,15 @@ package object sttp { * 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)) + 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)) + Multipart(name, implicitly[BodySerializer[B]].apply(b), contentType = Some(ApplicationOctetStreamContentType)) // util @@ -278,8 +249,7 @@ package object sttp { private[sttp] def codeIsSuccess(c: Int): Boolean = c >= 200 && c < 300 - private[sttp] def concatByteBuffers(bb1: ByteBuffer, - bb2: ByteBuffer): ByteBuffer = + private[sttp] def concatByteBuffers(bb1: ByteBuffer, bb2: ByteBuffer): ByteBuffer = ByteBuffer .allocate(bb1.array().length + bb2.array().length) .put(bb1) diff --git a/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala b/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala index 36df795..d7d1034 100644 --- a/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala +++ b/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala @@ -26,10 +26,9 @@ import scala.util.{Failure, Success, Try} * or headers. A [[ClassCastException]] might occur if for a given request, * a response is specified with the incorrect or inconvertible body type. */ -class SttpBackendStub[R[_], S] private ( - rm: MonadError[R], - matchers: PartialFunction[Request[_, _], R[Response[_]]], - fallback: Option[SttpBackend[R, S]]) +class SttpBackendStub[R[_], S] private (rm: MonadError[R], + matchers: PartialFunction[Request[_, _], R[Response[_]]], + fallback: Option[SttpBackend[R, S]]) extends SttpBackend[R, S] { /** @@ -57,9 +56,7 @@ class SttpBackendStub[R[_], S] private ( * Note that the stubs are immutable, and each new * specification that is added yields a new stub instance. */ - def whenRequestMatchesPartial( - partial: PartialFunction[Request[_, _], Response[_]]) - : SttpBackendStub[R, S] = { + def whenRequestMatchesPartial(partial: PartialFunction[Request[_, _], Response[_]]): SttpBackendStub[R, S] = { val wrappedPartial = partial.andThen(rm.unit) new SttpBackendStub(rm, matchers.orElse(wrappedPartial), fallback) } @@ -67,18 +64,11 @@ class SttpBackendStub[R[_], S] private ( override def send[T](request: Request[T, S]): R[Response[T]] = { Try(matchers.lift(request)) match { case Success(Some(response)) => - tryAdjustResponseType(rm, - request.response, - response.asInstanceOf[R[Response[T]]]) + tryAdjustResponseType(rm, request.response, response.asInstanceOf[R[Response[T]]]) case Success(None) => fallback match { case None => - wrapResponse( - Response[Nothing](Left("Not Found: " + request.uri), - 404, - "Not Found", - Nil, - Nil)) + wrapResponse(Response[Nothing](Left("Not Found: " + request.uri), 404, "Not Found", Nil, Nil)) case Some(fb) => fb.send(request) } case Failure(e) => rm.error(e) @@ -99,8 +89,7 @@ class SttpBackendStub[R[_], S] private ( thenRespondWithCode(404, "Not found") def thenRespondServerError(): SttpBackendStub[R, S] = thenRespondWithCode(500, "Internal server error") - def thenRespondWithCode(code: Int, - msg: String = ""): SttpBackendStub[R, S] = { + def thenRespondWithCode(code: Int, msg: String = ""): SttpBackendStub[R, S] = { val body = if (code >= 200 && code < 300) Right(msg) else Left(msg) thenRespond(Response(body, code, msg, Nil, Nil)) } @@ -136,9 +125,7 @@ object SttpBackendStub { */ def asynchronousFuture: SttpBackendStub[Future, Nothing] = { import scala.concurrent.ExecutionContext.Implicits.global - new SttpBackendStub[Future, Nothing](new FutureMonad(), - PartialFunction.empty, - None) + new SttpBackendStub[Future, Nothing](new FutureMonad(), PartialFunction.empty, None) } /** @@ -162,11 +149,8 @@ object SttpBackendStub { * Create a stub backend which delegates send requests to the given fallback * backend, if the request doesn't match any of the specified predicates. */ - def withFallback[R[_], S, S2 <: S]( - fallback: SttpBackend[R, S]): SttpBackendStub[R, S2] = - new SttpBackendStub[R, S2](fallback.responseMonad, - PartialFunction.empty, - Some(fallback)) + def withFallback[R[_], S, S2 <: S](fallback: SttpBackend[R, S]): SttpBackendStub[R, S2] = + new SttpBackendStub[R, S2](fallback.responseMonad, PartialFunction.empty, Some(fallback)) private[sttp] def tryAdjustResponseType[DesiredRType, RType, M[_]]( rm: MonadError[M], @@ -177,15 +161,12 @@ object SttpBackendStub { case Left(_) => r.asInstanceOf[Response[DesiredRType]] case Right(body) => val newBody: Any = tryAdjustResponseBody(ra, body).getOrElse(body) - r.copy( - body = - Right[String, DesiredRType](newBody.asInstanceOf[DesiredRType])) + r.copy(body = Right[String, DesiredRType](newBody.asInstanceOf[DesiredRType])) } } } - private[sttp] def tryAdjustResponseBody[T, U](ra: ResponseAs[T, _], - b: U): Option[T] = { + private[sttp] def tryAdjustResponseBody[T, U](ra: ResponseAs[T, _], b: U): Option[T] = { ra match { case IgnoreResponse => Some(()) case ResponseAsString(enc) => diff --git a/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala b/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala index 5fc9d50..828fdb2 100644 --- a/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala +++ b/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala @@ -31,11 +31,7 @@ class RequestTests extends FlatSpec with Matchers { it should "set cookies from a response" in { val response = - Response(Right(()), - 0, - "", - List((SetCookieHeader, "k1=v1"), (SetCookieHeader, "k2=v2")), - Nil) + Response(Right(()), 0, "", List((SetCookieHeader, "k1=v1"), (SetCookieHeader, "k2=v2")), Nil) sttp .cookies(response) .headers diff --git a/core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala b/core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala index e417233..69290b0 100644 --- a/core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala +++ b/core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala @@ -22,14 +22,11 @@ class UriInterpolatorTests extends FunSuite with Matchers { (uri"http://example.com?x=y", "http://example.com?x=y"), (uri"http://example.com/a/b/c", "http://example.com/a/b/c"), (uri"http://example.com/a/b/c/", "http://example.com/a/b/c/"), - (uri"http://example.com/a/b/c?x=y&h=j", - "http://example.com/a/b/c?x=y&h=j") + (uri"http://example.com/a/b/c?x=y&h=j", "http://example.com/a/b/c?x=y&h=j") ), "scheme" -> List( - (uri"http${if (secure) "s" else ""}://example.com", - s"https://example.com"), - (uri"${if (secure) "https" else "http"}://example.com", - s"https://example.com"), + (uri"http${if (secure) "s" else ""}://example.com", s"https://example.com"), + (uri"${if (secure) "https" else "http"}://example.com", s"https://example.com"), (uri"example.com?a=$v2", s"http://example.com?a=$v2queryEncoded") ), "user info" -> List( @@ -47,10 +44,8 @@ class UriInterpolatorTests extends FunSuite with Matchers { (uri"http://$None.example.com", s"http://example.com"), (uri"http://$None.$None.example.com", s"http://example.com"), (uri"http://${Some("sub")}.example.com", s"http://sub.example.com"), - (uri"http://${Some("sub1.sub2")}.example.com", - s"http://sub1.sub2.example.com"), - (uri"http://${List("sub1", "sub2")}.example.com", - s"http://sub1.sub2.example.com"), + (uri"http://${Some("sub1.sub2")}.example.com", s"http://sub1.sub2.example.com"), + (uri"http://${List("sub1", "sub2")}.example.com", s"http://sub1.sub2.example.com"), (uri"http://${List("sub", "example", "com")}", s"http://sub.example.com") ), "authority with parameters" -> List( @@ -78,18 +73,13 @@ class UriInterpolatorTests extends FunSuite with Matchers { (uri"http://example.com/$v1/", s"http://example.com/$v1/"), (uri"http://example.com/$v2", s"http://example.com/$v2encoded"), (uri"http://example.com/$v2/$v1", s"http://example.com/$v2encoded/$v1"), - (uri"http://example.com/$v1/p/$v4", - s"http://example.com/$v1/p/$v4encoded"), - (uri"http://example.com/a/${List(v2, "c", v4)}/b", - s"http://example.com/a/$v2encoded/c/$v4encoded/b"), - (uri"http://example.com/${"a/b/c".split('/')}", - s"http://example.com/a/b/c") + (uri"http://example.com/$v1/p/$v4", s"http://example.com/$v1/p/$v4encoded"), + (uri"http://example.com/a/${List(v2, "c", v4)}/b", s"http://example.com/a/$v2encoded/c/$v4encoded/b"), + (uri"http://example.com/${"a/b/c".split('/')}", s"http://example.com/a/b/c") ), "path with parameters" -> List( - (uri"http://example.com/$v1?x=$v2", - s"http://example.com/$v1?x=$v2queryEncoded"), - (uri"http://example.com/$v1/$v2?x=$v2", - s"http://example.com/$v1/$v2encoded?x=$v2queryEncoded") + (uri"http://example.com/$v1?x=$v2", s"http://example.com/$v1?x=$v2queryEncoded"), + (uri"http://example.com/$v1/$v2?x=$v2", s"http://example.com/$v1/$v2encoded?x=$v2queryEncoded") ), "query parameter values" -> List( (uri"http://example.com?x=$v1", s"http://example.com?x=$v1"), @@ -101,31 +91,24 @@ class UriInterpolatorTests extends FunSuite with Matchers { ), "query parameter without value" -> List( (uri"http://example.com?$v1", s"http://example.com?$v1"), - (uri"http://example.com?$v1&$v2", - s"http://example.com?$v1&$v2queryEncoded") + (uri"http://example.com?$v1&$v2", s"http://example.com?$v1&$v2queryEncoded") ), "optional query parameters" -> List( (uri"http://example.com?a=$None", s"http://example.com"), (uri"http://example.com?a=b&c=$None", s"http://example.com?a=b"), (uri"http://example.com?a=b&c=$None&e=f", s"http://example.com?a=b&e=f"), (uri"http://example.com?a=${Some(v1)}", s"http://example.com?a=$v1"), - (uri"http://example.com?a=${Some(v1)}&c=d", - s"http://example.com?a=$v1&c=d") + (uri"http://example.com?a=${Some(v1)}&c=d", s"http://example.com?a=$v1&c=d") ), "parameter collections" -> List( (uri"http://example.com?${Seq("a" -> "b", v2 -> v1, v1 -> v2)}", s"http://example.com?a=b&$v2queryEncoded=$v1&$v1=$v2queryEncoded"), - (uri"http://example.com?${Seq("a" -> "b", "a" -> "c")}", - s"http://example.com?a=b&a=c"), + (uri"http://example.com?${Seq("a" -> "b", "a" -> "c")}", s"http://example.com?a=b&a=c"), (uri"http://example.com?${Map("a" -> "b")}", s"http://example.com?a=b"), - (uri"http://example.com?x=y&${Map("a" -> "b")}", - s"http://example.com?x=y&a=b"), - (uri"http://example.com?x=y&${Map("a" -> None)}", - s"http://example.com?x=y"), - (uri"http://example.com?x=y&${Map("a" -> Some("b"))}", - s"http://example.com?x=y&a=b"), - (uri"http://example.com?x=y&${Seq("a" -> None)}", - s"http://example.com?x=y") + (uri"http://example.com?x=y&${Map("a" -> "b")}", s"http://example.com?x=y&a=b"), + (uri"http://example.com?x=y&${Map("a" -> None)}", s"http://example.com?x=y"), + (uri"http://example.com?x=y&${Map("a" -> Some("b"))}", s"http://example.com?x=y&a=b"), + (uri"http://example.com?x=y&${Seq("a" -> None)}", s"http://example.com?x=y") ), "fragments" -> List( (uri"http://example.com#$v1", s"http://example.com#$v1"), @@ -137,8 +120,7 @@ class UriInterpolatorTests extends FunSuite with Matchers { ), "embed whole url" -> List( (uri"${"http://example.com:123/a"}/b/c", "http://example.com:123/a/b/c"), - (uri"${uri"http://example.com/$v1?p=$v2"}", - s"http://example.com/$v1?p=$v2queryEncoded") + (uri"${uri"http://example.com/$v1?p=$v2"}", s"http://example.com/$v1?p=$v2queryEncoded") ) ) @@ -152,19 +134,14 @@ class UriInterpolatorTests extends FunSuite with Matchers { } val validationTestData = List( - ("uri with two ports", - () => uri"http://example.com:80:80", - "port specified multiple times"), - ("uri with embedded host+port and port", - () => uri"http://${"example.com:80"}:80", - "port specified multiple times") + ("uri with two ports", () => uri"http://example.com:80:80", "port specified multiple times"), + ("uri with embedded host+port and port", () => uri"http://${"example.com:80"}:80", "port specified multiple times") ) for { (name, createUri, expectedException) <- validationTestData } { - test( - s"""$name should validate and throw "$expectedException" if not valid""") { + test(s"""$name should validate and throw "$expectedException" if not valid""") { val caught = intercept[IllegalArgumentException] { createUri() } diff --git a/core/src/test/scala/com/softwaremill/sttp/UriTests.scala b/core/src/test/scala/com/softwaremill/sttp/UriTests.scala index b94ac72..5250303 100644 --- a/core/src/test/scala/com/softwaremill/sttp/UriTests.scala +++ b/core/src/test/scala/com/softwaremill/sttp/UriTests.scala @@ -2,11 +2,7 @@ package com.softwaremill.sttp import java.net.URI -import com.softwaremill.sttp.Uri.{ - QueryFragment, - QueryFragmentEncoding, - UserInfo -} +import com.softwaremill.sttp.Uri.{QueryFragment, QueryFragmentEncoding, UserInfo} import org.scalatest.{FunSuite, Matchers} class UriTests extends FunSuite with Matchers { @@ -23,13 +19,7 @@ class UriTests extends FunSuite with Matchers { List(QF.KeyValue("p1", "v1"), QF.KeyValue("p2", "v2")), Some("f")) -> "https://sub.example.com:8080/a/b/xyz?p1=v1&p2=v2#f", - Uri("http", - None, - "example.com", - None, - List(""), - List(QF.KeyValue("p", "v"), QF.KeyValue("p", "v")), - None) -> "http://example.com/?p=v&p=v", + Uri("http", None, "example.com", None, List(""), List(QF.KeyValue("p", "v"), QF.KeyValue("p", "v")), None) -> "http://example.com/?p=v&p=v", Uri("http", None, "exa mple.com", @@ -38,13 +28,7 @@ class UriTests extends FunSuite with Matchers { List(QF.KeyValue("p:1", "v&v"), QF.KeyValue("p2", "v v")), None) -> "http://exa%20mple.com/a%20b/z/%C4%85:%C4%99?p:1=v%26v&p2=v+v", - Uri("http", - Some(UserInfo("us&e/r", Some("pa ss"))), - "example.com", - None, - Nil, - Nil, - None) -> + Uri("http", Some(UserInfo("us&e/r", Some("pa ss"))), "example.com", None, Nil, Nil, None) -> "http://us&e%2Fr:pa%20ss@example.com", Uri("http", None, "example.com", None, Nil, Nil, Some("f:g/h i")) -> "http://example.com#f:g/h%20i", @@ -79,24 +63,16 @@ class UriTests extends FunSuite with Matchers { } val queryFragmentsTestData = List( - List(QF.KeyValue("k1", "v1"), - QF.KeyValue("k2", "v2"), - QF.KeyValue("k3", "v3"), - QF.KeyValue("k4", "v4")) -> "k1=v1&k2=v2&k3=v3&k4=v4", + List(QF.KeyValue("k1", "v1"), QF.KeyValue("k2", "v2"), QF.KeyValue("k3", "v3"), QF.KeyValue("k4", "v4")) -> "k1=v1&k2=v2&k3=v3&k4=v4", List(QF.KeyValue("k1", "v1"), QF.KeyValue("k2", "v2"), QF.Plain("-abc-"), QF.KeyValue("k3", "v3"), QF.KeyValue("k4", "v4")) -> "k1=v1&k2=v2-abc-k3=v3&k4=v4", List(QF.KeyValue("k1", "v1"), QF.Plain("&abc&"), QF.KeyValue("k2", "v2")) -> "k1=v1%26abc%26k2=v2", - List( - QF.KeyValue("k1", "v1"), - QF.Plain("&abc&", encoding = QueryFragmentEncoding.Relaxed)) -> "k1=v1&abc&", + List(QF.KeyValue("k1", "v1"), QF.Plain("&abc&", encoding = QueryFragmentEncoding.Relaxed)) -> "k1=v1&abc&", List(QF.KeyValue("k1&", "v1&", keyEncoding = QueryFragmentEncoding.Relaxed)) -> "k1&=v1%26", - List(QF.KeyValue( - "k1&", - "v1&", - valueEncoding = QueryFragmentEncoding.Relaxed)) -> "k1%26=v1&", + List(QF.KeyValue("k1&", "v1&", valueEncoding = QueryFragmentEncoding.Relaxed)) -> "k1%26=v1&", List(QF.Plain("ą/ę&+;?", encoding = QueryFragmentEncoding.Relaxed)) -> "%C4%85/%C4%99&+;?", List(QF.KeyValue("k", "v1,v2", valueEncoding = QueryFragmentEncoding.All)) -> "k=v1%2Cv2", List(QF.KeyValue("k", "v1,v2")) -> "k=v1,v2", diff --git a/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala b/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala index 92c62f7..1299cae 100644 --- a/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala +++ b/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala @@ -19,13 +19,9 @@ class SttpBackendStubTests extends FlatSpec with Matchers with ScalaFutures { .whenRequestMatches(_.method == Method.GET) .thenRespondServerError() .whenRequestMatchesPartial({ - case r - if r.method == Method.POST && r.uri.path.endsWith( - List("partial10")) => + case r if r.method == Method.POST && r.uri.path.endsWith(List("partial10")) => Response(Right(10), 200, "OK", Nil, Nil) - case r - if r.method == Method.POST && r.uri.path.endsWith( - List("partialAda")) => + case r if r.method == Method.POST && r.uri.path.endsWith(List("partialAda")) => Response(Right("Ada"), 200, "OK", Nil, Nil) }) .whenRequestMatches(_.uri.port.exists(_ == 8080)) @@ -210,13 +206,9 @@ class SttpBackendStubTests extends FlatSpec with Matchers with ScalaFutures { (s, IgnoreResponse, Some(())), (s, ResponseAsString(Utf8), Some(s)), (s.getBytes(Utf8), ResponseAsString(Utf8), Some(s)), - (new ByteArrayInputStream(s.getBytes(Utf8)), - ResponseAsString(Utf8), - Some(s)), + (new ByteArrayInputStream(s.getBytes(Utf8)), ResponseAsString(Utf8), Some(s)), (10, ResponseAsString(Utf8), None), - ("10", - MappedResponseAs(ResponseAsString(Utf8), (_: String).toInt), - Some(10)), + ("10", MappedResponseAs(ResponseAsString(Utf8), (_: String).toInt), Some(10)), (10, MappedResponseAs(ResponseAsString(Utf8), (_: String).toInt), None) ) @@ -226,8 +218,7 @@ class SttpBackendStubTests extends FlatSpec with Matchers with ScalaFutures { (body, responseAs, expectedResult) <- adjustTestData } { it should s"adjust $body to $expectedResult when specified as $responseAs" in { - SttpBackendStub.tryAdjustResponseBody(responseAs, body) should be( - expectedResult) + SttpBackendStub.tryAdjustResponseBody(responseAs, body) should be(expectedResult) } } } diff --git a/json/circe/src/main/scala/com/softwaremill/sttp/circe/package.scala b/json/circe/src/main/scala/com/softwaremill/sttp/circe/package.scala index ddc9583..d5b6a08 100644 --- a/json/circe/src/main/scala/com/softwaremill/sttp/circe/package.scala +++ b/json/circe/src/main/scala/com/softwaremill/sttp/circe/package.scala @@ -5,8 +5,7 @@ import io.circe.{Decoder, Encoder} package object circe { - implicit def circeBodySerializer[B]( - implicit encoder: Encoder[B]): BodySerializer[B] = + implicit def circeBodySerializer[B](implicit encoder: Encoder[B]): BodySerializer[B] = b => StringBody(encoder(b).noSpaces, Utf8, Some(ApplicationJsonContentType)) def asJson[B: Decoder]: ResponseAs[Either[io.circe.Error, B], Nothing] = diff --git a/json/circe/src/test/scala/com/softwaremill/sttp/CirceTests.scala b/json/circe/src/test/scala/com/softwaremill/sttp/CirceTests.scala index 1e7dddc..d435267 100644 --- a/json/circe/src/test/scala/com/softwaremill/sttp/CirceTests.scala +++ b/json/circe/src/test/scala/com/softwaremill/sttp/CirceTests.scala @@ -84,8 +84,7 @@ class CirceTests extends FlatSpec with Matchers with EitherValues { case StringBody(body, "utf-8", Some(ApplicationJsonContentType)) => body case wrongBody => - fail( - s"Request body does not serialize to correct StringBody: $wrongBody") + fail(s"Request body does not serialize to correct StringBody: $wrongBody") } def runJsonResponseAs[A](responseAs: ResponseAs[A, Nothing]): String => A = @@ -95,8 +94,7 @@ class CirceTests extends FlatSpec with Matchers with EitherValues { case ResponseAsString("utf-8") => responseAs.g case ResponseAsString(encoding) => - fail( - s"MappedResponseAs wraps a ResponseAsString with wrong encoding: $encoding") + fail(s"MappedResponseAs wraps a ResponseAsString with wrong encoding: $encoding") case _ => fail("MappedResponseAs does not wrap a ResponseAsString") } diff --git a/json/json4s/src/main/scala/com/softwaremill/sttp/json4s/package.scala b/json/json4s/src/main/scala/com/softwaremill/sttp/json4s/package.scala index 4c7aa36..f19f776 100644 --- a/json/json4s/src/main/scala/com/softwaremill/sttp/json4s/package.scala +++ b/json/json4s/src/main/scala/com/softwaremill/sttp/json4s/package.scala @@ -4,11 +4,9 @@ import org.json4s._ import org.json4s.native.Serialization.{read, write} package object json4s { - implicit def json4sBodySerializer[B <: AnyRef]( - implicit formats: Formats = DefaultFormats): BodySerializer[B] = + implicit def json4sBodySerializer[B <: AnyRef](implicit formats: Formats = DefaultFormats): BodySerializer[B] = b => StringBody(write(b), Utf8, Some(ApplicationJsonContentType)) - def asJson[B: Manifest]( - implicit formats: Formats = DefaultFormats): ResponseAs[B, Nothing] = + def asJson[B: Manifest](implicit formats: Formats = DefaultFormats): ResponseAs[B, Nothing] = asString(Utf8).map(s => read[B](s)) } diff --git a/json/json4s/src/test/scala/com/softwaremill/sttp/Json4sTests.scala b/json/json4s/src/test/scala/com/softwaremill/sttp/Json4sTests.scala index bb4a774..c70a55c 100644 --- a/json/json4s/src/test/scala/com/softwaremill/sttp/Json4sTests.scala +++ b/json/json4s/src/test/scala/com/softwaremill/sttp/Json4sTests.scala @@ -49,8 +49,7 @@ class Json4sTests extends FlatSpec with Matchers with EitherValues { case StringBody(body, "utf-8", Some(ApplicationJsonContentType)) => body case wrongBody => - fail( - s"Request body does not serialize to correct StringBody: $wrongBody") + fail(s"Request body does not serialize to correct StringBody: $wrongBody") } def runJsonResponseAs[A](responseAs: ResponseAs[A, Nothing]): String => A = @@ -60,8 +59,7 @@ class Json4sTests extends FlatSpec with Matchers with EitherValues { case ResponseAsString("utf-8") => responseAs.g case ResponseAsString(encoding) => - fail( - s"MappedResponseAs wraps a ResponseAsString with wrong encoding: $encoding") + fail(s"MappedResponseAs wraps a ResponseAsString with wrong encoding: $encoding") case _ => fail("MappedResponseAs does not wrap a ResponseAsString") } diff --git a/metrics/brave-backend/src/main/scala/com/softwaremill/sttp/brave/BraveBackend.scala b/metrics/brave-backend/src/main/scala/com/softwaremill/sttp/brave/BraveBackend.scala index aaacd79..a530251 100644 --- a/metrics/brave-backend/src/main/scala/com/softwaremill/sttp/brave/BraveBackend.scala +++ b/metrics/brave-backend/src/main/scala/com/softwaremill/sttp/brave/BraveBackend.scala @@ -9,9 +9,7 @@ import zipkin2.Endpoint import scala.language.higherKinds -class BraveBackend[R[_], S] private (delegate: SttpBackend[R, S], - httpTracing: HttpTracing) - extends SttpBackend[R, S] { +class BraveBackend[R[_], S] private (delegate: SttpBackend[R, S], httpTracing: HttpTracing) extends SttpBackend[R, S] { // .asInstanceOf as the create method lacks generics in its return type private val handler = HttpClientHandler @@ -42,9 +40,7 @@ class BraveBackend[R[_], S] private (delegate: SttpBackend[R, S], } } - private def sendAndHandleReceive[T]( - span: Span, - request: Request[T, S]): R[Response[T]] = { + private def sendAndHandleReceive[T](span: Span, request: Request[T, S]): R[Response[T]] = { val spanInScope = tracer.withSpanInScope(span) responseMonad.handleError( @@ -61,8 +57,7 @@ class BraveBackend[R[_], S] private (delegate: SttpBackend[R, S], } } - private def injectTracing[T](span: Span, - request: Request[T, S]): Request[T, S] = { + private def injectTracing[T](span: Span, request: Request[T, S]): Request[T, S] = { /* Sadly the Brave API supports only mutable request representations, hence we need to work our way around this and inject headers into the traced request with the help of a mutable variable. Later a no-op injector @@ -85,8 +80,7 @@ class BraveBackend[R[_], S] private (delegate: SttpBackend[R, S], object BraveBackend { private val NoopInjector = new TraceContext.Injector[Request[_, _]] { - override def inject(traceContext: TraceContext, - carrier: Request[_, _]): Unit = {} + override def inject(traceContext: TraceContext, carrier: Request[_, _]): Unit = {} } private val TraceContextRequestTag = classOf[TraceContext].getName @@ -99,20 +93,17 @@ object BraveBackend { type AnyRequest = Request[_, _] type AnyResponse = Response[_] - def apply[R[_], S](delegate: SttpBackend[R, S], - tracing: Tracing): SttpBackend[R, S] = { + def apply[R[_], S](delegate: SttpBackend[R, S], tracing: Tracing): SttpBackend[R, S] = { apply(delegate, HttpTracing.create(tracing)) } - def apply[R[_], S](delegate: SttpBackend[R, S], - httpTracing: HttpTracing): SttpBackend[R, S] = { + def apply[R[_], S](delegate: SttpBackend[R, S], httpTracing: HttpTracing): SttpBackend[R, S] = { // redirects should be handled before brave tracing, hence adding the follow-redirects backend on top new FollowRedirectsBackend(new BraveBackend(delegate, httpTracing)) } } -object SttpHttpClientAdapter - extends HttpClientAdapter[AnyRequest, AnyResponse] { +object SttpHttpClientAdapter extends HttpClientAdapter[AnyRequest, AnyResponse] { override def method(request: AnyRequest): String = request.method.m @@ -123,8 +114,7 @@ object SttpHttpClientAdapter override def statusCode(response: AnyResponse): Integer = response.code - override def parseServerAddress(req: AnyRequest, - builder: Endpoint.Builder): Boolean = { + override def parseServerAddress(req: AnyRequest, builder: Endpoint.Builder): Boolean = { if (builder.parseIp(req.uri.host)) { req.uri.port.foreach(builder.port(_)) diff --git a/metrics/brave-backend/src/test/scala/com/softwaremill/sttp/brave/BraveBackendTest.scala b/metrics/brave-backend/src/test/scala/com/softwaremill/sttp/brave/BraveBackendTest.scala index f046210..94bbaed 100644 --- a/metrics/brave-backend/src/test/scala/com/softwaremill/sttp/brave/BraveBackendTest.scala +++ b/metrics/brave-backend/src/test/scala/com/softwaremill/sttp/brave/BraveBackendTest.scala @@ -19,14 +19,11 @@ class BraveBackendTest extends FlatSpec with Matchers with BeforeAndAfter { def newT(): Unit = { t = new ITHttpClient[SttpBackend[Id, Nothing]]() { - override def post(client: SttpBackend[Id, Nothing], - pathIncludingQuery: String, - body: String): Unit = { + override def post(client: SttpBackend[Id, Nothing], pathIncludingQuery: String, body: String): Unit = { client.send(sttp.post(uri"${url(pathIncludingQuery)}").body(body)) } - override def get(client: SttpBackend[Id, Nothing], - pathIncludingQuery: String): Unit = { + override def get(client: SttpBackend[Id, Nothing], pathIncludingQuery: String): Unit = { client.send(sttp.get(uri"${url(pathIncludingQuery)}")) } @@ -34,8 +31,7 @@ class BraveBackendTest extends FlatSpec with Matchers with BeforeAndAfter { client.close() override def newClient(port: Int): SttpBackend[Id, Nothing] = { - _backend = - BraveBackend[Id, Nothing](HttpURLConnectionBackend(), httpTracing) + _backend = BraveBackend[Id, Nothing](HttpURLConnectionBackend(), httpTracing) _httpTracing = httpTracing _takeSpan = () => takeSpan() @@ -135,10 +131,8 @@ class BraveBackendTest extends FlatSpec with Matchers with BeforeAndAfter { val request = t.server.takeRequest request.getHeader("x-b3-traceId") should be(parent.context.traceIdString) - request.getHeader("x-b3-parentspanid") should be( - HexCodec.toLowerHex(parent.context.spanId)) + request.getHeader("x-b3-parentspanid") should be(HexCodec.toLowerHex(parent.context.spanId)) - Set(_takeSpan(), _takeSpan()).map(_.kind) should be( - Set(null, Span.Kind.CLIENT)) + Set(_takeSpan(), _takeSpan()).map(_.kind) should be(Set(null, Span.Kind.CLIENT)) } } diff --git a/okhttp-backend/monix/src/main/scala/com/softwaremill/sttp/okhttp/monix/OkHttpMonixBackend.scala b/okhttp-backend/monix/src/main/scala/com/softwaremill/sttp/okhttp/monix/OkHttpMonixBackend.scala index f579ff5..bda8959 100644 --- a/okhttp-backend/monix/src/main/scala/com/softwaremill/sttp/okhttp/monix/OkHttpMonixBackend.scala +++ b/okhttp-backend/monix/src/main/scala/com/softwaremill/sttp/okhttp/monix/OkHttpMonixBackend.scala @@ -16,30 +16,24 @@ import okio.BufferedSink import scala.concurrent.Future import scala.util.{Failure, Success, Try} -class OkHttpMonixBackend private (client: OkHttpClient, closeClient: Boolean)( - implicit s: Scheduler) - extends OkHttpAsyncBackend[Task, Observable[ByteBuffer]](client, - TaskMonad, - closeClient) { - - override def streamToRequestBody( - stream: Observable[ByteBuffer]): Option[OkHttpRequestBody] = +class OkHttpMonixBackend private (client: OkHttpClient, closeClient: Boolean)(implicit s: Scheduler) + extends OkHttpAsyncBackend[Task, Observable[ByteBuffer]](client, TaskMonad, closeClient) { + + override def streamToRequestBody(stream: Observable[ByteBuffer]): Option[OkHttpRequestBody] = Some(new OkHttpRequestBody() { override def writeTo(sink: BufferedSink): Unit = toIterable(stream) map (_.array()) foreach sink.write override def contentType(): MediaType = null }) - override def responseBodyToStream( - res: okhttp3.Response): Try[Observable[ByteBuffer]] = + override def responseBodyToStream(res: okhttp3.Response): Try[Observable[ByteBuffer]] = Success( Observable .fromInputStream(res.body().byteStream()) .map(ByteBuffer.wrap) .doAfterTerminate(_ => res.close())) - private def toIterable[T](observable: Observable[T])( - implicit s: Scheduler): Iterable[T] = + private def toIterable[T](observable: Observable[T])(implicit s: Scheduler): Iterable[T] = new Iterable[T] { override def iterator: Iterator[T] = new Iterator[T] { case object Completed extends Exception @@ -85,15 +79,11 @@ object OkHttpMonixBackend { new FollowRedirectsBackend(new OkHttpMonixBackend(client, closeClient)(s)) def apply(options: SttpBackendOptions = SttpBackendOptions.Default)( - implicit s: Scheduler = Scheduler.Implicits.global) - : SttpBackend[Task, Observable[ByteBuffer]] = - OkHttpMonixBackend( - OkHttpBackend.defaultClient(DefaultReadTimeout.toMillis, options), - closeClient = true)(s) - - def usingClient(client: OkHttpClient)(implicit s: Scheduler = - Scheduler.Implicits.global) - : SttpBackend[Task, Observable[ByteBuffer]] = + implicit s: Scheduler = Scheduler.Implicits.global): SttpBackend[Task, Observable[ByteBuffer]] = + OkHttpMonixBackend(OkHttpBackend.defaultClient(DefaultReadTimeout.toMillis, options), closeClient = true)(s) + + def usingClient(client: OkHttpClient)( + implicit s: Scheduler = Scheduler.Implicits.global): SttpBackend[Task, Observable[ByteBuffer]] = OkHttpMonixBackend(client, closeClient = false)(s) } @@ -105,8 +95,7 @@ private[monix] object TaskMonad extends MonadAsyncError[Task] { override def flatMap[T, T2](fa: Task[T])(f: (T) => Task[T2]): Task[T2] = fa.flatMap(f) - override def async[T]( - register: ((Either[Throwable, T]) => Unit) => Unit): Task[T] = + override def async[T](register: ((Either[Throwable, T]) => Unit) => Unit): Task[T] = Task.async { (_, cb) => register { case Left(t) => cb(Failure(t)) @@ -118,8 +107,8 @@ private[monix] object TaskMonad extends MonadAsyncError[Task] { override def error[T](t: Throwable): Task[T] = Task.raiseError(t) - override protected def handleWrappedError[T](rt: Task[T])( - h: PartialFunction[Throwable, Task[T]]): Task[T] = rt.onErrorRecoverWith { - case t => h(t) - } + override protected def handleWrappedError[T](rt: Task[T])(h: PartialFunction[Throwable, Task[T]]): Task[T] = + rt.onErrorRecoverWith { + case t => h(t) + } } diff --git a/okhttp-backend/src/main/scala/com/softwaremill/sttp/okhttp/OkHttpBackend.scala b/okhttp-backend/src/main/scala/com/softwaremill/sttp/okhttp/OkHttpBackend.scala index 5716245..369950f 100644 --- a/okhttp-backend/src/main/scala/com/softwaremill/sttp/okhttp/OkHttpBackend.scala +++ b/okhttp-backend/src/main/scala/com/softwaremill/sttp/okhttp/OkHttpBackend.scala @@ -25,12 +25,9 @@ import scala.concurrent.{ExecutionContext, Future} import scala.language.higherKinds import scala.util.{Failure, Try} -abstract class OkHttpBackend[R[_], S](client: OkHttpClient, - closeClient: Boolean) - extends SttpBackend[R, S] { +abstract class OkHttpBackend[R[_], S](client: OkHttpClient, closeClient: Boolean) extends SttpBackend[R, S] { - private[okhttp] def convertRequest[T]( - request: Request[T, S]): OkHttpRequest = { + private[okhttp] def convertRequest[T](request: Request[T, S]): OkHttpRequest = { val builder = new OkHttpRequest.Builder() .url(request.uri.toString) @@ -51,8 +48,7 @@ abstract class OkHttpBackend[R[_], S](client: OkHttpClient, builder.build() } - private def bodyToOkHttp[T]( - body: RequestBody[S]): Option[OkHttpRequestBody] = { + private def bodyToOkHttp[T](body: RequestBody[S]): Option[OkHttpRequestBody] = { body match { case NoBody => None case StringBody(b, _, _) => @@ -79,26 +75,21 @@ abstract class OkHttpBackend[R[_], S](client: OkHttpClient, } } - private def addMultipart(builder: OkHttpMultipartBody.Builder, - mp: Multipart): Unit = { + private def addMultipart(builder: OkHttpMultipartBody.Builder, mp: Multipart): Unit = { val allHeaders = mp.additionalHeaders + (ContentDispositionHeader -> mp.contentDispositionHeaderValue) val headers = Headers.of(allHeaders.asJava) bodyToOkHttp(mp.body).foreach(builder.addPart(headers, _)) } - private[okhttp] def readResponse[T]( - res: OkHttpResponse, - responseAs: ResponseAs[T, S]): R[Response[T]] = { + private[okhttp] def readResponse[T](res: OkHttpResponse, responseAs: ResponseAs[T, S]): R[Response[T]] = { val code = res.code() val body = if (codeIsSuccess(code)) { - responseMonad.map(responseHandler(res).handle(responseAs, responseMonad))( - Right(_)) + responseMonad.map(responseHandler(res).handle(responseAs, responseMonad))(Right(_)) } else { - responseMonad.map(responseHandler(res).handle(asString, responseMonad))( - Left(_)) + responseMonad.map(responseHandler(res).handle(asString, responseMonad))(Left(_)) } val headers = res @@ -107,8 +98,7 @@ abstract class OkHttpBackend[R[_], S](client: OkHttpClient, .asScala .flatMap(name => res.headers().values(name).asScala.map((name, _))) - responseMonad.map(body)( - Response(_, res.code(), res.message(), headers.toList, Nil)) + responseMonad.map(body)(Response(_, res.code(), res.message(), headers.toList, Nil)) } private def responseHandler(res: OkHttpResponse) = @@ -121,8 +111,7 @@ abstract class OkHttpBackend[R[_], S](client: OkHttpClient, val charset = Option(res.header(ContentTypeHeader)) .flatMap(encodingFromContentType) .getOrElse(encoding) - val body = Try( - res.body().source().readString(Charset.forName(charset))) + val body = Try(res.body().source().readString(Charset.forName(charset))) res.close() body case ResponseAsByteArray => @@ -132,8 +121,7 @@ abstract class OkHttpBackend[R[_], S](client: OkHttpClient, case ras @ ResponseAsStream() => responseBodyToStream(res).map(ras.responseIsStream) case ResponseAsFile(file, overwrite) => - val body = Try( - ResponseAs.saveFile(file, res.body().byteStream(), overwrite)) + val body = Try(ResponseAs.saveFile(file, res.body().byteStream(), overwrite)) res.close() body } @@ -151,9 +139,7 @@ abstract class OkHttpBackend[R[_], S](client: OkHttpClient, object OkHttpBackend { - private[okhttp] def defaultClient( - readTimeout: Long, - options: SttpBackendOptions): OkHttpClient = { + private[okhttp] def defaultClient(readTimeout: Long, options: SttpBackendOptions): OkHttpClient = { var clientBuilder = new OkHttpClient.Builder() .followRedirects(false) .followSslRedirects(false) @@ -168,16 +154,13 @@ object OkHttpBackend { clientBuilder.build() } - private[okhttp] def updateClientIfCustomReadTimeout[T, S]( - r: Request[T, S], - client: OkHttpClient): OkHttpClient = { + private[okhttp] def updateClientIfCustomReadTimeout[T, S](r: Request[T, S], client: OkHttpClient): OkHttpClient = { val readTimeout = r.options.readTimeout if (readTimeout == DefaultReadTimeout) client else client .newBuilder() - .readTimeout(if (readTimeout.isFinite()) readTimeout.toMillis else 0, - TimeUnit.MILLISECONDS) + .readTimeout(if (readTimeout.isFinite()) readTimeout.toMillis else 0, TimeUnit.MILLISECONDS) .build() } @@ -198,24 +181,17 @@ class OkHttpSyncBackend private (client: OkHttpClient, closeClient: Boolean) } object OkHttpSyncBackend { - private def apply(client: OkHttpClient, - closeClient: Boolean): SttpBackend[Id, Nothing] = - new FollowRedirectsBackend[Id, Nothing]( - new OkHttpSyncBackend(client, closeClient)) + private def apply(client: OkHttpClient, closeClient: Boolean): SttpBackend[Id, Nothing] = + new FollowRedirectsBackend[Id, Nothing](new OkHttpSyncBackend(client, closeClient)) - def apply(options: SttpBackendOptions = SttpBackendOptions.Default) - : SttpBackend[Id, Nothing] = - OkHttpSyncBackend( - OkHttpBackend.defaultClient(DefaultReadTimeout.toMillis, options), - closeClient = true) + def apply(options: SttpBackendOptions = SttpBackendOptions.Default): SttpBackend[Id, Nothing] = + OkHttpSyncBackend(OkHttpBackend.defaultClient(DefaultReadTimeout.toMillis, options), closeClient = true) def usingClient(client: OkHttpClient): SttpBackend[Id, Nothing] = OkHttpSyncBackend(client, closeClient = false) } -abstract class OkHttpAsyncBackend[R[_], S](client: OkHttpClient, - rm: MonadAsyncError[R], - closeClient: Boolean) +abstract class OkHttpAsyncBackend[R[_], S](client: OkHttpClient, rm: MonadAsyncError[R], closeClient: Boolean) extends OkHttpBackend[R, S](client, closeClient) { override def send[T](r: Request[T, S]): R[Response[T]] = { val request = convertRequest(r) @@ -241,27 +217,19 @@ abstract class OkHttpAsyncBackend[R[_], S](client: OkHttpClient, override def responseMonad: MonadError[R] = rm } -class OkHttpFutureBackend private (client: OkHttpClient, closeClient: Boolean)( - implicit ec: ExecutionContext) - extends OkHttpAsyncBackend[Future, Nothing](client, - new FutureMonad, - closeClient) {} +class OkHttpFutureBackend private (client: OkHttpClient, closeClient: Boolean)(implicit ec: ExecutionContext) + extends OkHttpAsyncBackend[Future, Nothing](client, new FutureMonad, closeClient) {} object OkHttpFutureBackend { private def apply(client: OkHttpClient, closeClient: Boolean)( implicit ec: ExecutionContext): SttpBackend[Future, Nothing] = - new FollowRedirectsBackend[Future, Nothing]( - new OkHttpFutureBackend(client, closeClient)) + new FollowRedirectsBackend[Future, Nothing](new OkHttpFutureBackend(client, closeClient)) def apply(options: SttpBackendOptions = SttpBackendOptions.Default)( - implicit ec: ExecutionContext = ExecutionContext.Implicits.global) - : SttpBackend[Future, Nothing] = - OkHttpFutureBackend( - OkHttpBackend.defaultClient(DefaultReadTimeout.toMillis, options), - closeClient = true) - - def usingClient(client: OkHttpClient)(implicit ec: ExecutionContext = - ExecutionContext.Implicits.global) - : SttpBackend[Future, Nothing] = + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[Future, Nothing] = + OkHttpFutureBackend(OkHttpBackend.defaultClient(DefaultReadTimeout.toMillis, options), closeClient = true) + + def usingClient(client: OkHttpClient)( + implicit ec: ExecutionContext = ExecutionContext.Implicits.global): SttpBackend[Future, Nothing] = OkHttpFutureBackend(client, closeClient = false) } diff --git a/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala b/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala index 4e855fc..1d03154 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala @@ -94,25 +94,13 @@ class BasicTests } } ~ pathPrefix("set_cookies") { path("with_expires") { - setCookie( - HttpCookie("c", - "v", - expires = Some(DateTime(1997, 12, 8, 12, 49, 12)))) { + setCookie(HttpCookie("c", "v", expires = Some(DateTime(1997, 12, 8, 12, 49, 12)))) { complete("ok") } } ~ get { - setCookie( - HttpCookie("cookie1", - "value1", - secure = true, - httpOnly = true, - maxAge = Some(123L))) { + setCookie(HttpCookie("cookie1", "value1", secure = true, httpOnly = true, maxAge = Some(123L))) { setCookie(HttpCookie("cookie2", "value2")) { - setCookie( - HttpCookie("cookie3", - "", - domain = Some("xyz"), - path = Some("a/b/c"))) { + setCookie(HttpCookie("cookie3", "", domain = Some("xyz"), path = Some("a/b/c"))) { complete("ok") } } @@ -143,8 +131,7 @@ class BasicTests .mapAsync(1) { p => val fv = p.entity.dataBytes.runFold(ByteString())(_ ++ _) fv.map(_.utf8String) - .map(v => - p.name + "=" + v + p.filename.fold("")(fn => s" ($fn)")) + .map(v => p.name + "=" + v + p.filename.fold("")(fn => s" ($fn)")) } .runFold(Vector.empty[String])(_ :+ _) .map(v => v.mkString(", ")) @@ -168,8 +155,7 @@ class BasicTests } } ~ pathPrefix("timeout") { complete { - akka.pattern.after(1.second, using = actorSystem.scheduler)( - Future.successful("Done")) + akka.pattern.after(1.second, using = actorSystem.scheduler)(Future.successful("Done")) } } ~ path("empty_unauthorized_response") { post { @@ -184,9 +170,8 @@ class BasicTests } } ~ path("respond_with_iso_8859_2") { get { ctx => - val entity = HttpEntity( - MediaTypes.`text/plain`.withCharset(HttpCharset.custom("ISO-8859-2")), - textWithSpecialCharacters) + val entity = + HttpEntity(MediaTypes.`text/plain`.withCharset(HttpCharset.custom("ISO-8859-2")), textWithSpecialCharacters) ctx.complete(HttpResponse(200, entity = entity)) } } @@ -195,30 +180,19 @@ class BasicTests var closeBackends: List[() => Unit] = Nil - runTests("HttpURLConnection")(HttpURLConnectionBackend(), - ForceWrappedValue.id) - runTests("TryHttpURLConnection")(TryHttpURLConnectionBackend(), - ForceWrappedValue.scalaTry) - runTests("Akka HTTP")(AkkaHttpBackend.usingActorSystem(actorSystem), - ForceWrappedValue.future) - runTests("Async Http Client - Future")(AsyncHttpClientFutureBackend(), - ForceWrappedValue.future) - runTests("Async Http Client - Scalaz")(AsyncHttpClientScalazBackend(), - ForceWrappedValue.scalazTask) - runTests("Async Http Client - Monix")(AsyncHttpClientMonixBackend(), - ForceWrappedValue.monixTask) - runTests("Async Http Client - Cats Effect")( - AsyncHttpClientCatsBackend[cats.effect.IO](), - ForceWrappedValue.catsIo) + runTests("HttpURLConnection")(HttpURLConnectionBackend(), ForceWrappedValue.id) + runTests("TryHttpURLConnection")(TryHttpURLConnectionBackend(), ForceWrappedValue.scalaTry) + runTests("Akka HTTP")(AkkaHttpBackend.usingActorSystem(actorSystem), ForceWrappedValue.future) + runTests("Async Http Client - Future")(AsyncHttpClientFutureBackend(), ForceWrappedValue.future) + runTests("Async Http Client - Scalaz")(AsyncHttpClientScalazBackend(), ForceWrappedValue.scalazTask) + runTests("Async Http Client - Monix")(AsyncHttpClientMonixBackend(), ForceWrappedValue.monixTask) + runTests("Async Http Client - Cats Effect")(AsyncHttpClientCatsBackend[cats.effect.IO](), ForceWrappedValue.catsIo) runTests("OkHttpSyncClientHandler")(OkHttpSyncBackend(), ForceWrappedValue.id) - runTests("OkHttpAsyncClientHandler - Future")(OkHttpFutureBackend(), - ForceWrappedValue.future) - runTests("OkHttpAsyncClientHandler - Monix")(OkHttpMonixBackend(), - ForceWrappedValue.monixTask) + runTests("OkHttpAsyncClientHandler - Future")(OkHttpFutureBackend(), ForceWrappedValue.future) + runTests("OkHttpAsyncClientHandler - Monix")(OkHttpMonixBackend(), ForceWrappedValue.monixTask) - def runTests[R[_]](name: String)( - implicit backend: SttpBackend[R, Nothing], - forceResponse: ForceWrappedValue[R]): Unit = { + def runTests[R[_]](name: String)(implicit backend: SttpBackend[R, Nothing], + forceResponse: ForceWrappedValue[R]): Unit = { closeBackends = (() => backend.close()) :: closeBackends @@ -373,8 +347,7 @@ class BasicTests name should "read response headers" in { val response = getHeaders.response(sttpIgnore).send().force() response.headers should have length (6) - response.headers("Cache-Control").toSet should be( - Set("no-cache", "max-age=1000")) + response.headers("Cache-Control").toSet should be(Set("no-cache", "max-age=1000")) response.header("Server") should be('defined) response.header("server") should be('defined) response.header("Server").get should startWith("akka-http") @@ -405,11 +378,7 @@ class BasicTests response.cookies should have length (3) response.cookies.toSet should be( Set( - Cookie("cookie1", - "value1", - secure = true, - httpOnly = true, - maxAge = Some(123L)), + Cookie("cookie1", "value1", secure = true, httpOnly = true, maxAge = Some(123L)), Cookie("cookie2", "value2"), Cookie("cookie3", "", domain = Some("xyz"), path = Some("a/b/c")) )) @@ -443,8 +412,7 @@ class BasicTests val req = secureBasic val resp = req.send().force() resp.code should be(401) - resp.header("WWW-Authenticate") should be( - Some("""Basic realm="test realm",charset=UTF-8""")) + resp.header("WWW-Authenticate") should be(Some("""Basic realm="test realm",charset=UTF-8""")) } name should "perform basic authorization" in { @@ -586,8 +554,7 @@ class BasicTests } name should "send a multipart message with filenames" in { - val req = mp.multipartBody(multipart("p1", "v1").fileName("f1"), - multipart("p2", "v2").fileName("f2")) + val req = mp.multipartBody(multipart("p1", "v1").fileName("f1"), multipart("p2", "v2").fileName("f2")) val resp = req.send().force() resp.unsafeBody should be("p1=v1 (f1), p2=v2 (f2)") } diff --git a/tests/src/test/scala/com/softwaremill/sttp/IllTypedTests.scala b/tests/src/test/scala/com/softwaremill/sttp/IllTypedTests.scala index 66d040c..881c60e 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/IllTypedTests.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/IllTypedTests.scala @@ -7,8 +7,7 @@ import scala.tools.reflect.ToolBoxError class IllTypedTests extends FlatSpec with Matchers { "compilation" should "fail when trying to stream using the default backend" in { val thrown = intercept[ToolBoxError] { - EvalScala( - """ + EvalScala(""" import com.softwaremill.sttp._ import akka.stream.scaladsl.Source import akka.util.ByteString @@ -30,7 +29,6 @@ class IllTypedTests extends FlatSpec with Matchers { """) } - thrown.getMessage should include( - "This is a partial request, the method & url are not specified") + thrown.getMessage should include("This is a partial request, the method & url are not specified") } } diff --git a/tests/src/test/scala/com/softwaremill/sttp/StreamingTests.scala b/tests/src/test/scala/com/softwaremill/sttp/StreamingTests.scala index f7faf64..e3dbe2c 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/StreamingTests.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/StreamingTests.scala @@ -38,9 +38,7 @@ class StreamingTests runTests("Monix OkHttp", new OkHttpMonixStreamingTests) runTests("fs2 Async Http Client", new AsyncHttpClientFs2StreamingTests) - def runTests[R[_], S]( - name: String, - testStreamingBackend: TestStreamingBackend[R, S]): Unit = { + def runTests[R[_], S](name: String, testStreamingBackend: TestStreamingBackend[R, S]): Unit = { import testStreamingBackend._ closeBackends = (() => backend.close()) :: closeBackends diff --git a/tests/src/test/scala/com/softwaremill/sttp/streaming/AkkaHttpStreamingTests.scala b/tests/src/test/scala/com/softwaremill/sttp/streaming/AkkaHttpStreamingTests.scala index 3fca682..d8fbb82 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/streaming/AkkaHttpStreamingTests.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/streaming/AkkaHttpStreamingTests.scala @@ -10,8 +10,7 @@ import com.softwaremill.sttp.{ForceWrappedValue, SttpBackend} import scala.concurrent.Future -class AkkaHttpStreamingTests(actorSystem: ActorSystem)( - implicit materializer: Materializer) +class AkkaHttpStreamingTests(actorSystem: ActorSystem)(implicit materializer: Materializer) extends TestStreamingBackend[Future, Source[ByteString, Any]] { override implicit val backend: SttpBackend[Future, Source[ByteString, Any]] = diff --git a/tests/src/test/scala/com/softwaremill/sttp/streaming/AsyncHttpClientFs2StreamingTests.scala b/tests/src/test/scala/com/softwaremill/sttp/streaming/AsyncHttpClientFs2StreamingTests.scala index ec6ce05..82f36be 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/streaming/AsyncHttpClientFs2StreamingTests.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/streaming/AsyncHttpClientFs2StreamingTests.scala @@ -8,8 +8,7 @@ import com.softwaremill.sttp.asynchttpclient.fs2.AsyncHttpClientFs2Backend import com.softwaremill.sttp.{ForceWrappedValue, SttpBackend} import fs2._ -class AsyncHttpClientFs2StreamingTests - extends TestStreamingBackend[IO, Stream[IO, ByteBuffer]] { +class AsyncHttpClientFs2StreamingTests extends TestStreamingBackend[IO, Stream[IO, ByteBuffer]] { override implicit val backend: SttpBackend[IO, Stream[IO, ByteBuffer]] = AsyncHttpClientFs2Backend[IO]() diff --git a/tests/src/test/scala/com/softwaremill/sttp/streaming/MonixBaseBackend.scala b/tests/src/test/scala/com/softwaremill/sttp/streaming/MonixBaseBackend.scala index 3510fbc..acd67a7 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/streaming/MonixBaseBackend.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/streaming/MonixBaseBackend.scala @@ -6,15 +6,13 @@ import com.softwaremill.sttp.ForceWrappedValue import monix.eval.Task import monix.reactive.Observable -trait MonixBaseBackend - extends TestStreamingBackend[Task, Observable[ByteBuffer]] { +trait MonixBaseBackend extends TestStreamingBackend[Task, Observable[ByteBuffer]] { override implicit def forceResponse: ForceWrappedValue[Task] = ForceWrappedValue.monixTask override def bodyProducer(body: String): Observable[ByteBuffer] = - Observable.fromIterable( - body.getBytes("utf-8").map(b => ByteBuffer.wrap(Array(b)))) + Observable.fromIterable(body.getBytes("utf-8").map(b => ByteBuffer.wrap(Array(b)))) override def bodyConsumer(stream: Observable[ByteBuffer]): Task[String] = stream diff --git a/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala b/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala index c926840..1a57b7e 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala @@ -18,10 +18,7 @@ import scala.language.higherKinds import scala.util.Try import scalaz._ -trait TestHttpServer - extends BeforeAndAfterAll - with ScalaFutures - with TestingPatience { +trait TestHttpServer extends BeforeAndAfterAll with ScalaFutures with TestingPatience { this: Suite => protected implicit val actorSystem: ActorSystem = ActorSystem("sttp-test") import actorSystem.dispatcher -- cgit v1.2.3