Skip to content

Commit 0e8d226

Browse files
authored
feat: Support HTTP proxies with credentials. (#2176)
1 parent 705033b commit 0e8d226

5 files changed

Lines changed: 52 additions & 1 deletion

File tree

buildSrc/src/main/kotlin/Dependencies.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ object Dependencies {
3636
//endregion ktor
3737

3838
const val LOGBACK = "ch.qos.logback:logback-classic:${Versions.LOGBACK}"
39+
const val JBOSS_LOGGING = "org.jboss.logging:commons-logging-jboss-logging:${Versions.JBOSS_LOGGING}"
3940

4041
const val WOODSTOX = "com.fasterxml.woodstox:woodstox-core:${Versions.WOODSTOX}"
4142

buildSrc/src/main/kotlin/Versions.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ object Versions {
8989
// https://commons.apache.org/proper/commons-text/
9090
const val COMMON_TEXT = "1.9"
9191

92+
// https://github.com/jboss-logging/commons-logging-jboss-logging
93+
// JBoss logging dep is used by the Google Auth library when configuring a proxy.
94+
// https://github.com/googleapis/google-auth-library-java#configuring-a-proxy
95+
const val JBOSS_LOGGING = "1.0.0.Final"
96+
9297
// https://github.com/fusesource/jansi/releases
9398
const val JANSI = "2.4.0"
9499

docs/index.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,13 @@ and flank's example [gradle-export-api](https://github.com/Flank/flank/tree/mast
10581058
6) > How can I find project id?
10591059
10601060
Please check the [firebase documentation](https://firebase.google.com/docs/projects/learn-more?hl=en#find_the_project_id) about finding the project id
1061+
1062+
7) > How do I run Flank with a proxy?
1063+
1064+
`java -Dhttps.proxyHost=localhost -Dhttps.proxyPort=8080 -Dhttps.proxyUser=user -Dhttps.proxyPassword=pass -jar ./test_runner/build/libs/flank.jar firebase test android run`
10611065

1066+
See [google-auth-library-java](https://github.com/googleapis/google-auth-library-java#configuring-a-proxy) for details.
1067+
10621068

10631069
# Resources
10641070

test_runner/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ dependencies {
195195
implementation(Dependencies.KOTLIN_REFLECT)
196196

197197
implementation(Dependencies.LOGBACK)
198+
implementation(Dependencies.JBOSS_LOGGING)
198199

199200
implementation(Dependencies.PICOCLI)
200201
annotationProcessor(Dependencies.PICOCLI_CODEGEN)

test_runner/src/main/kotlin/ftl/client/google/Credentials.kt

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package ftl.client.google
22

33
import com.google.api.client.http.GoogleApiLogger
44
import com.google.api.client.http.HttpRequestInitializer
5+
import com.google.api.client.http.apache.v2.ApacheHttpTransport
6+
import com.google.auth.http.HttpTransportFactory
57
import com.google.auth.oauth2.AccessToken
68
import com.google.auth.oauth2.GoogleCredentials
79
import com.google.auth.oauth2.ServiceAccountCredentials
@@ -10,6 +12,12 @@ import flank.common.isWindows
1012
import ftl.config.FtlConstants
1113
import ftl.http.HttpTimeoutIncrease
1214
import ftl.run.exception.FlankGeneralError
15+
import org.apache.http.HttpHost
16+
import org.apache.http.auth.AuthScope
17+
import org.apache.http.auth.UsernamePasswordCredentials
18+
import org.apache.http.impl.client.BasicCredentialsProvider
19+
import org.apache.http.impl.client.ProxyAuthenticationStrategy
20+
import org.apache.http.impl.conn.DefaultProxyRoutePlanner
1321
import java.io.IOException
1422
import java.util.Date
1523

@@ -19,7 +27,12 @@ val credential: GoogleCredentials by lazy {
1927
else ->
2028
runCatching {
2129
GoogleApiLogger.silenceComputeEngine()
22-
ServiceAccountCredentials.getApplicationDefault()
30+
val httpTransportFactory = getHttpTransportFactory()
31+
if (httpTransportFactory != null) {
32+
ServiceAccountCredentials.getApplicationDefault(httpTransportFactory)
33+
} else {
34+
ServiceAccountCredentials.getApplicationDefault()
35+
}
2336
}.getOrElse {
2437
when {
2538
isWindows -> loadCredentialsWindows()
@@ -29,6 +42,31 @@ val credential: GoogleCredentials by lazy {
2942
}
3043
}
3144

45+
private fun getHttpTransportFactory(): HttpTransportFactory? {
46+
val proxyHost = System.getProperty("http.proxyHost") ?: return null
47+
val proxyPort = System.getProperty("http.proxyPort")?.toInt() ?: return null
48+
val proxyPassword = System.getProperty("http.proxyPassword") ?: return null
49+
val proxyUsername = System.getProperty("http.proxyUser") ?: return null
50+
51+
val proxyHostDetails = HttpHost(proxyHost, proxyPort)
52+
val httpRoutePlanner = DefaultProxyRoutePlanner(proxyHostDetails)
53+
54+
val credentialsProvider = BasicCredentialsProvider()
55+
credentialsProvider.setCredentials(
56+
AuthScope(proxyHostDetails.getHostName(), proxyHostDetails.getPort()),
57+
UsernamePasswordCredentials(proxyUsername, proxyPassword)
58+
)
59+
60+
val httpClient = ApacheHttpTransport.newDefaultHttpClientBuilder()
61+
.setRoutePlanner(httpRoutePlanner)
62+
.setProxyAuthenticationStrategy(ProxyAuthenticationStrategy.INSTANCE)
63+
.setDefaultCredentialsProvider(credentialsProvider)
64+
.build()
65+
66+
val httpTransport = ApacheHttpTransport(httpClient)
67+
return HttpTransportFactory { httpTransport }
68+
}
69+
3270
private fun loadCredentialsWindows() = runCatching {
3371
loadGoogleAccountCredentials()
3472
}.getOrElse {

0 commit comments

Comments
 (0)