2

I'm trying to find out if a play 2 (with scala) app is running on http or https

I tried with routes.Application.index.absoluteURL(request), like this

def chatUri(username: String)(implicit request: RequestHeader): String = {

  val uri = routes.Application.index.absoluteURL(request)

but I get the following error:

/home/sas/tmp/websocket-chat/app/controllers/Application.scala:51: overloaded method value absoluteURL with alternatives:
[error]   (secure: Boolean)(implicit request: play.api.mvc.RequestHeader)java.lang.String <and>
[error]   (play.mvc.Http.Request)java.lang.String
[error]  cannot be applied to (play.api.mvc.RequestHeader)
[error]     val rootUri = Uri(routes.Application.index.absoluteURL(request))

I tried to transform the RequestHeader into a Request, but I get the following error

val rootUri = Uri(routes.Application.index.absoluteURL(request.asInstanceOf[Request[Any]]))

(secure: Boolean)(implicit request: play.api.mvc.RequestHeader)java.lang.String <and>
[error]   (play.mvc.Http.Request)java.lang.String
[error]  cannot be applied to (play.api.mvc.Request[Any])
[error]     val rootUri = Uri(routes.Application.index.absoluteURL(request.asInstanceOf[Request[Any]]))

Any idea how can I achieve it?

ndeverge
  • 21,378
  • 4
  • 56
  • 85
opensas
  • 60,462
  • 79
  • 252
  • 386

2 Answers2

4

Must say I'm surprised about problems with getting absolute url in Scala, AFAIR in Java it works well, anyway... I doubt if it will help you to determine the protocol (edit: as @MariusSoutier wrote)

As there's no built-in support for SSL in Play 2 most probably you are using (or you should use) some HTTP server on front of your application, let's say Apache. There are some samples and posts describing the proccess:

  1. Take a look at topic: How to config PlayFramework2 to support SSL? Nasir gives there a sample of configuring the Apache as a proxy for Play
  2. There's also nice description of configuring Apache as a proxy (warning the posts describes the Play 1.x, however Apache part will be the same)
  3. Finally you need to to set the proper headers which will be forwarded to your app

so after setting the headers (as showed in point 3) you'll be able to check it in your controller:

def index = Action { request =>
    val proto = request.headers("X-FORWARDED-PROTO")
    Ok("Got request [" + request + "] with schema: " + proto )
}

or the same in Java controller:

public static Result index() {
    String proto = request().getHeader("X-FORWARDED-PROTO");
    return ok("Got request [" + request() + "] with schema: " + proto);
}
Community
  • 1
  • 1
biesior
  • 55,576
  • 10
  • 125
  • 182
3

First off, by creating an absolute URL, you cannot find out if the app is running on http or https - take a look at the method signature:

def absoluteURL (secure: Boolean = false)(implicit request: RequestHeader): String

That's right, you have to tell this method whether or not you want secure.

I think this is because Play was designed to working behind a reverse proxy which makes it transparent to use encrypted requests. That means Play shouldn't have to care about this. absoluteURL can only enforce https URLs, for example to make sure a login page uses https.

Depending on your reverse proxy, you can set a custom http header that tells you what is used. RequestHeader doesn't have the information.

Marius Soutier
  • 11,184
  • 1
  • 38
  • 48
  • allow me to share a good post talling a workaround for dealing with this affair: https://github.com/playframework/playframework/issues/2427 – Victor Oct 08 '19 at 14:36