Skip to content

Commit

Permalink
feature/softwaremill#1918 HttpClientBackend compress impl
Browse files Browse the repository at this point in the history
  • Loading branch information
ifedorov committed Apr 26, 2024
1 parent 5542ffc commit cab4004
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 35 deletions.
25 changes: 2 additions & 23 deletions core/src/main/scala/sttp/client4/request.scala
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,7 @@ case class Request[T](
* unchanged.
*/
def send[F[_]](backend: Backend[F]): F[Response[T]] =
(this.options.encoding, this.body) match {
case (Nil, _) => backend.send(this)
case (codecs, b: BasicBodyPart) if codecs.nonEmpty =>
val (newBody, newLength) = ContentCodec.encode(b, codecs) match {
case Left(err) => throw new EncodingException(this, err)
case Right(v) => v
}
val newReq = this.contentLength(newLength.toLong).copyWithBody(newBody)
backend.send(newReq)

case _ => backend.send(this)
}
backend.send(this)

/** Sends the request synchronously, using the given backend.
*
Expand All @@ -170,17 +159,7 @@ case class Request[T](
* unchanged.
*/
def send(backend: SyncBackend): Response[T] =
(this.options.encoding, this.body) match {
case (codecs, b: BasicBodyPart) if codecs.nonEmpty =>
val (newBody, newLength) = ContentCodec.encode(b, codecs) match {
case Left(err) => throw new EncodingException(this, err)
case Right(v) => v
}
val newReq = this.contentLength(newLength.toLong).copyWithBody(newBody)
backend.send(newReq)

case _ => backend.send(this)
}
backend.send(this)
}

object Request {
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/scala/sttp/client4/requestBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ trait PartialRequestBuilder[+PR <: PartialRequestBuilder[PR, R], +R]
*/
def body(fs: Seq[(String, String)], encoding: String): PR = formDataBody(fs, encoding)

def body(b: BasicBody): PR = copyWithBody(b)

def multipartBody(ps: Seq[Part[BasicBodyPart]]): PR = copyWithBody(BasicMultipartBody(ps))

def multipartBody(p1: Part[BasicBodyPart], ps: Part[BasicBodyPart]*): PR = copyWithBody(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package sttp.client4.internal.httpclient

import sttp.capabilities.Streams
import sttp.client4.internal.SttpToJavaConverters.toJavaSupplier
import sttp.client4.internal.{throwNestedMultipartNotAllowed, Utf8}
import sttp.client4.internal.{throwNestedMultipartNotAllowed, ContentEncoding, Utf8}
import sttp.client4._
import sttp.client4.internal.encoders.ContentCodec
import sttp.model.{Header, HeaderNames, Part}
import sttp.monad.MonadError
import sttp.monad.syntax._
Expand All @@ -25,26 +26,44 @@ private[client4] trait BodyToHttpClient[F[_], S] {
builder: HttpRequest.Builder,
contentType: Option[String]
): F[BodyPublisher] = {
val body = request.body match {
case NoBody => BodyPublishers.noBody().unit
case StringBody(b, _, _) => BodyPublishers.ofString(b).unit
case ByteArrayBody(b, _) => BodyPublishers.ofByteArray(b).unit
case ByteBufferBody(b, _) =>
val body: F[BodyPublisher] = request.options.encoding -> request.body match {
case (_, NoBody) => BodyPublishers.noBody().unit
case (Nil, StringBody(b, _, _)) => BodyPublishers.ofString(b).unit
case (Nil, ByteArrayBody(b, _)) => BodyPublishers.ofByteArray(b).unit
case (Nil, ByteBufferBody(b, _)) =>
if (b.hasArray) BodyPublishers.ofByteArray(b.array(), 0, b.limit()).unit
else { val a = new Array[Byte](b.remaining()); b.get(a); BodyPublishers.ofByteArray(a).unit }
case InputStreamBody(b, _) => BodyPublishers.ofInputStream(toJavaSupplier(() => b)).unit
case FileBody(f, _) => BodyPublishers.ofFile(f.toFile.toPath).unit
case StreamBody(s) => streamToPublisher(s.asInstanceOf[streams.BinaryStream])
case m: MultipartBody[_] =>
case (Nil, InputStreamBody(b, _)) => BodyPublishers.ofInputStream(toJavaSupplier(() => b)).unit
case (Nil, FileBody(f, _)) => BodyPublishers.ofFile(f.toFile.toPath).unit
case (_, StreamBody(s)) => streamToPublisher(s.asInstanceOf[streams.BinaryStream])
case (_, m: MultipartBody[_]) =>
val multipartBodyPublisher = multipartBody(m.parts)
val baseContentType = contentType.getOrElse("multipart/form-data")
builder.header(HeaderNames.ContentType, s"$baseContentType; boundary=${multipartBodyPublisher.getBoundary}")
multipartBodyPublisher.build().unit

case (coders, r: BasicBodyPart) =>
ContentCodec.encode(r, coders) match {
case Left(err) => monad.error(err)
case Right(newBody) =>
val (body, length) = newBody
val newRequest = request
.contentLength(length.toLong)
.body(body)
.withOptions(request.options.copy(encoding = Nil))
apply[T](newRequest, builder, contentType) // can we avoid recursion?
}
}

(request.contentLength: Option[Long]) match {
case None => body
case Some(cl) => body.map(b => withKnownContentLength(b, cl))
case None => body
case Some(cl) =>
body.map { b =>
if (b.contentLength() >= 0) // see BodyPublisher.contentLength docs
withKnownContentLength(b, b.contentLength())
else
withKnownContentLength(b, cl)
}
}
}

Expand Down

0 comments on commit cab4004

Please sign in to comment.