1

Does anyone know how to manipulate the HTTP Status text in Scala Play 2.2? I see that it's easy to specify the status code but not the accompanying text.

The reason I'm interested is that I'm trying to emulate exactly a web service I need to consume, and it puts specific information in the status text.

For example, when failing a login attempt I'll get the following snippet from this service (curl output):

< HTTP/1.1 401 username or password invalid
< ...

When I return an Unauthorized response from my Mock service I just get the following:

< HTTP/1.1 401 Unauthorized
< ...

I'm clearly missing the real way to do this if it's even possible in the first place.

Here's how I'm constructing the unauthorized response:

Unauthorized(views.html.invalidlogon(message)).withHeaders(
  CONTENT_TYPE -> "text/plain"
)

Here's what I'd like to do in my fictional naive world:

Unauthorized(views.html.invalidlogon(message)).withHeaders(
  CONTENT_TYPE -> "text/plain"
).setStatusText(message)

Thanks for the help!

Edit - Additional Info

So it turns out what I'm really looking for is the Reason Phrase.

According to the RFC they say the following:

The reason phrases listed here are only recommendations -- they MAY be replaced by local equivalents without affecting the protocol.

Of particular interest is the use of MAY with regard to the existing error codes.

However if in Play I return a custom 4XX error then the reason phrase is just Client Error following the classification of the 4XX status. It would be nice to have control over the reason phrase so that it accompanies the custom response status code.

slohr
  • 613
  • 6
  • 9

2 Answers2

0

De facto response status is a numeric value by HTTP specification and therefore it's hardcoded in Play.

If you really need this so as suggested in answer to other question it's better to add custom header, ie:

Unauthorized("You can't login now, sorry...").withHeaders(
  CONTENT_TYPE -> "text/plain; charset=utf-8",
  "X-Error-Message" -> "Login or password invalid"
)

TIP: For security reasons be careful with too descriptive error messages during login proccess.

Community
  • 1
  • 1
biesior
  • 55,576
  • 10
  • 125
  • 182
  • Thanks for the response. Indeed I looked at the spec and it appears that what I was looking for was the Reason Phrase. Some libraries call it Status Text which is a misnomer as I've discovered. Unfortunately I'm trying to emulate an existing service so the extra header (though sensible) is not an option. – slohr Oct 16 '14 at 22:43
0

After review of the Play code I don't think this is possible at the moment.

If you look here they do the following:

def createNettyResponse(header: ResponseHeader, closeConnection: Boolean, httpVersion: HttpVersion) = {
  val nettyResponse = new DefaultHttpResponse(httpVersion, HttpResponseStatus.valueOf(header.status))
...

The call to HttpResponseStatus.valueOf(header.status) doesn't allow for Reason Phrase to be added.

In a purely fictional (and possibly dubious) world the following change might allow this:

def createNettyResponse(header: ResponseHeader, closeConnection: Boolean, httpVersion: HttpVersion) = {
  val nettyResponse = header.reasonPhrase match {
    case Some(reasonPhrase) => new DefaultHttpResponse(httpVersion, HttpResponseStatus(header.status, header.reasonPhrase))
    case _ => new DefaultHttpResponse(httpVersion, HttpResponseStatus.valueOf(header.status))
  }
  ...

However a change like that has a big ripple effect.

So If I'm correct, this is just not possible and I will see what the Play folks think.

thanks

slohr
  • 613
  • 6
  • 9