Troubleshooting a PHP problem with Wireshark
Off late, I have been quite busy on a number of projects especially for one of the Android app platforms being developed by my company Azeem Technologies. Today I was adding some functionality to the app which required that it make contact with a web server to retrieve some data. And I ran into a really strange problem.
Essentially, the app is making a POST request and expects a single line of text that it then parses to understand what to do next. The web server is Apache (version 2.4.7-5.1) and the request is handled by a PHP (version 5.5.12.1) script. Previously, to test the client, I had hardcoded the response in the script file and so it looked something like this in the PHP script.
ini_set("log_errors", 1);
ini_set("error_log", "/tmp/php-error.log");
echo "209\n";
and I varied the values of echo everytime I wanted to test a
different piece of code on the Android client. On the Android
client, a simple piece of code retrieved the text and executed
the next piece of code as follows.
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = reader.readLine() ;
code = Integer.parseInt(result.trim());
Everything worked fine.
Next, the script had to be written to perform database operations which would then decide what the echo statement should spit out for the client. So I went ahead and modified the script. After testing it to make sure that the correct values were being output by the code, I hooked the app to the script. And to my great surprise, it was not working. There was an exception being generated in the Android logcat as follows
Exception: Invalid int: ""
Ater some 2 hours of trial and error and then finally,
divide-by-two troubleshooting, I realized that as long as the
any echo statement appeared before the first connection to the
database 'mysqli_connect()', echo worked fine. After making the
connection, only an empty string was appearing on Android.
// WORKING
echo '209\n';
$dbc = @mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) OR die
('Could not connect to MySQL: '.mysqli_connect_error());
// NOT WORKING
$dbc = @mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) OR die
('Could not connect to MySQL: '.mysqli_connect_error());
echo '209\n';
I tried many things including Google searches but could find no
reason for why this should happen.
Frustrated, I fired up Wireshark and tcpdump. What did I find? For some strange reason, two new lines '\n' were being printed first and then the echo statement line in the POST response.
\n
\n
209\r\n
So in all three lines were appearing on the Android
client. Since the code was expecting only a single line, it
never went to check further and when it parsed the first line
(which happened to be empty), it launced
an
Exception. I triple checked the PHP script and there was no
reason why this should be happening. In fact, this occured even
with
// NOT WORKING
$dbc = @mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) OR die
('Could not connect to MySQL: '.mysqli_connect_error());
echo '209\n';
Eventually I gave up and hacked the Android app to ignore initial empty lines.
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = "";
// getting rid of newlines generated by PHP
while(true)
{
result = reader.readLine() ;
if( result.equalsIgnoreCase(""))
continue;
else
break;
}
code = Integer.parseInt(result.trim());
If anyone knows why this should have happened, please do let me know.