Skip to content

Commit f854ff8

Browse files
committed
[jb] fix #10694: respect GW user settings
1 parent 70aea6c commit f854ff8

14 files changed

+134
-76
lines changed

components/gitpod-protocol/java/src/main/java/io/gitpod/gitpodprotocol/api/GitpodServerLauncher.java

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,26 @@
44

55
package io.gitpod.gitpodprotocol.api;
66

7+
import org.eclipse.jetty.client.HttpClient;
8+
import org.eclipse.jetty.client.HttpProxy;
9+
import org.eclipse.jetty.client.Socks4Proxy;
10+
import org.eclipse.jetty.util.ssl.SslContextFactory;
11+
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
712
import org.eclipse.lsp4j.jsonrpc.Launcher;
813
import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
914
import org.eclipse.lsp4j.jsonrpc.MessageIssueHandler;
1015
import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
1116
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
1217
import org.eclipse.lsp4j.websocket.WebSocketMessageHandler;
1318

19+
import javax.net.ssl.SSLContext;
1420
import javax.websocket.*;
15-
import java.io.IOException;
21+
import java.net.InetSocketAddress;
22+
import java.net.Proxy;
23+
import java.net.SocketAddress;
1624
import java.net.URI;
1725
import java.util.Arrays;
26+
import java.util.Collections;
1827
import java.util.List;
1928
import java.util.Map;
2029
import java.util.logging.Level;
@@ -47,10 +56,60 @@ public GitpodServerConnection listen(
4756
String userAgent,
4857
String clientVersion,
4958
String token
50-
) throws DeploymentException, IOException {
59+
) throws Exception {
60+
return listen(apiUrl, origin, userAgent, clientVersion, token, Collections.emptyList(), null);
61+
}
62+
63+
public GitpodServerConnection listen(
64+
String apiUrl,
65+
String origin,
66+
String userAgent,
67+
String clientVersion,
68+
String token,
69+
List<Proxy> proxies,
70+
SSLContext sslContext
71+
) throws Exception {
5172
String gitpodHost = URI.create(apiUrl).getHost();
73+
HttpClient httpClient;
74+
if (sslContext == null) {
75+
httpClient = new HttpClient();
76+
} else {
77+
SslContextFactory ssl = new SslContextFactory.Client();
78+
ssl.setSslContext(sslContext);
79+
httpClient = new HttpClient(ssl);
80+
}
81+
for (Proxy proxy : proxies) {
82+
if (proxy.type().equals(Proxy.Type.DIRECT)) {
83+
continue;
84+
}
85+
SocketAddress proxyAddress = proxy.address();
86+
if (!(proxyAddress instanceof InetSocketAddress)) {
87+
GitpodServerConnectionImpl.LOG.log(Level.WARNING, gitpodHost + ": unexpected proxy:", proxy);
88+
continue;
89+
}
90+
String hostName = ((InetSocketAddress) proxyAddress).getHostString();
91+
int port = ((InetSocketAddress) proxyAddress).getPort();
92+
if (proxy.type().equals(Proxy.Type.HTTP)) {
93+
httpClient.getProxyConfiguration().getProxies().add(new HttpProxy(hostName, port));
94+
} else if (proxy.type().equals(Proxy.Type.SOCKS)) {
95+
httpClient.getProxyConfiguration().getProxies().add(new Socks4Proxy(hostName, port));
96+
}
97+
}
98+
ClientContainer container = new ClientContainer(httpClient);
99+
// allow clientContainer to own httpClient (for start/stop lifecycle)
100+
container.getClient().addManaged(httpClient);
101+
container.start();
102+
52103
GitpodServerConnectionImpl connection = new GitpodServerConnectionImpl(gitpodHost);
53-
connection.setSession(ContainerProvider.getWebSocketContainer().connectToServer(new Endpoint() {
104+
connection.whenComplete((input, exception) -> {
105+
try {
106+
container.stop();
107+
} catch (Throwable t) {
108+
GitpodServerConnectionImpl.LOG.log(Level.WARNING, gitpodHost + ": failed to stop websocket container:", t);
109+
}
110+
});
111+
112+
connection.setSession(container.connectToServer(new Endpoint() {
54113
@Override
55114
public void onOpen(Session session, EndpointConfig config) {
56115
session.addMessageHandler(new WebSocketMessageHandler(messageReader, jsonHandler, remoteEndpoint));

components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/auth/GitpodAuthCallbackHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,4 @@ internal class GitpodAuthCallbackHandler : RestService() {
6262
</html>
6363
""".trimIndent()
6464
}
65-
}
65+
}

components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/auth/GitpodAuthService.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import java.util.*
3838
import java.util.concurrent.CompletableFuture
3939
import kotlin.math.absoluteValue
4040

41-
4241
@Service
4342
internal class GitpodAuthService : OAuthServiceBase<Credentials>() {
4443
override val name: String
@@ -66,7 +65,7 @@ internal class GitpodAuthService : OAuthServiceBase<Credentials>() {
6665
constructor(gitpodHost: String) {
6766
val codeVerifier = generateCodeVerifier()
6867
val codeChallenge = generateCodeChallenge(codeVerifier)
69-
val serviceUrl = newFromEncoded("https://${gitpodHost}/api/oauth")
68+
val serviceUrl = newFromEncoded("https://$gitpodHost/api/oauth")
7069
credentialsAcquirer = GitpodAuthCredentialsAcquirer(
7170
serviceUrl.resolve("token"), mapOf(
7271
"grant_type" to "authorization_code",
@@ -94,7 +93,7 @@ internal class GitpodAuthService : OAuthServiceBase<Credentials>() {
9493
val bytes = ByteArray(size)
9594
secureRandom.nextBytes(bytes)
9695

97-
val mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
96+
val mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"
9897
val scale = 256 / mask.length
9998
val builder = StringBuilder()
10099
for (i in 0 until size) {
@@ -147,7 +146,6 @@ internal class GitpodAuthService : OAuthServiceBase<Credentials>() {
147146

148147
private data class AuthorizationResponseData(val accessToken: String)
149148
private data class JsonWebToken(val jti: String)
150-
151149
}
152150

153151
companion object {
@@ -198,8 +196,8 @@ internal class GitpodAuthService : OAuthServiceBase<Credentials>() {
198196
listener()
199197
}
200198
}
201-
dispatcher.addListener(internalListener);
199+
dispatcher.addListener(internalListener)
202200
return Disposable { dispatcher.removeListener(internalListener) }
203201
}
204202
}
205-
}
203+
}

components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/gateway/GatewayGitpodClient.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@ import kotlinx.coroutines.sync.Mutex
2121
import kotlinx.coroutines.sync.withLock
2222

2323
class GatewayGitpodClient(
24-
private val lifetimeDefinition: LifetimeDefinition, private val gitpodHost: String
24+
private val lifetimeDefinition: LifetimeDefinition,
25+
private val gitpodHost: String
2526
) : GitpodClient() {
2627

2728
private val mutex = Mutex()
2829

2930
private val listeners = concurrentMapOf<String, CopyOnWriteArrayList<Channel<WorkspaceInstance>>?>()
3031

3132
private val timeoutDelayInMinutes = 15
32-
private var timeoutJob: Job? = null;
33+
private var timeoutJob: Job? = null
3334

3435
init {
3536
GlobalScope.launch {
@@ -59,7 +60,7 @@ class GatewayGitpodClient(
5960
}
6061
}
6162

62-
private var syncJob: Job? = null;
63+
private var syncJob: Job? = null
6364
override fun notifyConnect() {
6465
syncJob?.cancel()
6566
syncJob = GlobalScope.launch {
@@ -69,17 +70,17 @@ class GatewayGitpodClient(
6970
continue
7071
}
7172
try {
72-
syncWorkspace(id);
73+
syncWorkspace(id)
7374
} catch (t: Throwable) {
74-
thisLogger().error("${gitpodHost}: ${id}: failed to sync", t)
75+
thisLogger().error("$gitpodHost: $id: failed to sync", t)
7576
}
7677
}
7778
}
7879
}
7980

8081
override fun onInstanceUpdate(instance: WorkspaceInstance?) {
8182
if (instance == null) {
82-
return;
83+
return
8384
}
8485
GlobalScope.launch {
8586
val wsListeners = listeners[instance.workspaceId] ?: return@launch
@@ -102,7 +103,7 @@ class GatewayGitpodClient(
102103
val listener = Channel<WorkspaceInstance>()
103104
mutex.withLock {
104105
val listeners = this.listeners.getOrPut(workspaceId) { CopyOnWriteArrayList() }!!
105-
listeners.add(listener);
106+
listeners.add(listener)
106107
cancelTimeout("listening to workspace: $workspaceId")
107108
}
108109
listenerLifetime.onTerminationOrNow {
@@ -120,7 +121,7 @@ class GatewayGitpodClient(
120121
if (listeners.isNullOrEmpty()) {
121122
return
122123
}
123-
listeners.remove(listener);
124+
listeners.remove(listener)
124125
if (listeners.isNotEmpty()) {
125126
return
126127
}
@@ -137,5 +138,4 @@ class GatewayGitpodClient(
137138
onInstanceUpdate(info.latestInstance)
138139
return info
139140
}
140-
141-
}
141+
}

components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/gateway/GitpodConnectionProvider.kt

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import javax.swing.JComponent
4747
import javax.swing.JLabel
4848
import kotlin.coroutines.coroutineContext
4949

50-
5150
class GitpodConnectionProvider : GatewayConnectionProvider {
5251

5352
private val gitpod = service<GitpodConnectionService>()
@@ -64,10 +63,10 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
6463
requestor: ConnectionRequestor
6564
): GatewayConnectionHandle? {
6665
if (parameters["gitpodHost"] == null) {
67-
throw IllegalArgumentException("bad gitpodHost parameter");
66+
throw IllegalArgumentException("bad gitpodHost parameter")
6867
}
6968
if (parameters["workspaceId"] == null) {
70-
throw IllegalArgumentException("bad workspaceId parameter");
69+
throw IllegalArgumentException("bad workspaceId parameter")
7170
}
7271
val connectParams = ConnectParams(
7372
parameters["gitpodHost"]!!,
@@ -92,7 +91,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
9291
background = phaseMessage.background
9392
columns = 30
9493
}
95-
var ideUrl = "";
94+
var ideUrl = ""
9695
val connectionPanel = panel {
9796
indent {
9897
row {
@@ -146,18 +145,18 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
146145
}
147146

148147
GlobalScope.launch {
149-
var thinClient: ThinClientHandle? = null;
150-
var thinClientJob: Job? = null;
148+
var thinClient: ThinClientHandle? = null
149+
var thinClientJob: Job? = null
151150

152-
var lastUpdate: WorkspaceInstance? = null;
151+
var lastUpdate: WorkspaceInstance? = null
153152
try {
154153
for (update in updates) {
155154
try {
156155
if (WorkspaceInstance.isUpToDate(lastUpdate, update)) {
157-
continue;
156+
continue
158157
}
159158
ideUrl = update.ideUrl
160-
lastUpdate = update;
159+
lastUpdate = update
161160
if (!update.status.conditions.failed.isNullOrBlank()) {
162161
setErrorMessage(update.status.conditions.failed)
163162
}
@@ -212,7 +211,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
212211
if (thinClientJob == null && update.status.phase == "running") {
213212
thinClientJob = launch {
214213
try {
215-
val ideUrl = URL(update.ideUrl);
214+
val ideUrl = URL(update.ideUrl)
216215
val hostKeys = resolveHostKeys(ideUrl, connectParams)
217216
if (hostKeys.isNullOrEmpty()) {
218217
setErrorMessage("${connectParams.gitpodHost} installation does not allow SSH access, public keys cannot be found")
@@ -270,7 +269,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
270269
}
271270
}
272271

273-
return GitpodConnectionHandle(connectionLifetime, connectionPanel, connectParams);
272+
return GitpodConnectionHandle(connectionLifetime, connectionPanel, connectParams)
274273
}
275274

276275
private suspend fun resolveJoinLink(
@@ -356,7 +355,6 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
356355
break
357356
}
358357
}
359-
360358
}
361359
matchedFingerprint
362360
}
@@ -369,7 +367,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
369367
ownerToken: String?,
370368
): String? {
371369
val maxRequestTimeout = 30 * 1000L
372-
val timeoutDelayGrowFactor = 1.5;
370+
val timeoutDelayGrowFactor = 1.5
373371
var requestTimeout = 2 * 1000L
374372
while (true) {
375373
coroutineContext.job.ensureActive()
@@ -388,16 +386,16 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
388386
return response.body()
389387
}
390388
if (response.statusCode() < 500) {
391-
thisLogger().error("${connectParams.gitpodHost}: ${connectParams.workspaceId}: failed to fetch '${endpointUrl}': ${response.statusCode()}")
389+
thisLogger().error("${connectParams.gitpodHost}: ${connectParams.workspaceId}: failed to fetch '$endpointUrl': ${response.statusCode()}")
392390
return null
393391
}
394-
thisLogger().warn("${connectParams.gitpodHost}: ${connectParams.workspaceId}: failed to fetch '${endpointUrl}', trying again...: ${response.statusCode()}")
392+
thisLogger().warn("${connectParams.gitpodHost}: ${connectParams.workspaceId}: failed to fetch '$endpointUrl', trying again...: ${response.statusCode()}")
395393
} catch (t: Throwable) {
396394
if (t is CancellationException) {
397395
throw t
398396
}
399397
thisLogger().warn(
400-
"${connectParams.gitpodHost}: ${connectParams.workspaceId}: failed to fetch '${endpointUrl}', trying again...:",
398+
"${connectParams.gitpodHost}: ${connectParams.workspaceId}: failed to fetch '$endpointUrl', trying again...:",
401399
t
402400
)
403401
}
@@ -437,5 +435,4 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
437435
}
438436

439437
private data class SSHHostKey(val type: String, val hostKey: String)
440-
441438
}

0 commit comments

Comments
 (0)