D
D
Dmitry Kinash2013-12-04 15:33:20
Android
Dmitry Kinash, 2013-12-04 15:33:20

Problem with HttpURLConnection on Android 3.0?

There is a program written for Android. There are no problems on ordinary smartphones and tablets. But some of our clients bought a batch of cheap tablets with Android 3.0 version on board and it turned out that they do not have access to the resources of our site.

The check showed that our server returns a 400 - Bad Request error. Using ADB, I connected to the tablet provided for testing and recorded the traffic using tcpdump. The results were very interesting. First, only headers are sent to the server, which describe that this is a POST request and specify its parameters. Then our web server, "goofed" from such a message, responds with a 400 code. And only then is the content of the HTTP packet sent as a separate packet (of course, without headers, but only the POST body).

Judging by the fact that on other versions of Android there is no such crushing problem (including my emulator with Android 2.3), then the point is in some nuances of the third version.

The code is pretty simple:

URL oURL = new URL(url);
HttpURLConnection con = (HttpURLConnection) oURL.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Authorization", auth);
con.setRequestProperty("Content-type" , "text/xml; charset=utf-8");
                
String reqXML = "Тут находится тело POST запроса в кодировке UTF-8";
                
OutputStream reqStream = con.getOutputStream();
reqStream.write(reqXML.getBytes());
reqStream.flush();
                
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] byteBuf = new byte[1024];
                
int status = con.getResponseCode();
InputStream resStream = null;
if (status >= 400) {
  resStream = con.getErrorStream();
} else {
       	resStream = con.getInputStream();
}
                
int len = resStream.read(byteBuf);
while (len > -1) {
       	outStream.write(byteBuf, 0, len);
       	len = resStream.read(byteBuf);
}

outStream.close();
reqStream.close();
resStream.close();
con.disconnect();

Thanks in advance for your help in solving the problem.

Update.
After following the tips and in the course of my experiments on similar topics from the stackoverflow, the code took the following form:

byte [] reqBody = reqXML.getBytes();
            	
URL oURL = new URL(pack.url);
HttpURLConnection con = (HttpURLConnection) oURL.openConnection();
                
con.setRequestMethod("POST");
con.setRequestProperty("Authorization", auth);
con.setRequestProperty("SOAPAction"   , action);
con.setRequestProperty("Content-type" , "text/xml; charset=utf-8");
                
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
                
OutputStream reqStream = con.getOutputStream();
reqStream.write(reqBody);
reqStream.close();
........


But it doesn't help yet. Debugging on the tablet with tcpdump running on the server shows that the first part of the packet arrives at the server, a 400 response is received, and then the rest of the message is sent at the time the reqStream.close() instruction is fired .

If someone is interested in the type of dump, then I added it as a comment to the second answer.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Anton, 2013-12-05
@TonyCode

On the move - I was confused by the line:
Usually, I write instead:
There is an assumption that it is because of flush() that only a part is sent at first, and when it comes to destroy the local reqStream, it executes close() and sends POST without headers - and this is specific on 3.0... I advise you to try replacing the string with close()!

A
Anton Gorodchuk, 2015-08-14
@antoman

Stumbled in looking for a solution. Maybe I'm not the last one to look here.
I had such a problem on Android 2.3.3
. It turned out that the problem is setRequestProperty("Authorization", auth), where auth is a Base64 string.
Decided by replacing with Authenticator .
developer.android.com/reference/java/net/Authentic...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question