All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sttp.client3.internal.ToRfc2616Converter.scala Maven / Gradle / Ivy

There is a newer version: 3.10.1
Show newest version
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]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy