Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to fetch the Reason-Phrase from the status line of a HTTP 1.1 response with Java 11's HttpClient?

With Java's java.net.HttpURLConnection there is a getResponseMessage() method to retrieve any Reason-Phrase text (as specified by RFC2616 6.1 Status Line).

In the newer Java 11 HttpClient, java.net.http.HttpResponse only has a statusCode() method.

Is there a way to obtain text returned on the end of the status line using this API? If not, why was it not included? (I know that HTTP 2 does not define this value, but most applications still use HTTP 1.1 where it remains valid.)

like image 243
Nathan Williams Avatar asked Aug 22 '20 19:08

Nathan Williams


2 Answers

Is there a way to obtain text returned on the end of the status line using this API?

No.

If not, why was it not included?

We can't tell you the actual reasons because a detailed design rationale has not been published.

However, I imagine that the reasons / reasoning went like this:

  1. Because the text is routinely ignored by clients. (Bear with me ...)

  2. Because the text rarely contains anything useful. It is usually just the standard (recommended) text message corresponding to the response code. (This is one reason why the text is routinely ignored by clients.)

  3. Because if a web application is going to provide a meaningful explanation, it is likely to do it in the payload. (Because of 1. But also reinforcing it.)

  4. Because some web stacks don't let the web app set the reason text.

  5. Because some HTTP 1.1 web servers routinely leave the reason text out entirely! (For example, with Tomcat 8.0.x there is no message, and with Tomcat 8.5.x there is an option to enable it.)


(I know that HTTP 2 does not define this value, but most applications still use HTTP 1.1 where it remains valid.)

That's now ... 1.

This is actually another reason for (new) web applications not try to pass useful information in the reason text AND to not support it in the API.

Eventually, most applications will use HTTP 2 or later. Or at least, enough will use it that relying on good support for an HTTP 1.x feature could cause problems for your application.

Bear in mind that HTTP 3 is now in the pipeline. Nobody can see far enough into the future to accurately predict what proportion of web servers will use what versions of HTTP in (say) 5 years time.

1 - Server-side adoption is trending upwards, but it varies depending on the server platform. See the 2020 Web Almanac for some data points.


In the light of the above, if you make your client code depend on seeing specific reason texts ... or seeing any at all ... then it is liable to break for some web servers.

Hence, I would say that Java 11's HttpClient API designers did us all a big favor by not exposing the reason text to client-side code.

You are free to disagree ... and use other HTTP client libraries.


My advice is to go with the flow. If you don't try to use the reason text (client side or server side) then you won't have to deal with the problems that using it will bring. The problems will only get worse.

like image 94
Stephen C Avatar answered Sep 28 '22 01:09

Stephen C


I was looking for http status code reason phrases in Java and found this discussion during my Google search. I ended up writing my own function that I wanted to share in case somebody else finds it useful. It might not be complete, but it serves my purposes.

public static String getReasonPhrase(int statusCode) {
    switch(statusCode) {
        case (200): return "OK";
        case (201): return "Created";
        case (202): return "Accepted";
        case (203): return "Non Authoritative Information";
        case (204): return "No Content";
        case (205): return "Reset Content";
        case (206): return "Partial Content";
        case (207): return "Partial Update OK";
        case (300): return "Mutliple Choices";
        case (301): return "Moved Permanently";
        case (302): return "Moved Temporarily";
        case (303): return "See Other";
        case (304): return "Not Modified";
        case (305): return "Use Proxy";
        case (307): return "Temporary Redirect";
        case (400): return "Bad Request";
        case (401): return "Unauthorized";
        case (402): return "Payment Required";
        case (403): return "Forbidden";
        case (404): return "Not Found";
        case (405): return "Method Not Allowed";
        case (406): return "Not Acceptable";
        case (407): return "Proxy Authentication Required";
        case (408): return "Request Timeout";
        case (409): return "Conflict";
        case (410): return "Gone";
        case (411): return "Length Required";
        case (412): return "Precondition Failed";
        case (413): return "Request Entity Too Large";
        case (414): return "Request-URI Too Long";
        case (415): return "Unsupported Media Type";
        case (416): return "Requested Range Not Satisfiable";
        case (417): return "Expectation Failed";
        case (418): return "Reauthentication Required";
        case (419): return "Proxy Reauthentication Required";
        case (422): return "Unprocessable Entity";
        case (423): return "Locked";
        case (424): return "Failed Dependency";
        case (500): return "Server Error";
        case (501): return "Not Implemented";
        case (502): return "Bad Gateway";
        case (503): return "Service Unavailable";
        case (504): return "Gateway Timeout";
        case (505): return "HTTP Version Not Supported";
        case (507): return "Insufficient Storage";
        default: return "";
    }
}
like image 43
Bjorn Avatar answered Sep 28 '22 02:09

Bjorn