sttp.client3.internal.ToRfc2616Converter.scala Maven / Gradle / Ivy
package sttp.client3.internal
import sttp.client3._
import sttp.model._
import scala.util.Random
class ToRfc2616Converter[R <: RequestT[Identity, _, _]] {
private val BoundaryChars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray
def apply(request: R): String = apply(request, HeaderNames.SensitiveHeaders)
def apply(request: R, sensitiveHeaders: Set[String]): String = {
val extractMethod = request.method.method
val extractUri = request.uri
val result = s"$extractMethod $extractUri"
val headers = extractHeaders(request, sensitiveHeaders)
val resultWithHeaders = if (headers.isEmpty) result else result + s"\n$headers"
val body = extractBody(request)
if (body.isEmpty) resultWithHeaders else resultWithHeaders + s"\n\n$body"
}
private def extractBody(r: R): String = {
r.body match {
case StringBody(text, _, _) => s"$text"
case ByteArrayBody(_, _) => ""
case ByteBufferBody(_, _) => ""
case InputStreamBody(_, _) => ""
case StreamBody(_) => ""
case MultipartBody(parts) => handleMultipartBody(parts)
case FileBody(file, _) => s"<${file.name}"
case NoBody => ""
}
}
def handleMultipartBody(parts: Seq[Part[RequestBody[_]]]): String = {
val boundary = generateBoundary()
parts
.map { p =>
p.body match {
case StringBody(s, _, _) =>
s"""--$boundary
|Content-Disposition: form-data; name="${p.name}"
|
|$s\n""".stripMargin
case FileBody(f, _) =>
s"""--$boundary
|Content-Disposition: form-data; name="${p.name}"
|
|< ${f.name}\n""".stripMargin
case _ => s"--$boundary"
}
}
.mkString("") + s"--$boundary--"
}
private def extractHeaders(r: R, sensitiveHeaders: Set[String]): String = {
r.headers
// filtering out compression headers so that the results are human-readable, if possible
.filterNot(_.name.equalsIgnoreCase(HeaderNames.AcceptEncoding))
.map(h => h.toStringSafe(sensitiveHeaders))
.mkString("\n")
}
private def generateBoundary(): String = {
val random = Random
List
.fill(32)(BoundaryChars(random.nextInt(BoundaryChars.length)))
.mkString
}
}
object ToRfc2616Converter {
def requestToRfc2616[R <: Request[_, _]]: ToRfc2616Converter[R] = new ToRfc2616Converter[R]
}