diff options
author | adamw <adam@warski.org> | 2017-07-21 14:43:20 +0200 |
---|---|---|
committer | adamw <adam@warski.org> | 2017-07-21 14:43:20 +0200 |
commit | a6b4a71d59da928ddb326671b1058501bb1a45c5 (patch) | |
tree | 8b1a2bc5d4196ff252d5ccd00cd546657f92fd14 /core | |
parent | 2d099f6832f6e362b9a4cd48e81a16c8d77adeaf (diff) | |
download | sttp-a6b4a71d59da928ddb326671b1058501bb1a45c5.tar.gz sttp-a6b4a71d59da928ddb326671b1058501bb1a45c5.tar.bz2 sttp-a6b4a71d59da928ddb326671b1058501bb1a45c5.zip |
AcceptEncoding + response decompression
Diffstat (limited to 'core')
-rw-r--r-- | core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionSttpHandler.scala | 20 | ||||
-rw-r--r-- | core/src/main/scala/com/softwaremill/sttp/package.scala | 25 |
2 files changed, 38 insertions, 7 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionSttpHandler.scala b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionSttpHandler.scala index 0a86f97..f5a5971 100644 --- a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionSttpHandler.scala +++ b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionSttpHandler.scala @@ -3,7 +3,9 @@ package com.softwaremill.sttp import java.io._ import java.net.HttpURLConnection import java.nio.channels.Channels +import java.nio.charset.CharacterCodingException import java.nio.file.Files +import java.util.zip.{GZIPInputStream, InflaterInputStream} import com.softwaremill.sttp.model._ @@ -23,6 +25,8 @@ object HttpURLConnectionSttpHandler extends SttpHandler[Id, Nothing] { val is = c.getInputStream readResponse(c, is, r.responseAs) } catch { + case e: CharacterCodingException => throw e + case e: UnsupportedEncodingException => throw e case _: IOException if c.getResponseCode != -1 => readResponse(c, c.getErrorStream, r.responseAs) } @@ -85,11 +89,15 @@ object HttpURLConnectionSttpHandler extends SttpHandler[Id, Nothing] { val headers = c.getHeaderFields.asScala.toVector .filter(_._1 != null) .flatMap { case (k, vv) => vv.asScala.map((k, _)) } - Response(readResponseBody(is, responseAs), c.getResponseCode, headers) + val contentEncoding = Option(c.getHeaderField(ContentEncodingHeader)) + Response(readResponseBody(wrapInput(contentEncoding, is), responseAs), + c.getResponseCode, + headers) } private def readResponseBody[T](is: InputStream, responseAs: ResponseAs[T, Nothing]): T = { + def asString(enc: String) = Source.fromInputStream(is, enc).mkString responseAs match { @@ -128,4 +136,14 @@ object HttpURLConnectionSttpHandler extends SttpHandler[Id, Nothing] { throw new IllegalStateException() } } + + private def wrapInput(contentEncoding: Option[String], + is: InputStream): InputStream = + contentEncoding.map(_.toLowerCase) match { + case None => is + case Some("gzip") => new GZIPInputStream(is) + case Some("deflate") => new InflaterInputStream(is) + case Some(ce) => + throw new UnsupportedEncodingException(s"Unsupported encoding: $ce") + } } diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala index d51d6c5..aa2224a 100644 --- a/core/src/main/scala/com/softwaremill/sttp/package.scala +++ b/core/src/main/scala/com/softwaremill/sttp/package.scala @@ -181,6 +181,8 @@ package object sttp { new SpecifyAuthScheme[U, T, S](AuthorizationHeader, this) def proxyAuth: SpecifyAuthScheme[U, T, S] = new SpecifyAuthScheme[U, T, S](ProxyAuthorizationHeader, this) + def acceptEncoding(encoding: String): RequestT[U, T, S] = + header(AcceptEncodingHeader, encoding) /** * Uses the `utf-8` encoding. @@ -333,11 +335,6 @@ package object sttp { rt.header(hn, s"Bearer $token") } - object RequestT { - val empty: RequestT[Empty, String, Nothing] = - RequestT[Empty, String, Nothing](None, None, NoBody, Vector(), asString) - } - type PartialRequest[T, +S] = RequestT[Empty, T, S] type Request[T, +S] = RequestT[Id, T, S] @@ -352,6 +349,8 @@ package object sttp { private[sttp] val CookieHeader = "Cookie" private[sttp] val AuthorizationHeader = "Authorization" private[sttp] val ProxyAuthorizationHeader = "Proxy-Authorization" + private[sttp] val AcceptEncodingHeader = "Accept-Encoding" + private[sttp] val ContentEncodingHeader = "Content-Encoding" private val Utf8 = "utf-8" private val ApplicationOctetStreamContentType = "application/octet-stream" @@ -359,7 +358,21 @@ package object sttp { private val TextPlainContentType = "text/plain" private val MultipartFormDataContentType = "multipart/form-data" - val sttp: RequestT[Empty, String, Nothing] = RequestT.empty + /** + * An empty request with no headers. + */ + val emptyRequest: RequestT[Empty, String, Nothing] = + RequestT[Empty, String, Nothing](None, None, NoBody, Vector(), asString) + + /** + * A starting request, with the following modifications comparing to + * `emptyRequest`: + * + * - `Accept-Encoding` set to `gzip, deflate` (handled automatically by the + * library) + */ + val sttp: RequestT[Empty, String, Nothing] = + emptyRequest.acceptEncoding("gzip, deflate") private def contentTypeWithEncoding(ct: String, enc: String) = s"$ct; charset=$enc" |