Android内置浏览器和下载

时间:2014-08-16 17:54:29

标签: android http apk android-browser

这让我疯了。我想提供一个.apk文件供下载。我测试过的所有浏览器都会毫无问题地下载我的文件。除了android中的内置浏览器。出于某种奇怪的原因,它将重复对资源的请求。使用BurpSuite我发现apk文件传输完美无缺。我代理文件,但我立即发送标题,使用curl我可以确认标题已发送,内容开始在下面传输。我将我的标题与threema.ch发送的标题进行了比较,这些标题完美无缺。

这些标题由我的应用程序发送:

HTTP/1.1 200 OK
Date: Sat, 16 Aug 2014 16:41:01 GMT
Server: Apache/2.4.7
Content-Disposition: attachment; filename="test.apk"
Content-Type: application/vnd.android.package-archive
Transfer-Encoding: Chunked

这些标题由Threema发送:

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 16 Aug 2014 17:49:10 GMT
Content-Type: application/vnd.android.package-archive
Content-Length: 14146751
Connection: keep-alive
Content-Disposition: attachment; filename="Threema-1.63.apk"
Strict-Transport-Security: max-age=31536000; includeSubdomains

我首先通过iframe加载了该文件。目前我正在使用HTTP重定向将浏览器重定向到下载。我从不同的子域提供文件。但我也尝试从同一个域提供文件并使用html链接。

这些是客户端发送的标头。第一:

GET /download/download/NlnMhaeXmcjSosfqRTcG8YdxQgQGSxTWQeE10-GrH4U HTTP/1.1
Host: l.dl.test
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Linux; Android 4.4.4; Nexus 7 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Safari/537.36
Referer: http://l.google/device/deviceid/351cd7c24f637eb5?token=6Xf3nJIIMIa4toKrpTqgDGFjAKzeBBoaeduMmcIMeGY
Accept-Encoding: gzip,deflate
Accept-Language: de-DE,en-US;q=0.8
X-Requested-With: com.android.browser

然后(大约20年后):

GET /download/download/NlnMhaeXmcjSosfqRTcG8YdxQgQGSxTWQeE10-GrH4U HTTP/1.1
User-Agent: Mozilla/5.0 (Linux; Android 4.4.4; Nexus 7 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Safari/537.36
Referer: 
cookie: 
Accept-Encoding: identity
Host: l.dl.test
Connection: Keep-Alive

我正在生成一次性使用的下载ID。第二个请求将失败,因为在第一个请求后,id变为无效。如果我允许第二次尝试下载文件,则下载有效。

可能是android浏览器在第一次尝试时想要压缩内容,如果它获得了身份内容,它将使用Accept-Encoding身份进行第二次尝试?我也试过没有运气设置Content-Encoding: identity

解决方法: 我没有发送.apk两次的唯一方法就是使用这个非常愚蠢(并且容易出错)的解决方法:

header("Content-Disposition: attachment; filename=\"test.apk\"");
header('Content-Type: application/vnd.android.package-archive');

// Ugly workaround for bug in built-in android browser.
if (
  isset($_SERVER['HTTP_X_REQUESTED_WITH'])
  && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'com.android.browser')
  && isset($_SERVER['HTTP_ACCEPT_ENCODING'])
  && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'identity') === FALSE)
) {
    // The built-in android browser will make two requests for the apk
    // file, one with Accept-Encoding gzip and deflate and one with
    // Accept-Encoding identity. But it will only serve the second request
    // with Accept encoding identity. So stop the first request.

    // If the first request is shown, the workaround didn't work.
    die ("Oh no! I'm sorry. The built-in android browser has a nasty bug."
    . " It's hard to work around. If you see this the workaround failed."
    . " Please try downloading with a different browser.");
}

0 个答案:

没有答案