I have API server which is built on top of Node.js.
I've set response header for download data like below.
res.setHeader('Content-Length', fileSize);
res.setHeader('Content-Type', 'application/octet-stream');
res.setHeader('Content-Disposition', 'attachment;filename="' + fileName + '"');
It works fine in any computer O/S and web browsers.
However, when I try to download data using android phone, any web browsers (eg., dolphine, chrome, FF) DOES NOT recognize response header (ie., filename, content-length)
Any one can help me to solve this problem?
Thanks in advance.
Finally, I found the reason why the http header does NOT work on android.
It's very sorry that I did not mention critical stuff.
Actually, I tried to download using https not http and since I'm using test server which has no valid SSL certification.
I could ignore SSL certification in web browsers in PC but Android.
It was the reason why Android web browser cannot read header.
I've changed the way to download from https to http, it works perfectly.
Thanks for all concerns and responses.
Thank you.
Related
My live android app stop working when server shifted from http to https.
Tried adding .htaccess for redirecting but still same problem.
i can't change my baseurl at android, but need help to modify at php code.
because android does not understand your serverside configuration so you have to put it manually in an android constant file make for the store base URL and all basic string data so you have not to change everywhere....and save lots of time...also please show your android code ...so anyone can understand where you want to change
Yes... i got the solutions..
you can change http to https without changed android code base url ( which was live with http ) by not forcing to https at cpanel > domains > Force HTTPS Redirect > off
thanks
I'm using Charles proxy to fetch all the requests coming from my Android app to a webservice.
The thing is Charles shows me the complete request, meaning I can see the whole URL, headers and body so I can see www.example.com/rest/resource/param1/param2,
the JSON I send with it and also the authentication header.
After reading several posts like this and this one I thought the good part of working with the TLS was that one could only get the domain name from the URL, in this case www.example.com
To make sure it's not the client's fault, I requested the webservice resource with Retrofit and HttpsURLConnection and I could see the whole request both times.
I guess also the certificate is properly installed because it is shown in the browser every time an https request is made. Am I missing something else here or is this the normal behaviour?
So far I couldn't find a reason for this to happen so any help will be appreciated.
To debug with Charles proxy you must install a certificate on your browser (client).
With https the URL is encrypted.
But because you choose to use that proxy, your browser establish a secure connection to that proxy, and the proxy to the website. So, only 1) you, 2) the proxy 3)the website can decrypt the https traffic.
By installing a CA certificate on your browser, you allow the person detaining the corresponding private key (in your case, your proxy) to impersonate (so, decrypt with a MITM) any website.
I have a ASP.NET website deployed to IIS with a couple of ashx that returns JSONs to be consumed by an Android application.
I have implemented an authentication logic using Basic Authentication.
The problem: When accessed from Android, the server response is a 400 Bad request. The httperr log file says "400 - Hostname -".
It works when I try it out on localhost from Android emulator
It works when accessing the ashx file on the server from a browser
It works when replicating the call in Fiddler
(If I use Fiddler with the Android Emulator, the Response will be -1 (and looking in Fiddler at the raw data sent, it seems to loose the host from the url) - but this is another issue so don't dwell on that, i just thought I would mention it...)
Turns out my problem (and solution) was the same as in this thread:
HTTP POST request with authorization on android
Grails 1.3.7
I have some code that looks like this...
response.setHeader("Content-disposition", "attachment; filename=${fileName}")
response.contentType = download.contentType
response.contentLength = file.length()
response.outputStream << file.getBytes()
On the desktop and on the iPad, the downloads work just fine. But on android devices it just gives me "Unknown myserver.com In progress". And then eventually fails. A couple of points...
This happens locally, staging, and on production servers
Testing without SSL, everything works fine.
When I try the download in the Dolphin Browser I get the same results
with an added bit of text "Waiting for data connection"
Update #2: Stacktrace that only occurs when downloading from an Android device:
Stacktrace follows:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at com.sun.net.ssl.internal.ssl.OutputRecord.writeBuffer(OutputRecord.java:297)
at com.sun.net.ssl.internal.ssl.OutputRecord.write(OutputRecord.java:286)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:743)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:731)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
at com.wbr.consumer.ProductController$_closure1_closure2.doCall(ProductController.groovy:30)
at com.wbr.consumer.ProductController$_closure1.doCall(ProductController.groovy:28)
at com.wbr.consumer.ProductController$_closure1.doCall(ProductController.groovy)
at java.lang.Thread.run(Thread.java:680)
I realize this is a few months late but I also ran into this issue with the Android browser and a Grails application I was working on.
The issue appears to be how Android handles downloadable content and the android browser integration with download manager.
http://code.google.com/p/android/issues/detail?id=1978
http://code.google.com/p/android/issues/detail?id=18462
I was receiving two requests on the server side for a downloadable file; one from the browser and one from the download manager. The one from the browser ends up getting terminated and the socket closed as soon as the browser determines that it is downloadable content. The browser then hands off the download to the download manager.
I was also having issues with the download failing from download manager but that had to due with me not sending headers as soon as they were ready. I ran into this only with larger APKs, small APKs (under 10-20K) seemed to download just fine.
Some code may help:
response.contentType = 'application/vnd.android.package-archive'
response.addHeader('Content-Disposition', 'attachment; filename=FILENAME.APK')
// output file content
response.setStatus(200)
response.setContentLength("CONTENTSIZE")
// send headers
response.flushBuffer()
try {
response.outputStream << {FILE}.getBytes()
response.outputStream.flush()
} catch (SocketException e) {
log.error(e)
}
return
With this, I always end up with one socket exception. Don't know if thats avoidable, from some quick searching I didn't see a way to determine socket state from servlet without simply trying to write to the socket.
It sounds like there are potentially 2 issues
the browser you are using does not trust the self signed cert.
Do other SSL sites work from this browser?
Can you install your STG
cert into the browser's trusted certs store?
A stupid question is : did you get the request URL correct? https vs http ... i know it's stupid.....
the response is never flushed to the client. Try this:
response.outputStream.flush()
I am creating an aplication that involves an WebView. The thing is that I want to load the full page and not the mobile one, so I have changed the User Agent. Nevertheless there are pages that loads the mobile version.
Here are two versions of code that I have tried:
1.webview.getSettings().setUserAgentString("Mozila ");
2.
String DESKTOP_USERAGENT = webview.getSettings().getUserAgentString ();
DESKTOP_USERAGENT = DESKTOP_USERAGENT.replace("Mobile ","");
webview.getSettings().setUserAgentString(DESKTOP_USERAGENT);
This are exemples of webpages that loads the mobile version in any cases:
http://www.jurnalul.ro
http://www.androidzoom.com
1.Does anyone knows how I can trick the server and tell him I am using a desktop and not a mobile?
2.How does a website knows that I am using a mobile version?
Thank you very much,
Razvan
The problem may be that if you are using a device that your carrier is routing all your HTTP requests through a proxy, and that the proxy is changing the User-Agent. Check on the other end, with your own server, using nc -l 80 -vvv that your request is indeed sending the User-Agent that you have modified.
EDIT: Some specific troubleshooting steps
Forward a port 9090 on your router to your desktop machine or laptop.
Download netcat
Run netcat with the command "nc -l 9090 -vvv"
In your Android application's WebView, make an HTTP request with the User-Agent you are injecting to http://your.ip.address:9090
In the terminal you ran netcat, you will see the HTTP request dump in plain text. There you can check the HTTP header User-Agent to see if it has been changed by a proxy server or not.
You cannot test this stuff with Wireshark or Fiddler because it is happening in the WAN. You need to test it on the receiving end, either on a server, or on your own desktop machine.
webview.getSettings().setUserAgent(1);//for desktop 1 or mobil 0.