0

I am new to Java and Android programming, I'm trying to get the result of a PHP file on my server but I get the following exception:

java.net.ProtocolException: Unexpected status line: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at com.android.okhttp.internal.http.StatusLine.parse(StatusLine.java:54)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:905)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:789)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:443)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at it.codesnippet.dots.LoginActivity$1$override.run(LoginActivity.java:49)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at it.codesnippet.dots.LoginActivity$1$override.access$dispatch(LoginActivity.java)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at it.codesnippet.dots.LoginActivity$1.run(LoginActivity.java:0)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err:     at java.lang.Thread.run(Thread.java:818)

This is the code (in LoginActivity.java) where the exception comes from:

Thread loginCheckThread = new Thread(new Runnable() {
    public void run() {
        String result = "", dataObj = "";
        TextView username = (TextView) findViewById(R.id.login_mail);
        TextView password = (TextView) findViewById(R.id.login_password);

        JSONObject jsonObj = new JSONObject();
        try {
            jsonObj.put("loginMail", username.getText());
            jsonObj.put("loginPassword", password.getText());
            dataObj = jsonObj.toString(0);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        try {
            URL url = new URL("http://myserver.it/testandroid.php?data=" + dataObj);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

            try {
/* line #49 */  InputStream in = new BufferedInputStream(urlConnection.getInputStream());
                ByteArrayOutputStream bo = new ByteArrayOutputStream();
                int i = in.read();
                while (i != -1) {
                    bo.write(i);
                    i = in.read();
                }
                result = bo.toString();
            } catch (IOException e) {
                result = "Exception: Class::IOStream Related";
                e.printStackTrace();

            } finally {
                urlConnection.disconnect();
            }
        } catch (IOException e) {
            result = "Exception: Class::URL Related";
        }

        System.out.println(result);
    }
});
loginCheckThread.start();

The line which causes the exception is line #49:

InputStream in = new BufferedInputStream(urlConnection.getInputStream());

The PHP file is just a test file for now and is supposed to return <input_username> - <input_password> retrieved from the data variable in the query string:

$jsonObj = json_decode($_GET["data"], TRUE);

echo $jsonObj["loginMail"] . " - " . $jsonObj["loginPassword"];

Is about two days that this problem blocked me, what can I do to solve this?

Cliff Burton
  • 3,414
  • 20
  • 33
  • 47
  • Without delving any deeper into this problem, might I suggest OkHttp for network calls? It served me quite well and it might fix this sisue for you. – Vucko Jul 10 '16 at 09:53
  • It sounds a lot like the HTTP response is invalid; if so, the problem is at the server end, not in the quoted code. – T.J. Crowder Jul 10 '16 at 09:53
  • @T.J.Crowder - The server file works fine, even just echoing "A" calling it from Java doesn't work – Cliff Burton Jul 10 '16 at 09:54
  • I'm just saying, the error is a protocol exception saying that when it tried to read the status line of the HTTP response, instead it got the first line of the payload. That points to a problem at the sending end (or a bug in `HttpURLConnection`, but [`select` isn't broken](https://pragprog.com/the-pragmatic-programmer/extracts/tips), so...). – T.J. Crowder Jul 10 '16 at 09:59
  • Sorry @T.J.Crowder, I'm not following you, can you explain? I'm not mother thongue, sorry :( – Cliff Burton Jul 10 '16 at 10:10
  • @Vucko - Thanks, could you provide a link to the official docs of `OkHttp` or to an example on how to use? – Cliff Burton Jul 10 '16 at 10:11
  • HTTP is a line-based protocol. When a server sends an HTTP response, the first line is the "status line" and it indicates the status of the response (200 for "okay," 404 for "not found", etc.), like this: `HTTP/1.1 200 OK` The error is telling you that the `HttpURLConnection` expected the first line of the response to be like that, but instead it saw ` – T.J. Crowder Jul 10 '16 at 10:14
  • @CliffBurton [Here it is](http://square.github.io/okhttp/). you have everything you need to know here. – Vucko Jul 10 '16 at 10:29
  • 1
    Thank tou @Vucko, I just googled it and found it XD – Cliff Burton Jul 10 '16 at 10:30
  • Thanks for your patience @T.J.Crowder, I know how HTTP works and now I got what you meant. It is strange because listening with Fiddler the PHP file has a correct header, it seems that `select` is broken... – Cliff Burton Jul 10 '16 at 10:36
  • @CliffBurton: It does happen sometimes. :-) For instance, recently there was a bug in the JavaScript engine in Chrome. It's rare, but it happens... – T.J. Crowder Jul 10 '16 at 10:46

2 Answers2

1

Important

To anyone who has this error in you Volley HTTP implementation:

java.net.ProtocolException: Unexpected status line: <!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>

Please check and use OkHttp Dependency for solve it. Here the documentation to check.

In my case (I don't know why), my Android Test Phone (MOTO E V.4.4.4 Kitkat) was getting me back the java.net.ProtocolException: Unexpected status line exception. I tried to reset the phone and deleting the app, and nothing works.

For the other side, my Nexus 5X (With Android Oreo) was working good (same app, same network, same backend).

Please (really) try the OkHttp dependency and it gonna work.

Psd: Some stackoverflow threads says about Volley Cache or something like that, tried everything in my own, but OkHttp solved my trouble.

Community
  • 1
  • 1
marcode_ely
  • 434
  • 1
  • 5
  • 18
0

I'm not yet allowed to leave a comment, therefore I need to write an answer. There is a difference between HTTP and HTML. HTTP is used to download data (such as HTML). Your PHP script generates the downloadable content, but the HTTP client doesn't seem to think that it is the content already. As an example I'd like to show you how a HTTP response usually looks like:

HTTP/1.1 200 OK
Date: Sun, 10 Jul 2016 10:02:42 GMT
Content-Type: text/html
Content-Length: 6920
Last-Modified: Sun, 10 Jul 2016 04:00:22 GMT
Connection: keep-alive
Accept-Ranges: bytes

Here goes the content.

As you can see the HTTP information appears until a double newline or CRLF (carriage return, line feed) appears. I've seen some server implementing that with LF only and that might be the problem, since your Java client isn't able to see when the content starts. Lets make a test: add an echo "\r\n\r\n"; right at the start of your PHP file to print the CRLFCRLF manually. If it then works, it is your server software's output which is wrong. Not your script and not your client. However, the RFC 2616 also says that it is recommended to ignore the CR and only watch for an LF:

The line terminator for message-header fields is the sequence CRLF. However, we recommend that applications, when parsing such headers, recognize a single LF as a line terminator and ignore the leading CR. RFC 2616

DanielB
  • 369
  • 4
  • 15
  • Thanks for your suggestion, I'm going to test it – Cliff Burton Jul 10 '16 at 10:13
  • Hmm then maybe the header is completely missing and the client doesn't find it. You could try `echo "HTTP/1.0 200 OK\r\n\r\n";` then instead. Do you have it hosted somewhere? Can you give us access to it maybe? – DanielB Jul 10 '16 at 11:02
  • [The header is set](http://stackoverflow.com/questions/38290610/java-net-protocolexception-unexpected-status-line-doctype-html-public-ie/38290789?noredirect=1#comment63999408_38290610), I tested it with Fiddler. I think I'm going to use `OkHttp` suggested by @Vucko, thanks for your help ;) – Cliff Burton Jul 10 '16 at 11:10