aboutsummaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionHandler.scala18
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/RequestT.scala7
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/SttpHandler.scala5
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/package.scala23
4 files changed, 38 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())
}