Skip to content

Commit

Permalink
feat: enable for operating behind a proxy that modifies the url
Browse files Browse the repository at this point in the history
Assume the backend is hosted on a server with a proxy that maps requests to `/backend/<routes>` to `/<routes>`, then we need a mechanism so that links still work (the link from the error page to the swagger UI, the links in the swagger UI to the api docs).

This solution assumes that `X-forwarded-...` headers are set by the proxy, e.g.:
* X-Forwarded-For
* X-Forwarded-Proto
* X-Forwarded-Prefix
  • Loading branch information
fengelniederhammer committed Aug 23, 2023
1 parent 5a6e856 commit 78f0231
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 13 deletions.
7 changes: 7 additions & 0 deletions lapis2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ Use Docker Compose to run SILO and LAPIS:
LAPIS_TAG=latest SILO_TAG=latest DATABASE_CONFIG=path/to/config docker compose up
```

### Operating LAPIS behind a proxy

When running LAPIS behind a proxy, the proxy needs to set X-Forwarded headers:
* X-Forwarded-For
* X-Forwarded-Proto
* X-Forwarded-Prefix

## End-to-end tests

There are end-to-end tests in `siloLapisTests/` that test the integration of SILO and LAPIS.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.genspectrum.lapis.controller

import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import mu.KotlinLogging
import org.springframework.boot.autoconfigure.web.ErrorProperties
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController
import org.springframework.boot.web.servlet.error.ErrorAttributes
import org.springframework.http.MediaType
import org.springframework.stereotype.Component
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.View
import org.springframework.web.servlet.support.ServletUriComponentsBuilder

private val log = KotlinLogging.logger { }

@Component
class ErrorController(errorAttributes: ErrorAttributes) :
BasicErrorController(errorAttributes, ErrorProperties()) {

@RequestMapping(produces = [MediaType.TEXT_HTML_VALUE])
override fun errorHtml(request: HttpServletRequest, response: HttpServletResponse): ModelAndView {
val modelAndView = super.errorHtml(request, response)

response.addHeader("Content-Type", MediaType.TEXT_HTML_VALUE)

val urlPrefix = removeErrorSegmentFromUrl(ServletUriComponentsBuilder.fromCurrentRequest().toUriString())
val url = "$urlPrefix/swagger-ui/index.html"

log.debug { "Generated url $url to Swagger UI in 'not found page'" }

modelAndView.view = NotFoundView(url)
return modelAndView
}

fun removeErrorSegmentFromUrl(url: String): String {
val lastSlashIndex = url.trimEnd('/').lastIndexOf("error")
return url.substring(0, lastSlashIndex).trim('/')
}
}

data class NotFoundView(private val url: String?) : View {

override fun render(model: MutableMap<String, *>?, request: HttpServletRequest, response: HttpServletResponse) {
val html: String = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Error 404</title>
</head>
<body>
<h1>LAPIS</h1>
<h3>Page not found!</h3>
<a href="$url">Visit our swagger-ui</a>
</body>
</html>
""".trimIndent()

response.outputStream.write(html.toByteArray())
}
}
12 changes: 0 additions & 12 deletions lapis2/src/main/resources/public/error/404.html

This file was deleted.

2 changes: 1 addition & 1 deletion siloLapisTests/test/unknownUrl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ describe('Error handling: UnknownUrl', () => {

let responseBody = await result.text();
expect(responseBody).contains('Page not found');
expect(responseBody).contains('a href="/swagger-ui/index.html"');
expect(responseBody).contains('<a href="http://localhost:8080/swagger-ui/index.html">');
});
});

0 comments on commit 78f0231

Please sign in to comment.