Skip to content

Instantly share code, notes, and snippets.

@Jire
Created January 5, 2023 06:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jire/aac72eaaaa9fa4152947efd314238269 to your computer and use it in GitHub Desktop.
Save Jire/aac72eaaaa9fa4152947efd314238269 to your computer and use it in GitHub Desktop.
Creates a ChromeDriver for Selenium that uses authenticated proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
import java.net.URI
import java.nio.file.FileSystems
import java.nio.file.Files
object ChromeDriverProxied {
operator fun get(
proxyHost: String, proxyPort: Int,
proxyUser: String, proxyPass: String
): WebDriver {
val tempDir = Files.createTempDirectory("chrome-driver-proxied")
val manifestJsonPath = tempDir.resolve("manifest.json")
Files.writeString(manifestJsonPath, MANIFEST_JSON_TEMPLATE)
val backgroundJsPath = tempDir.resolve("background.js")
Files.writeString(backgroundJsPath, BACKGROUND_JS_TEMPLATE.format(proxyHost, proxyPort, proxyUser, proxyPass))
val zipFile = tempDir.resolve("proxy_auth_plugin.zip")
val zipFileUri = URI.create("jar:${zipFile.toUri()}")
val env = mapOf(
"create" to "true",
"encoding" to "UTF-8"
)
FileSystems.newFileSystem(zipFileUri, env).use { fs ->
Files.copy(manifestJsonPath, fs.getPath(manifestJsonPath.fileName.toString()))
Files.copy(backgroundJsPath, fs.getPath(backgroundJsPath.fileName.toString()))
}
val options = ChromeOptions().addExtensions(zipFile.toFile())
return ChromeDriver(options)
}
private const val MANIFEST_JSON_TEMPLATE = """{
"version": "1.0.0",
"manifest_version": 2,
"name": "Chrome Proxy",
"permissions": [
"proxy",
"tabs",
"unlimitedStorage",
"storage",
"<all_urls>",
"webRequest",
"webRequestBlocking"
],
"background": {
"scripts": ["background.js"]
},
"minimum_chrome_version":"22.0.0"
}"""
private const val BACKGROUND_JS_TEMPLATE = """var config = {
mode: "fixed_servers",
rules: {
singleProxy: {
scheme: "http",
host: "%s",
port: parseInt(%s)
},
bypassList: ["localhost"]
}
};
chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});
function callbackFn(details) {
return {
authCredentials: {
username: "%s",
password: "%s"
}
};
}
chrome.webRequest.onAuthRequired.addListener(
callbackFn,
{urls: ["<all_urls>"]},
['blocking']
);"""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment