aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authoradamw <adam@warski.org>2017-07-16 09:59:09 +0200
committeradamw <adam@warski.org>2017-07-16 09:59:09 +0200
commitb1844f09d78e035d85302310e2ba55929cd5fc52 (patch)
treef1659e57ff863dd81f6935e422d9f9043fc66f40 /core/src
parent062ab1ac1bd4fa9f4602ae31419c60a7e6d991bf (diff)
downloadsttp-b1844f09d78e035d85302310e2ba55929cd5fc52.tar.gz
sttp-b1844f09d78e035d85302310e2ba55929cd5fc52.tar.bz2
sttp-b1844f09d78e035d85302310e2ba55929cd5fc52.zip
Streaming tests, comments
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala3
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/Response.scala12
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala15
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/package.scala91
4 files changed, 82 insertions, 39 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala b/core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala
index dc6f8a2..50f6d76 100644
--- a/core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/HttpConnectionSttpHandler.scala
@@ -120,7 +120,8 @@ object HttpConnectionSttpHandler extends SttpHandler[Id, Nothing] {
r.parse(asString(enc))
case ResponseAsStream() =>
- // only possible when the user requests the response as a stream of Nothing. Oh well ...
+ // only possible when the user requests the response as a stream of
+ // Nothing. Oh well ...
throw new IllegalStateException()
}
}
diff --git a/core/src/main/scala/com/softwaremill/sttp/Response.scala b/core/src/main/scala/com/softwaremill/sttp/Response.scala
index a4d60a5..44c39c3 100644
--- a/core/src/main/scala/com/softwaremill/sttp/Response.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/Response.scala
@@ -47,9 +47,9 @@ case class Cookie(name: String,
object Cookie {
def apply(hc: HttpCookie, h: String): Cookie = {
- // HttpCookie.parse has special handling for the expires attribute and turns it into max-age
- // if the cookie contains an expires header; hand-parsing in such case to preserve the
- // values from the cookie
+ // HttpCookie.parse has special handling for the expires attribute and
+ // turns it into max-age if the cookie contains an expires header;
+ // hand-parsing in such case to preserve the values from the cookie
val lch = h.toLowerCase
val (expires, maxAge) = if (lch.contains("expires=")) {
val tokenizer = new StringTokenizer(h, ";")
@@ -85,7 +85,8 @@ object Cookie {
}
/**
- * Modified version of `HttpCookie.expiryDate2DeltaSeconds` to return a `ZonedDateTime`, not a second-delta.
+ * Modified version of `HttpCookie.expiryDate2DeltaSeconds` to return a
+ * `ZonedDateTime`, not a second-delta.
*/
private def expiryDate2ZonedDateTime(
dateString: String): Option[ZonedDateTime] = {
@@ -98,7 +99,8 @@ object Cookie {
df.set2DigitYearStart(cal.getTime)
try {
cal.setTime(df.parse(dateString))
- if (!format.contains("yyyy")) { // 2-digit years following the standard set
+ if (!format.contains("yyyy")) {
+ // 2-digit years following the standard set
// out it rfc 6265
var year = cal.get(Calendar.YEAR)
year %= 100
diff --git a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala
index 1216a1e..a8099a4 100644
--- a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala
@@ -44,9 +44,10 @@ object UriInterpolator {
case Array(x) =>
if (!x.matches("[a-zA-Z0-9+\\.\\-]*")) {
- // anything else than the allowed characters in scheme suggest that there is no scheme
- // assuming whatever we parsed so far is part of authority, and parsing the rest
- // see https://stackoverflow.com/questions/3641722/valid-characters-for-uri-schemes
+ // anything else than the allowed characters in scheme suggest that
+ // there is no scheme assuming whatever we parsed so far is part of
+ // authority, and parsing the rest; see
+ // https://stackoverflow.com/questions/3641722/valid-characters-for-uri-schemes
Authority(Scheme(""), v).parseS(x)
} else append(x)
}
@@ -54,8 +55,8 @@ object UriInterpolator {
override def parseE(e: Any): UriBuilder = {
def encodeIfNotInitialEndpoint(s: String) = {
- // special case: when this is the first expression, contains a complete schema with :// and nothing is yet parsed
- // not escaping the contents
+ // special case: when this is the first expression, contains a complete
+ // schema with :// and nothing is yet parsed not escaping the contents
if (v.isEmpty && s.contains("://")) s else encode(s)
}
@@ -314,8 +315,8 @@ object UriInterpolator {
private def encode(s: Any): String = {
// space is encoded as a +, which is only valid in the query;
- // in other contexts, it must be percent-encoded
- // see https://stackoverflow.com/questions/2678551/when-to-encode-space-to-plus-or-20
+ // in other contexts, it must be percent-encoded; see
+ // https://stackoverflow.com/questions/2678551/when-to-encode-space-to-plus-or-20
URLEncoder.encode(String.valueOf(s), "UTF-8").replaceAll("\\+", "%20")
}
diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala
index baf4061..763b6c3 100644
--- a/core/src/main/scala/com/softwaremill/sttp/package.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/package.scala
@@ -26,6 +26,10 @@ package object sttp {
ResponseAsString(encoding)
def responseAsByteArray: ResponseAs[Array[Byte], Nothing] =
ResponseAsByteArray
+
+ /**
+ * Uses `utf-8` encoding.
+ */
def responseAsParams: ResponseAs[Seq[(String, String)], Nothing] =
responseAsParams(Utf8)
def responseAsParams(
@@ -35,8 +39,9 @@ package object sttp {
def responseAsStream[S]: ResponseAs[S, S] = ResponseAsStream[S, S]()
/**
- * Use the factory methods `multiPart` to conveniently create instances of this class. A part can be then
- * further customised using `fileName`, `contentType` and `header` methods.
+ * Use the factory methods `multiPart` to conveniently create instances of
+ * this class. A part can be then further customised using `fileName`,
+ * `contentType` and `header` methods.
*/
case class MultiPart(name: String,
data: BasicRequestBody,
@@ -50,7 +55,8 @@ package object sttp {
}
/**
- * Content type will be set to `text/plain` with `utf-8` encoding, can be overridden later using the `contentType` method.
+ * Content type will be set to `text/plain` with `utf-8` encoding, can be
+ * overridden later using the `contentType` method.
*/
def multiPart(name: String, data: String): MultiPart =
MultiPart(name,
@@ -59,7 +65,8 @@ package object sttp {
Some(contentTypeWithEncoding(TextPlainContentType, Utf8)))
/**
- * Content type will be set to `text/plain` with `utf-8` encoding, can be overridden later using the `contentType` method.
+ * Content type will be set to `text/plain` with `utf-8` encoding, can be
+ * overridden later using the `contentType` method.
*/
def multiPart(name: String, data: String, encoding: String): MultiPart =
MultiPart(name,
@@ -68,7 +75,8 @@ package object sttp {
Some(contentTypeWithEncoding(TextPlainContentType, Utf8)))
/**
- * Content type will be set to `application/octet-stream`, can be overridden later using the `contentType` method.
+ * Content type will be set to `application/octet-stream`, can be overridden
+ * later using the `contentType` method.
*/
def multiPart(name: String, data: Array[Byte]): MultiPart =
MultiPart(name,
@@ -76,7 +84,8 @@ package object sttp {
contentType = Some(ApplicationOctetStreamContentType))
/**
- * Content type will be set to `application/octet-stream`, can be overridden later using the `contentType` method.
+ * Content type will be set to `application/octet-stream`, can be overridden
+ * later using the `contentType` method.
*/
def multiPart(name: String, data: ByteBuffer): MultiPart =
MultiPart(name,
@@ -84,7 +93,8 @@ package object sttp {
contentType = Some(ApplicationOctetStreamContentType))
/**
- * Content type will be set to `application/octet-stream`, can be overridden later using the `contentType` method.
+ * Content type will be set to `application/octet-stream`, can be overridden
+ * later using the `contentType` method.
*/
def multiPart(name: String, data: InputStream): MultiPart =
MultiPart(name,
@@ -92,13 +102,15 @@ package object sttp {
contentType = Some(ApplicationOctetStreamContentType))
/**
- * Content type will be set to `application/octet-stream`, can be overridden later using the `contentType` method.
+ * Content type will be set to `application/octet-stream`, can be overridden
+ * later using the `contentType` method.
*/
def multiPart(name: String, data: File): MultiPart =
multiPart(name, data.toPath)
/**
- * Content type will be set to `application/octet-stream`, can be overridden later using the `contentType` method.
+ * Content type will be set to `application/octet-stream`, can be overridden
+ * later using the `contentType` method.
*/
def multiPart(name: String, data: Path): MultiPart =
MultiPart(name,
@@ -106,6 +118,17 @@ package object sttp {
fileName = Some(data.getFileName.toString),
contentType = Some(ApplicationOctetStreamContentType))
+ /**
+ * @tparam U Specifies if the method & uri are specified. By default can be
+ * either:
+ * * `Empty`, which is a type constructor which always resolves to
+ * `None`. This type of request is aliased to `PartialRequest`:
+ * there's no method and uri specified, and the request cannot be
+ * sent.
+ * * `Id`, which is an identity type constructor. This type of
+ * request is aliased to `Request`: the method and uri are
+ * specified, and the request can be sent.
+ */
case class RequestTemplate[U[_]](
method: U[Method],
uri: U[URI],
@@ -159,12 +182,14 @@ package object sttp {
/**
* Uses the `utf-8` encoding.
- * If content type is not yet specified, will be set to `text/plain` with `utf-8` encoding.
+ * If content type is not yet specified, will be set to `text/plain`
+ * with `utf-8` encoding.
*/
def body(b: String): RequestTemplate[U] = body(b, Utf8)
/**
- * If content type is not yet specified, will be set to `text/plain` with the given encoding.
+ * If content type is not yet specified, will be set to `text/plain`
+ * with the given encoding.
*/
def body(b: String, encoding: String): RequestTemplate[U] =
setContentTypeIfMissing(
@@ -172,33 +197,38 @@ package object sttp {
.copy(body = StringBody(b, encoding))
/**
- * If content type is not yet specified, will be set to `application/octet-stream`.
+ * If content type is not yet specified, will be set to
+ * `application/octet-stream`.
*/
def body(b: Array[Byte]): RequestTemplate[U] =
setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
body = ByteArrayBody(b))
/**
- * If content type is not yet specified, will be set to `application/octet-stream`.
+ * If content type is not yet specified, will be set to
+ * `application/octet-stream`.
*/
def body(b: ByteBuffer): RequestTemplate[U] =
setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
body = ByteBufferBody(b))
/**
- * If content type is not yet specified, will be set to `application/octet-stream`.
+ * If content type is not yet specified, will be set to
+ * `application/octet-stream`.
*/
def body(b: InputStream): RequestTemplate[U] =
setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
body = InputStreamBody(b))
/**
- * If content type is not yet specified, will be set to `application/octet-stream`.
+ * If content type is not yet specified, will be set to
+ * `application/octet-stream`.
*/
def body(b: File): RequestTemplate[U] = body(b.toPath)
/**
- * If content type is not yet specified, will be set to `application/octet-stream`.
+ * If content type is not yet specified, will be set to
+ * `application/octet-stream`.
*/
def body(b: Path): RequestTemplate[U] =
setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
@@ -206,34 +236,39 @@ package object sttp {
/**
* Encodes the given parameters as form data using `utf-8`.
- * If content type is not yet specified, will be set to `application/x-www-form-urlencoded`.
+ * If content type is not yet specified, will be set to
+ * `application/x-www-form-urlencoded`.
*/
def body(fs: Map[String, String]): RequestTemplate[U] =
formDataBody(fs.toList, Utf8)
/**
* Encodes the given parameters as form data.
- * If content type is not yet specified, will be set to `application/x-www-form-urlencoded`.
+ * If content type is not yet specified, will be set to
+ * `application/x-www-form-urlencoded`.
*/
def body(fs: Map[String, String], encoding: String): RequestTemplate[U] =
formDataBody(fs.toList, encoding)
/**
* Encodes the given parameters as form data using `utf-8`.
- * If content type is not yet specified, will be set to `application/x-www-form-urlencoded`.
+ * If content type is not yet specified, will be set to
+ * `application/x-www-form-urlencoded`.
*/
def body(fs: (String, String)*): RequestTemplate[U] =
formDataBody(fs.toList, Utf8)
/**
* Encodes the given parameters as form data.
- * If content type is not yet specified, will be set to `application/x-www-form-urlencoded`.
+ * If content type is not yet specified, will be set to
+ * `application/x-www-form-urlencoded`.
*/
def body(fs: Seq[(String, String)], encoding: String): RequestTemplate[U] =
formDataBody(fs, encoding)
/**
- * If content type is not yet specified, will be set to `application/octet-stream`.
+ * If content type is not yet specified, will be set to
+ * `application/octet-stream`.
*/
def body[T: BodySerializer](b: T): RequestTemplate[U] =
setContentTypeIfMissing(ApplicationOctetStreamContentType).copy(
@@ -242,10 +277,13 @@ package object sttp {
//def multipartData(parts: MultiPart*): RequestTemplate[U] = ???
/**
- * @param responseAs What's the target type to which the response should be read. Needs to be specified upfront
- * so that the response is always consumed and hence there are no requirements on client code
- * to consume it. An exception to this are streaming responses, which need to fully consumed
- * by the client if such a response type is requested.
+ * @param responseAs What's the target type to which the response body
+ * should be read. Needs to be specified upfront
+ * so that the response is always consumed and hence
+ * there are no requirements on client code to consume
+ * it. An exception to this are streaming responses,
+ * which need to fully consumed by the client if such
+ * a response type is requested.
*/
def send[R[_], S, T](responseAs: ResponseAs[T, S])(
implicit handler: SttpHandler[R, S],
@@ -293,7 +331,8 @@ package object sttp {
type Request = RequestTemplate[Id]
@implicitNotFound(
- "This is a partial request, the method & url are not specified. Use .get(...), .post(...) etc. to obtain a non-partial request.")
+ "This is a partial request, the method & url are not specified. Use " +
+ ".get(...), .post(...) etc. to obtain a non-partial request.")
private type IsRequest[U[_]] = RequestTemplate[U] =:= Request
val sttp: RequestTemplate[Empty] = RequestTemplate.empty