Skip to content

Commit

Permalink
Merge branch 'master' into update/http4s-client-0.23.25
Browse files Browse the repository at this point in the history
  • Loading branch information
adamw authored Feb 26, 2024
2 parents 9d4ff6a + 6cef894 commit 309fdb0
Show file tree
Hide file tree
Showing 35 changed files with 154 additions and 144 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ sttp (v2) documentation is available at [sttp.softwaremill.com/en/v2](https://st

sttp (v1) documentation is available at [sttp.softwaremill.com/en/v1](https://sttp.softwaremill.com/en/v1).

scaladoc is available at [https://www.javadoc.io](https://www.javadoc.io/doc/com.softwaremill.sttp.client4/core_2.12/4.0.0-M8)
scaladoc is available at [https://www.javadoc.io](https://www.javadoc.io/doc/com.softwaremill.sttp.client4/core_2.12/4.0.0-M9)

## Quickstart with scala-cli

Add the following directive to the top of your scala file to add the core sttp dependency:
If you are using [scala-cli](https://scala-cli.virtuslab.org), you can quickly start experimenting with sttp by copy-pasting the following:

```
//> using lib "com.softwaremill.sttp.client4::core:4.0.0-M8"
//> using lib "com.softwaremill.sttp.client4::core:4.0.0-M9"
import sttp.client4.quick._
quickRequest.get(uri"http://httpbin.org/ip").send()
```
Expand All @@ -68,7 +68,7 @@ The `quick` package import brings in the sttp API and a pre-configured, global s
Similarly, using [Ammonite](http://ammonite.io):

```scala
import $ivy.`com.softwaremill.sttp.client4::core:4.0.0-M8`
import $ivy.`com.softwaremill.sttp.client4::core:4.0.0-M9`
import sttp.client4.quick._
quickRequest.get(uri"http://httpbin.org/ip").send()
```
Expand All @@ -78,7 +78,7 @@ quickRequest.get(uri"http://httpbin.org/ip").send()
Add the following dependency:

```scala
"com.softwaremill.sttp.client4" %% "core" % "4.0.0-M8"
"com.softwaremill.sttp.client4" %% "core" % "4.0.0-M9"
```

Then, import:
Expand Down Expand Up @@ -133,7 +133,7 @@ The documentation is typechecked using [mdoc](https://scalameta.org/mdoc/). The

When generating documentation, it's best to set the version to the current one, so that the generated doc files don't include modifications with the current snapshot version.

That is, in sbt run: `set version := "4.0.0-M8"`, before running `mdoc` in `docs`.
That is, in sbt run: `set version := "4.0.0-M9"`, before running `mdoc` in `docs`.

### Testing the Scala.JS backend

Expand All @@ -160,4 +160,4 @@ We offer commercial support for sttp and related technologies, as well as develo

## Copyright

Copyright (C) 2017-2023 SoftwareMill [https://softwaremill.com](https://softwaremill.com).
Copyright (C) 2017-2024 SoftwareMill [https://softwaremill.com](https://softwaremill.com).
28 changes: 14 additions & 14 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ val testServerSettings = Seq(

val circeVersion: String = "0.14.6"

val jsoniterVersion = "2.25.0"
val jsoniterVersion = "2.27.2"

val play29JsonVersion = "2.10.3"
val play29JsonVersion = "2.10.4"

val playJsonVersion = "3.0.1"
val playJsonVersion = "3.0.2"

val catsEffect_3_version = "3.5.2"
val catsEffect_3_version = "3.5.3"
val fs2_3_version = "3.9.3"

val catsEffect_2_version = "2.5.5"
Expand All @@ -138,32 +138,32 @@ val akkaHttp = "com.typesafe.akka" %% "akka-http" % "10.2.10"
val akkaStreamVersion = "2.6.20"
val akkaStreams = "com.typesafe.akka" %% "akka-stream" % akkaStreamVersion

val pekkoHttp = "org.apache.pekko" %% "pekko-http" % "1.0.0"
val pekkoHttp = "org.apache.pekko" %% "pekko-http" % "1.0.1"
val pekkoStreamVersion = "1.0.2"
val pekkoStreams = "org.apache.pekko" %% "pekko-stream" % pekkoStreamVersion

val scalaTest = libraryDependencies ++= Seq("freespec", "funsuite", "flatspec", "wordspec", "shouldmatchers").map(m =>
"org.scalatest" %%% s"scalatest-$m" % "3.2.17" % Test
"org.scalatest" %%% s"scalatest-$m" % "3.2.18" % Test
)

val zio1Version = "1.0.18"
val zio2Version = "2.0.19"
val zio2Version = "2.0.21"
val zio1InteropRsVersion = "1.3.12"
val zio2InteropRsVersion = "2.0.2"

val sttpModelVersion = "1.7.6"
val sttpSharedVersion = "1.3.17"

val logback = "ch.qos.logback" % "logback-classic" % "1.4.14"
val logback = "ch.qos.logback" % "logback-classic" % "1.5.0"

val jeagerClientVersion = "1.8.1"
val braveOpentracingVersion = "1.0.0"
val braveOpentracingVersion = "1.0.1"
val zipkinSenderOkHttpVersion = "2.16.5"
val resilience4jVersion = "2.1.0"
val resilience4jVersion = "2.2.0"
val http4s_ce2_version = "0.22.15"
val http4s_ce3_version = "0.23.25"

val openTelemetryVersion = "1.33.0"
val openTelemetryVersion = "1.35.0"

val compileAndTest = "compile->compile;test->test"

Expand Down Expand Up @@ -676,7 +676,7 @@ lazy val http4sBackend = (projectMatrix in file("http4s-backend"))
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-client" % http4s_ce3_version,
"org.http4s" %% "http4s-ember-client" % "0.23.25" % Optional,
"org.http4s" %% "http4s-blaze-client" % "0.23.15" % Optional
"org.http4s" %% "http4s-blaze-client" % "0.23.16" % Optional
),
evictionErrorLevel := Level.Info
)
Expand All @@ -701,7 +701,7 @@ lazy val armeriaBackend = (projectMatrix in file("armeria-backend"))
.settings(testServerSettings)
.settings(
name := "armeria-backend",
libraryDependencies += "com.linecorp.armeria" % "armeria" % "1.26.4"
libraryDependencies += "com.linecorp.armeria" % "armeria" % "1.27.1"
)
.jvmPlatform(scalaVersions = scala2 ++ scala3)
.dependsOn(core % compileAndTest)
Expand Down Expand Up @@ -847,7 +847,7 @@ lazy val upickle = (projectMatrix in file("json/upickle"))
.settings(
name := "upickle",
libraryDependencies ++= Seq(
"com.lihaoyi" %%% "upickle" % "3.1.3"
"com.lihaoyi" %%% "upickle" % "3.1.4"
),
scalaTest,
// using macroRW causes a "match may not be exhaustive" error
Expand Down
21 changes: 11 additions & 10 deletions core/src/main/scalajs/sttp/client4/fetch/AbstractFetchBackend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,21 @@ abstract class AbstractFetchBackend[F[_], S <: Streams[S]](
private def sendRegular[T](request: GenericRequest[T, R]): F[Response[T]] = {
// https://stackoverflow.com/q/31061838/4094860
val readTimeout = request.options.readTimeout
val (signal, cancelTimeout) = readTimeout match {
val controller = new AbortController()
val signal = controller.signal
val cancelTimeout = readTimeout match {
case timeout: FiniteDuration =>
val controller = new AbortController()
val signal = controller.signal

val timeoutHandle = setTimeout(timeout) {
controller.abort()
}
(Some(signal), () => clearTimeout(timeoutHandle))
() => clearTimeout(timeoutHandle)

case _ =>
(None, () => ())
() => ()
}

val cancel = () => controller.abort()

val rheaders = new JSHeaders()
request.headers.foreach { header =>
// for multipart/form-data requests dom.FormData is responsible for setting the Content-Type header
Expand All @@ -113,7 +114,7 @@ abstract class AbstractFetchBackend[F[_], S <: Streams[S]](
val req = createBody(request.body).map { rbody =>
// use manual so we can return a specific error instead of the generic "TypeError: Failed to fetch"
val rredirect = if (request.options.followRedirects) RequestRedirect.follow else RequestRedirect.manual
val rsignal = signal.orUndefined
val rsignal = signal

val requestInitStatic = new RequestInit() {
this.method = request.method.method.asInstanceOf[HttpMethod]
Expand All @@ -132,7 +133,7 @@ abstract class AbstractFetchBackend[F[_], S <: Streams[S]](
}

val requestInitDynamic = requestInitStatic.asInstanceOf[js.Dynamic]
signal.foreach(s => requestInitDynamic.updateDynamic("signal")(s))
requestInitDynamic.updateDynamic("signal")(signal)
requestInitDynamic.updateDynamic("redirect")(rredirect) // named wrong in RequestInit
val requestInit = requestInitDynamic.asInstanceOf[RequestInit]

Expand Down Expand Up @@ -165,10 +166,10 @@ abstract class AbstractFetchBackend[F[_], S <: Streams[S]](
)
}
}
addCancelTimeoutHook(result, cancelTimeout)
addCancelTimeoutHook(result, cancel, cancelTimeout)
}

protected def addCancelTimeoutHook[T](result: F[T], cancel: () => Unit): F[T]
protected def addCancelTimeoutHook[T](result: F[T], cancel: () => Unit, cleanup: () => Unit): F[T]

private def convertResponseHeaders(headers: JSHeaders): Seq[Header] =
headers
Expand Down
8 changes: 6 additions & 2 deletions core/src/main/scalajs/sttp/client4/fetch/FetchBackend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ class FetchBackend private (fetchOptions: FetchOptions, customizeRequest: FetchR

override val streams: NoStreams = NoStreams

override protected def addCancelTimeoutHook[T](result: Future[T], cancel: () => Unit): Future[T] = {
result.onComplete(_ => cancel())
override protected def addCancelTimeoutHook[T](
result: Future[T],
cancel: () => Unit,
cleanup: () => Unit
): Future[T] = {
result.onComplete(_ => cleanup())
result
}

Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ println(response.header("Content-Length"))
println(response.body)
```

For more examples, see the [usage examples](examples.md) section. To start using sttp client in your project, see the [quickstart](quickstart.md). Or, browse the documentation to find the topics that interest you the most!
For more examples, see the [usage examples](examples.md) section. To start using sttp client in your project, see the [quickstart](quickstart.md). Or, browse the documentation to find the topics that interest you the most! ScalaDoc is available at [https://www.javadoc.io](https://www.javadoc.io/doc/com.softwaremill.sttp.client4/core_2.12/4.0.0-M9).

## Other sttp projects

Expand All @@ -56,7 +56,7 @@ Third party projects:

## Sponsors

Development and maintenance of sttp client is sponsored by [SoftwareMill](https://softwaremill.com), a software development and consulting company. We help clients scale their business through software. Our areas of expertise include backends, distributed systems, blockchain, machine learning and data analytics.
Development and maintenance of sttp client is sponsored by [SoftwareMill](https://softwaremill.com), a software development and consulting company. We help clients scale their business through software. Our areas of expertise include backends, distributed systems, machine learning, platform engineering and data analytics.

[![](https://files.softwaremill.com/logo/logo.png "SoftwareMill")](https://softwaremill.com)

Expand Down
6 changes: 3 additions & 3 deletions docs/model/uri.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import sttp.client4._
// the embedded / is escaped
println(uri"http://example.org/${"a/b"}")

// the embedded / is not escaped
// the literal / is not escaped
println(uri"http://example.org/${"a"}/${"b"}")

// the embedded : is not escaped
Expand Down Expand Up @@ -132,7 +132,7 @@ which is an ordinary `case class`, will contain a path segment with `a b`.

When parsing, that includes creating URIs from constant strings e.g. `uri"http://example.com/a%20b"`, all of the
components are decoded and stored in this form. This means that `Uri` might **not** exactly preserve the original
form, in which path segments or query parameters have been writte down (this might change in a future major release,
form, in which path segments or query parameters have been written down (this might change in a future major release,
though).

When serialising the `Uri` back to a `String`, the code follows the escaping rules defined in
Expand All @@ -156,4 +156,4 @@ println(uri"http://example.com?a=b/?c%26d".querySegmentsEncoding(Uri.QuerySegmen

// compare to:
println(uri"http://example.com?a=b/?c%26d")
```
```
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ class FetchCatsBackend[F[_]: Concurrent: ContextShift] private (

override val streams: NoStreams = NoStreams

override protected def addCancelTimeoutHook[T](result: F[T], cancel: () => Unit): F[T] = {
override protected def addCancelTimeoutHook[T](result: F[T], cancel: () => Unit, cleanup: () => Unit): F[T] = {
val doCancel = Sync[F].delay(cancel())
result.guarantee(doCancel)
val doCleanup = Sync[F].delay(cleanup())
result.onCancel(doCancel).guarantee(doCleanup)
}

override protected def handleStreamBody(s: Nothing): F[js.UndefOr[BodyInit]] = s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ class FetchCatsBackend[F[_]: Async] private (

override val streams: NoStreams = NoStreams

override protected def addCancelTimeoutHook[T](result: F[T], cancel: () => Unit): F[T] = {
override protected def addCancelTimeoutHook[T](result: F[T], cancel: () => Unit, cleanup: () => Unit): F[T] = {
val doCancel = Async[F].delay(cancel())
result.guarantee(doCancel)
val doCleanup = Async[F].delay(cleanup())
result.onCancel(doCancel).guarantee(doCleanup)
}

override protected def handleStreamBody(s: Nothing): F[js.UndefOr[BodyInit]] = s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ class FetchMonixBackend private (fetchOptions: FetchOptions, customizeRequest: F

override val streams: MonixStreams = MonixStreams

override protected def addCancelTimeoutHook[T](result: Task[T], cancel: () => Unit): Task[T] = {
override protected def addCancelTimeoutHook[T](result: Task[T], cancel: () => Unit, cleanup: () => Unit): Task[T] = {
val doCancel = Task.delay(cancel())
result.doOnCancel(doCancel).doOnFinish(_ => doCancel)
val doCleanup = Task.delay(cleanup())
result.doOnCancel(doCancel).doOnFinish(_ => doCleanup)
}

override protected def handleStreamBody(s: Observable[Array[Byte]]): Task[js.UndefOr[BodyInit]] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ class FetchZioBackend private (fetchOptions: FetchOptions, customizeRequest: Fet

override val streams: ZioStreams = ZioStreams

override protected def addCancelTimeoutHook[T](result: Task[T], cancel: () => Unit): Task[T] = {
val doCancel = ZIO.attempt(cancel())
result.onInterrupt(doCancel.catchAll(_ => ZIO.unit)).tap(_ => doCancel)
override protected def addCancelTimeoutHook[T](result: Task[T], cancel: () => Unit, cleanup: () => Unit): Task[T] = {
val doCancel = ZIO.attempt(cancel()).ignore
val doCleanup = ZIO.attempt(cleanup()).ignore
result.onInterrupt(doCancel).onExit(_ => doCleanup)
}

override protected def handleStreamBody(s: Observable[Byte]): Task[js.UndefOr[BodyInit]] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ class FetchZioBackend private (fetchOptions: FetchOptions, customizeRequest: Fet

override val streams: ZioStreams = ZioStreams

override protected def addCancelTimeoutHook[T](result: Task[T], cancel: () => Unit): Task[T] = {
val doCancel = ZIO.effect(cancel())
result.onInterrupt(doCancel.catchAll(_ => ZIO.unit)).tap(_ => doCancel)
override protected def addCancelTimeoutHook[T](result: Task[T], cancel: () => Unit, cleanup: () => Unit): Task[T] = {
val doCancel = ZIO.effect(cancel()).ignore
val doCleanup = ZIO.effect(cleanup()).ignore
result.onInterrupt(doCancel).onExit(_ => doCleanup)
}

override protected def handleStreamBody(s: Observable[Byte]): Task[js.UndefOr[BodyInit]] = {
Expand Down
2 changes: 1 addition & 1 deletion generated-docs/out/backends/akka.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This backend is based on [akka-http](http://doc.akka.io/docs/akka-http/current/scala/http/). To use, add the following dependency to your project:

```
"com.softwaremill.sttp.client4" %% "akka-http-backend" % "4.0.0-M8"
"com.softwaremill.sttp.client4" %% "akka-http-backend" % "4.0.0-M9"
```

A fully **asynchronous** backend. Uses the `Future` effect to return responses. There are also [other `Future`-based backends](future.md), which don't depend on Akka.
Expand Down
6 changes: 3 additions & 3 deletions generated-docs/out/backends/catseffect.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Also note that the [http4s](http4s.md) backend can also be created for a type im
Firstly, add the following dependency to your project:

```scala
"com.softwaremill.sttp.client4" %% "cats" % "4.0.0-M8"
"com.softwaremill.sttp.client4" %% "cats" % "4.0.0-M9"
```

Obtain a cats-effect `Resource` which creates the backend, and closes the thread pool after the resource is no longer used:
Expand Down Expand Up @@ -82,9 +82,9 @@ Creation of the backend can be done in two basic ways:
Firstly, add the following dependency to your project:

```scala
"com.softwaremill.sttp.client4" %% "armeria-backend-cats" % "4.0.0-M8" // for cats-effect 3.x
"com.softwaremill.sttp.client4" %% "armeria-backend-cats" % "4.0.0-M9" // for cats-effect 3.x
// or
"com.softwaremill.sttp.client4" %% "armeria-backend-cats-ce2" % "4.0.0-M8" // for cats-effect 2.x
"com.softwaremill.sttp.client4" %% "armeria-backend-cats-ce2" % "4.0.0-M9" // for cats-effect 2.x
```

create client:
Expand Down
2 changes: 1 addition & 1 deletion generated-docs/out/backends/finagle.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
To use, add the following dependency to your project:

```
"com.softwaremill.sttp.client4" %% "finagle-backend" % "4.0.0-M8"
"com.softwaremill.sttp.client4" %% "finagle-backend" % "4.0.0-M9"
```

Next you'll need to add an implicit value:
Expand Down
8 changes: 4 additions & 4 deletions generated-docs/out/backends/fs2.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Creation of the backend can be done in two basic ways:
Firstly, add the following dependency to your project:

```scala
"com.softwaremill.sttp.client4" %% "fs2" % "4.0.0-M8" // for cats-effect 3.x & fs2 3.x
"com.softwaremill.sttp.client4" %% "fs2" % "4.0.0-M9" // for cats-effect 3.x & fs2 3.x
// or
"com.softwaremill.sttp.client4" %% "fs2ce2" % "4.0.0-M8" // for cats-effect 2.x & fs2 2.x
"com.softwaremill.sttp.client4" %% "fs2ce2" % "4.0.0-M9" // for cats-effect 2.x & fs2 2.x
```

Obtain a cats-effect `Resource` which creates the backend, and closes the thread pool after the resource is no longer used:
Expand Down Expand Up @@ -78,9 +78,9 @@ Host header override is supported in environments running Java 12 onwards, but i
To use, add the following dependency to your project:

```scala
"com.softwaremill.sttp.client4" %% "armeria-backend-fs2" % "4.0.0-M8" // for cats-effect 3.x & fs2 3.x
"com.softwaremill.sttp.client4" %% "armeria-backend-fs2" % "4.0.0-M9" // for cats-effect 3.x & fs2 3.x
// or
"com.softwaremill.sttp.client4" %% "armeria-backend-fs2" % "4.0.0-M8" // for cats-effect 2.x & fs2 2.x
"com.softwaremill.sttp.client4" %% "armeria-backend-fs2" % "4.0.0-M9" // for cats-effect 2.x & fs2 2.x
```

create client:
Expand Down
Loading

0 comments on commit 309fdb0

Please sign in to comment.