diff options
author | adamw <adam@warski.org> | 2017-10-06 14:19:44 +0200 |
---|---|---|
committer | adamw <adam@warski.org> | 2017-10-06 14:19:44 +0200 |
commit | bb7abc189d9a5f079caa47a4508b5ae585dc8bcf (patch) | |
tree | 4d096e1b0c78156df923a7cf3282a86507b8ef8b /core | |
parent | 43baccc0edf12e8951c903d6697d7ee24a201e63 (diff) | |
download | sttp-bb7abc189d9a5f079caa47a4508b5ae585dc8bcf.tar.gz sttp-bb7abc189d9a5f079caa47a4508b5ae585dc8bcf.tar.bz2 sttp-bb7abc189d9a5f079caa47a4508b5ae585dc8bcf.zip |
#10: add proxy support
Diffstat (limited to 'core')
3 files changed, 63 insertions, 14 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala index 7e87795..3d6921b 100644 --- a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala +++ b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala @@ -9,22 +9,21 @@ import java.util.concurrent.ThreadLocalRandom import java.util.zip.{GZIPInputStream, InflaterInputStream} import scala.annotation.tailrec -import scala.io.Source import scala.collection.JavaConverters._ -import scala.concurrent.duration.{Duration, FiniteDuration} +import scala.concurrent.duration.Duration +import scala.io.Source class HttpURLConnectionBackend private ( - connectionTimeout: FiniteDuration, + opts: SttpBackendOptions, customizeConnection: HttpURLConnection => Unit) extends SttpBackend[Id, Nothing] { override def send[T](r: Request[T, Nothing]): Response[T] = { - val c = - new URL(r.uri.toString).openConnection().asInstanceOf[HttpURLConnection] + val c = openConnection(r.uri) 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)) + c.setConnectTimeout(timeout(opts.connectionTimeout)) // redirects are handled by FollowRedirectsBackend c.setInstanceFollowRedirects(false) @@ -55,6 +54,17 @@ class HttpURLConnectionBackend private ( override def responseMonad: MonadError[Id] = IdMonad + private def openConnection(uri: Uri): HttpURLConnection = { + val url = new URL(uri.toString) + val conn = opts.proxy match { + case None => url.openConnection() + case Some(p) => + url.openConnection(p.asJava) + } + + conn.asInstanceOf[HttpURLConnection] + } + private def writeBody(body: RequestBody[Nothing], c: HttpURLConnection): Option[OutputStream] = { body match { @@ -268,11 +278,10 @@ class HttpURLConnectionBackend private ( object HttpURLConnectionBackend { - def apply(connectionTimeout: FiniteDuration = - SttpBackend.DefaultConnectionTimeout, + def apply(options: SttpBackendOptions = SttpBackendOptions.Default, customizeConnection: HttpURLConnection => Unit = { _ => () }): SttpBackend[Id, Nothing] = new FollowRedirectsBackend[Id, Nothing]( - new HttpURLConnectionBackend(connectionTimeout, customizeConnection)) + new HttpURLConnectionBackend(options, customizeConnection)) } diff --git a/core/src/main/scala/com/softwaremill/sttp/SttpBackend.scala b/core/src/main/scala/com/softwaremill/sttp/SttpBackend.scala index 6eb312f..e3d5399 100644 --- a/core/src/main/scala/com/softwaremill/sttp/SttpBackend.scala +++ b/core/src/main/scala/com/softwaremill/sttp/SttpBackend.scala @@ -1,7 +1,6 @@ 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` @@ -20,7 +19,3 @@ trait SttpBackend[R[_], -S] { */ def responseMonad: MonadError[R] } - -object SttpBackend { - private[sttp] val DefaultConnectionTimeout = 30.seconds -} diff --git a/core/src/main/scala/com/softwaremill/sttp/SttpBackendOptions.scala b/core/src/main/scala/com/softwaremill/sttp/SttpBackendOptions.scala new file mode 100644 index 0000000..e515173 --- /dev/null +++ b/core/src/main/scala/com/softwaremill/sttp/SttpBackendOptions.scala @@ -0,0 +1,45 @@ +package com.softwaremill.sttp + +import java.net.InetSocketAddress + +import scala.concurrent.duration._ +import com.softwaremill.sttp.SttpBackendOptions._ + +case class SttpBackendOptions( + connectionTimeout: FiniteDuration, + proxy: Option[Proxy] +) { + + def connectionTimeout(ct: FiniteDuration): SttpBackendOptions = + this.copy(connectionTimeout = ct) + def httpProxy(host: String, port: Int): SttpBackendOptions = + this.copy(proxy = Some(Proxy(host, port, ProxyType.Http))) + def socksProxy(host: String, port: Int): SttpBackendOptions = + this.copy(proxy = Some(Proxy(host, port, ProxyType.Socks))) +} + +object SttpBackendOptions { + case class Proxy(host: String, port: Int, proxyType: ProxyType) { + def asJava = new java.net.Proxy(proxyType.asJava, inetSocketAddress) + def inetSocketAddress: InetSocketAddress = + InetSocketAddress.createUnresolved(host, port) + } + + sealed trait ProxyType { + def asJava: java.net.Proxy.Type + } + object ProxyType { + case object Http extends ProxyType { + override def asJava: java.net.Proxy.Type = java.net.Proxy.Type.HTTP + } + case object Socks extends ProxyType { + override def asJava: java.net.Proxy.Type = java.net.Proxy.Type.SOCKS + } + } + + val Default: SttpBackendOptions = SttpBackendOptions(30.seconds, None) + + def connectionTimeout(ct: FiniteDuration): SttpBackendOptions = Default.connectionTimeout(ct) + def httpProxy(host: String, port: Int): SttpBackendOptions = Default.httpProxy(host, port) + def socksProxy(host: String, port: Int): SttpBackendOptions = Default.socksProxy(host, port) +} |