diff options
author | Adam Warski <adam@warski.org> | 2017-09-07 09:13:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-07 09:13:04 +0200 |
commit | 3c85a4a5acf7197c1822d4b6339168e36cf1b853 (patch) | |
tree | 6147dd38662760d14bc6161b692486e1f29f9b30 /core | |
parent | 7188ebe102803c7d27c75b4640ded86a2ba7c6f6 (diff) | |
parent | 6874e55a316e4fe8a650efd3a849814a91bba8cb (diff) | |
download | sttp-3c85a4a5acf7197c1822d4b6339168e36cf1b853.tar.gz sttp-3c85a4a5acf7197c1822d4b6339168e36cf1b853.tar.bz2 sttp-3c85a4a5acf7197c1822d4b6339168e36cf1b853.zip |
Merge pull request #28 from bhop/feature/request-timeout
Make request timeout configurable
Diffstat (limited to 'core')
5 files changed, 42 insertions, 15 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionHandler.scala b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionHandler.scala index 45a0448..9b73298 100644 --- a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionHandler.scala +++ b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionHandler.scala @@ -11,14 +11,18 @@ import java.util.zip.{GZIPInputStream, InflaterInputStream} import scala.annotation.tailrec import scala.io.Source import scala.collection.JavaConverters._ +import scala.concurrent.duration.{Duration, FiniteDuration} -class HttpURLConnectionHandler extends SttpHandler[Id, Nothing] { +class HttpURLConnectionHandler private (connectionTimeout: FiniteDuration) + extends SttpHandler[Id, Nothing] { override def send[T](r: Request[T, Nothing]): Response[T] = { val c = new URL(r.uri.toString).openConnection().asInstanceOf[HttpURLConnection] c.setRequestMethod(r.method.m) r.headers.foreach { case (k, v) => c.setRequestProperty(k, v) } c.setDoInput(true) + c.setReadTimeout(timeout(r.options.readTimeout)) + c.setConnectTimeout(timeout(connectionTimeout)) // redirects are handled in SttpHandler c.setInstanceFollowRedirects(false) @@ -68,6 +72,10 @@ class HttpURLConnectionHandler extends SttpHandler[Id, Nothing] { } } + private def timeout(t: Duration): Int = + if (t.isFinite()) t.toMillis.toInt + else 0 + private def writeBasicBody(body: BasicRequestBody, os: OutputStream): Unit = { body match { case StringBody(b, encoding, _) => @@ -247,3 +255,11 @@ class HttpURLConnectionHandler extends SttpHandler[Id, Nothing] { override def close(): Unit = {} } + +object HttpURLConnectionHandler { + + def apply(connectionTimeout: FiniteDuration = SttpHandler.DefaultConnectionTimeout) + : SttpHandler[Id, Nothing] = + new FollowRedirectsHandler[Id, Nothing]( + new HttpURLConnectionHandler(connectionTimeout)) +} diff --git a/core/src/main/scala/com/softwaremill/sttp/RequestT.scala b/core/src/main/scala/com/softwaremill/sttp/RequestT.scala index 020e926..6e76f6f 100644 --- a/core/src/main/scala/com/softwaremill/sttp/RequestT.scala +++ b/core/src/main/scala/com/softwaremill/sttp/RequestT.scala @@ -6,7 +6,7 @@ import java.nio.file.Path import java.util.Base64 import scala.collection.immutable.Seq - +import scala.concurrent.duration.Duration import scala.language.higherKinds /** @@ -216,6 +216,9 @@ case class RequestT[U[_], T, +S]( def streamBody[S2 >: S](b: S2): RequestT[U, T, S2] = copy[U, T, S2](body = StreamBody(b)) + def readTimeout(t: Duration): RequestT[U, T, S] = + this.copy(options = options.copy(readTimeout = t)) + def response[T2, S2 >: S](ra: ResponseAs[T2, S2]): RequestT[U, T2, S2] = this.copy(response = ra) @@ -281,4 +284,4 @@ class SpecifyAuthScheme[U[_], T, +S](hn: String, rt: RequestT[U, T, S]) { rt.header(hn, s"Bearer $token") } -case class RequestOptions(followRedirects: Boolean) +case class RequestOptions(followRedirects: Boolean, readTimeout: Duration) diff --git a/core/src/main/scala/com/softwaremill/sttp/SttpHandler.scala b/core/src/main/scala/com/softwaremill/sttp/SttpHandler.scala index 248356d..b2019dc 100644 --- a/core/src/main/scala/com/softwaremill/sttp/SttpHandler.scala +++ b/core/src/main/scala/com/softwaremill/sttp/SttpHandler.scala @@ -1,6 +1,7 @@ package com.softwaremill.sttp import scala.language.higherKinds +import scala.concurrent.duration._ /** * @tparam R The type constructor in which responses are wrapped. E.g. `Id` @@ -19,3 +20,7 @@ trait SttpHandler[R[_], -S] { */ def responseMonad: MonadError[R] } + +object SttpHandler { + private[sttp] val DefaultConnectionTimeout = 30.seconds +}
\ No newline at end of file diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala index d64acfe..a9950be 100644 --- a/core/src/main/scala/com/softwaremill/sttp/package.scala +++ b/core/src/main/scala/com/softwaremill/sttp/package.scala @@ -7,6 +7,7 @@ import java.nio.file.Path import scala.annotation.{implicitNotFound, tailrec} import scala.language.higherKinds import scala.collection.immutable.Seq +import scala.concurrent.duration._ package object sttp { type Id[X] = X @@ -26,6 +27,8 @@ package object sttp { */ type BodySerializer[B] = B => BasicRequestBody + val DefaultReadTimeout: Duration = 1.minute + // constants private[sttp] val ContentTypeHeader = "Content-Type" @@ -55,13 +58,14 @@ 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), - 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 @@ -266,9 +270,4 @@ package object sttp { implicit class UriContext(val sc: StringContext) extends AnyVal { def uri(args: Any*): Uri = UriInterpolator.interpolate(sc, args: _*) } - - // default handler - - val HttpURLConnectionHandler: SttpHandler[Id, Nothing] = - new FollowRedirectsHandler[Id, Nothing](new HttpURLConnectionHandler()) } diff --git a/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala b/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala index 5773cb1..e62112a 100644 --- a/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala +++ b/core/src/test/scala/com/softwaremill/sttp/RequestTests.scala @@ -66,4 +66,8 @@ class RequestTests extends FlatSpec with Matchers { .find(_._1.equalsIgnoreCase(ContentLengthHeader)) .map(_._2) should be(Some("10")) } + + "request timeout" should "use default if not overridden" in { + sttp.options.readTimeout should be(DefaultReadTimeout) + } } |