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

ammonite.main.ProxyFromEnv.scala Maven / Gradle / Ivy

package ammonite.main

/**
 * Give Ammonite the ability to read (linux) system proxy environment variables
 * and convert them into java proxy properties. Which allows Ammonite to work
 * through proxy automatically, instead of setting `System.properties` manually.
 *
 * See issue 460.
 *
 * Parameter pattern:
 * https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
 *
 * Created by cuz on 17-5-21.
 */
private[ammonite] object ProxyFromEnv {
  private lazy val KeyPattern = """([\w\d]+)_proxy""".r
  private lazy val UrlPattern = """([\w\d]+://)?(.+@)?([\w\d\.\-]+):(\d+)/?""".r

  /**
   * Get current proxy environment variables.
   */
  private def getEnvs =
    sys.env.map { case (k, v) => (k.toLowerCase, v.toLowerCase) }
      .filterKeys(_.endsWith("proxy"))
      .toMap

  /**
   * Convert single proxy environment variable to corresponding system proxy properties.
   */
  private def envToProps(env: (String, String)): Map[String, String] = env match {
    case ("no_proxy", noProxySeq) =>
      val converted = noProxySeq.split(""",""").mkString("|")
      // https uses the same as http's. Ftp need not to be set here.
      Map("http.nonProxyHosts" -> converted)

    case (KeyPattern(proto), UrlPattern(_, cred, host, port)) =>
      val propHost = s"$proto.proxyHost" -> host
      val propPort = s"$proto.proxyPort" -> port
      val propCred = if (cred.isDefined) {
        val credPair = cred.dropRight(1).split(":")
        val propUser = s"$proto.proxyUser" -> credPair.head
        val propPassword = credPair.drop(1).map(s"$proto.proxyPassword" -> _)
        Seq(propUser) ++ propPassword
      } else Nil
      (Seq(propHost, propPort) ++ propCred).toMap
    case bad => Map.empty
  }

  /**
   * Set system proxy properties from environment variables.
   * Existing properties will not be overwritten.
   */
  def setPropProxyFromEnv(envs: Map[String, String] = this.getEnvs): Unit = {
    val sysProps = sys.props
    val proxyProps = envs.flatMap { env =>
      val props = envToProps(env)
      props
    }.filter(p => !sysProps.exists(sp => sp._1 == p._1))
    sysProps ++= proxyProps
  }

  /**
   * helper implicit conversion: add isDefined method to String.
   */
  implicit private class StringIsDefined(s: String) {
    def isDefined: Boolean = s != null && s.length > 0
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy