最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

kotlin - Downloading APK file from diy rust server to android app results in End of Stream error - Stack Overflow

programmeradmin0浏览0评论

As the title says I'm trying, for both functionality and learning purposes, to use a rust server to "host" the newest version of my android app apk and download the apk to my phone when a newer version is available.

As far as I can tell the rust server is correctly writing the data (I'm just using std::fs::read and TcpStream::write_all). The logcat is showing that I'm picking up chunks. What doesn't seem to be happening is that the stream gets interrupted every time just a few kilobytes shy. The file gets created and has most of the data written to it. I'm convinced it must be the rust server for whatever reason is closing the connection before the app is finished receiving.

Here's my rust code:

fn handle_get_apk(stream: TcpStream) {

    HttpResponseBuilder { 
        status : "200 OK".to_string(),
        headers : vec![],
        body : String::new()
    }.build_with_bytes(match fs::read(apk::get_apk_path()) {
        Ok(k_) => k_,
        Err(e_) => {
            error_response(stream, hkslib::error::format_error("handle_get_apk", e_.to_string()));

            return;
    }}).write_all(&stream);

}

fn build_with_bytes (&self, body_bytes: Vec<u8>) -> HttpStream {
        let mut res = format!("HTTP/1.1 {}\r\nAccept-Ranges: bytes\r\n", self.status);

        for header in &self.headers {
            res = res + &header + "\r\n";
        }

        let length = body_bytes.len();
        res = res + &format!("Content-Length: {}\r\n\r\n", length);

        let mut response = res.as_bytes().to_vec();
        response.extend_from_slice(&body_bytes);

        HttpStream {
            bytes : response
        }
    }
}

Here's the android kotlin code:

 fun getFile(destination: String, client: HttpClient, headers: ArrayList<Pair<String, String>>?) {

        GlobalScope.launch(Dispatchers.IO) {

            log("sending request to $destination")

                    var localfile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "app.apk")

            runBlocking {
                client.prepareGet(destination, block = {

                    headers?.forEach { (key, value) ->
                        header(key, value)
                    }

                }).execute { response: HttpResponse ->
                    if(response.status.value >= 400) {
                        println(response.toString())
                        return@execute
                    }
                    val channel = response.bodyAsChannel()
                    while(!channel.isClosedForRead) {
                        try {
                            val packet = channel.readRemaining(4096) // I've tried using different values, no effect
                            while (!packet.exhausted()) {
                                val bytes = packet.readByteArray()
                                localFile.appendBytes(bytes)
                                _log("Received ${localFile.length()} bytes from ${response.contentLength()}")
                            }
                        } catch (e: Exception) {
                            _log("Failed to complete capture... $e")
                            e.printStackTrace()
                            break
                        }
                    }
                }
            }

        }

Some other notes about the general architecture, the rust server is running on 4 threads with workers handling each request. This is not going to become a commercial app so I'm skipping a lot of the usual scoped storage restrictions for convenience.

Thoughts?

I've tried different headers, timeout settings, sending as chunks server side (couldn't get it to work tbh).

I haven't found anything on stackoverflow or github that gives me a solution

I'm expecting the file to be created and appended with all the data, the file is being created and appended with ~95% of the data

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论