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

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

The newest version!
package sttp.client3.internal

import sttp.client3._
import sttp.model._
import sttp.client3.NoBody
import sttp.model.MediaType

class ToCurlConverter[R <: RequestT[Identity, _, _]] {

  def apply(request: R): String = apply(request, HeaderNames.SensitiveHeaders)

  def apply(request: R, sensitiveHeaders: Set[String]): String = {
    val params = List(
      extractMethod(_),
      extractUrl(_),
      (r: R) => extractHeaders(r, sensitiveHeaders),
      extractBody(_),
      extractOptions(_)
    )
      .map(addSpaceIfNotEmpty)
      .reduce((acc, item) => (r: R) => acc(r) + item(r))
      .apply(request)

    s"""curl$params"""
  }

  private def extractMethod(r: R): String = {
    s"--request ${r.method.method}"
  }

  private def extractUrl(r: R): String = {
    s"--url '${r.uri}'"
  }

  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 => s"--header '${h.toStringSafe(sensitiveHeaders)}'")
      .mkString(newline)
  }

  private def extractBody(r: R): String = {
    r.body match {
      case StringBody(text, _, _) => s"""--data-raw '${text.replace("'", "\\'")}'"""
      case ByteArrayBody(_, _)    => s"--data-binary "
      case ByteBufferBody(_, _)   => s"--data-binary "
      case InputStreamBody(_, _)  => s"--data-binary "
      case StreamBody(_)          => s"--data-binary "
      case MultipartBody(parts)   => handleMultipartBody(parts)
      case FileBody(file, _)      => s"""--data-binary @${file.name}"""
      case NoBody                 => ""
    }
  }

  def handleMultipartBody(parts: Seq[Part[RequestBody[_]]]): String = {
    parts
      .map { p =>
        p.body match {
          case StringBody(s, _, _) => s"--form '${p.name}=$s'"
          case FileBody(f, _)      => s"--form '${p.name}=@${f.name}'"
          case _                   => s"--data-binary "
        }
      }
      .mkString(newline)
  }

  private def extractOptions(r: R): String = {
    if (r.options.followRedirects) {
      s"--location${newline}--max-redirs ${r.options.maxRedirects}"
    } else {
      ""
    }
  }

  private def addSpaceIfNotEmpty(fInput: R => String): R => String =
    t => if (fInput(t).isEmpty) "" else s"${newline}${fInput(t)}"

  private def newline: String = " \\\n  "
}

object ToCurlConverter {
  def requestToCurl[R <: Request[_, _]]: ToCurlConverter[R] = new ToCurlConverter[R]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy