Skip to content

Commit

Permalink
Merge pull request #41 from modelix/MODELIX-745
Browse files Browse the repository at this point in the history
feat(instances-manager): add generic redirection route to ports
  • Loading branch information
odzhychko authored Apr 22, 2024
2 parents 00fb2d5 + 8449383 commit 99c2f5d
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 14 deletions.
6 changes: 6 additions & 0 deletions instances-manager/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,10 @@ dependencies {
implementation(libs.auth0.jwt)

runtimeOnly(libs.slf4j.simple)

testImplementation(kotlin("test"))
}

tasks.test {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,19 @@ object Main {
}

override fun redirect(request: ServletUpgradeRequest): URI? {
val redirectedURL: RedirectedURL = DeploymentManager.INSTANCE.redirect(null, request.httpServletRequest)
?: return null
val redirectedURL = DeploymentManager.INSTANCE.redirect(null, request.httpServletRequest)
val urlToRedirectTo = redirectedURL?.getURLToRedirectTo(true)
return try {
URI(redirectedURL.getRedirectedUrl(true))
urlToRedirectTo?.let { URI(it) }
} catch (e: URISyntaxException) {
throw RuntimeException(e)
}
}

override fun rewriteTarget(clientRequest: HttpServletRequest): String? {
val redirectedURL: RedirectedURL = DeploymentManager.INSTANCE.redirect(null, clientRequest)
?: return null
return redirectedURL.getRedirectedUrl(false)
val redirectedURL = DeploymentManager.INSTANCE.redirect(null, clientRequest)
val urlToRedirectTo = redirectedURL?.getURLToRedirectTo(false)
return urlToRedirectTo
}
}
val proxyHandlerCondition: HandlerWrapper = object : HandlerWrapper() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,36 @@ class RedirectedURL(
var instanceName: InstanceName?,
val userToken: AccessTokenPrincipal?
) {
fun noPersonalDeployment() {
instanceName = null
}

fun getRedirectedUrl(websocket: Boolean): String {
fun getURLToRedirectTo(websocket: Boolean): String? {
var url = (if (websocket) "ws" else "http") + "://"
url += if (instanceName != null) instanceName?.name else workspaceReference
url += if (remainingPath.startsWith("/ide/")) {
url += if (remainingPath.startsWith("/ide")) {
":8887" + remainingPath.substring("/ide".length)
} else if (remainingPath.startsWith("/generator/")) {
} else if (remainingPath.startsWith("/generator")) {
// see https://github.com/modelix/modelix.mps-plugins/blob/bb70966087e2f41c263a7fe4d292e4722d50b9d1/mps-generator-execution-plugin/src/main/kotlin/org/modelix/mps/generator/web/GeneratorExecutionServer.kt#L78
":33335" + remainingPath.substring("/generator".length)
} else if (remainingPath.startsWith("/diff/")) {
} else if (remainingPath.startsWith("/diff")) {
// see https://github.com/modelix/modelix.mps-plugins/blob/bb70966087e2f41c263a7fe4d292e4722d50b9d1/mps-diff-plugin/src/main/kotlin/org/modelix/ui/diff/DiffServer.kt#L82
":33334" + remainingPath.substring("/diff".length)
} else if (remainingPath.startsWith("/port/")) {
val matchResults = PORT_MATCHER.matchEntire(remainingPath) ?: return null
val portString = matchResults.groupValues[1]
val portNumber = portString.toInt()
if (portNumber > HIGHEST_VALID_PORT_NUMBER) {
return null
}
val pathAfterPort = matchResults.groupValues[2]
":$portString$pathAfterPort"
} else {
":33333$remainingPath"
}
return url
}

companion object {
const val COOKIE_NAME = "modelix-mps-instance"
private const val HIGHEST_VALID_PORT_NUMBER = 65535
private val PORT_MATCHER = Regex("/port/(\\d{1,5})(/.*)?")
fun redirect(baseRequest: Request?, request: HttpServletRequest): RedirectedURL? {
var remainingPath = request.requestURI
if (!remainingPath.startsWith("/")) return null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.modelix.instancesmanager

import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull

class RedirectedURLTest {

fun createRedirectUrlToPort(portString: String, pathAfterPort: String): RedirectedURL {
return RedirectedURL(
remainingPath = "/port/$portString$pathAfterPort",
workspaceReference = "workspace",
sharedInstanceName = "own",
instanceName = null,
userToken = null
)
}

@Test
fun `create redirect URL for valid port number with path after port`() {
val redirectedURL = createRedirectUrlToPort("65535", "/some_path")
assertEquals("http://workspace:65535/some_path", redirectedURL.getURLToRedirectTo(false))
}

@Test
fun `create redirect URL for valid port number without path after port`() {
val redirectedURL = createRedirectUrlToPort("65535", "")
assertEquals("http://workspace:65535", redirectedURL.getURLToRedirectTo(false))
}


@Test
fun `do no create redirect URL for port that is out of range`() {
val redirectedURL = createRedirectUrlToPort("65536", "")
assertNull(redirectedURL.getURLToRedirectTo(false))
}

@Test
fun `do no create redirect URL for port that is not a number`() {
val redirectedURL = createRedirectUrlToPort("not_a_number", "")
assertNull(redirectedURL.getURLToRedirectTo(false))
}
}

0 comments on commit 99c2f5d

Please sign in to comment.