Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
058bf23465 | ||
|
|
7fec4c52a1 |
@@ -26,8 +26,8 @@ android {
|
||||
applicationId "com.example.androidbackupgui"
|
||||
minSdk 24
|
||||
targetSdk 34
|
||||
versionCode 8
|
||||
versionName "1.7"
|
||||
versionCode 10
|
||||
versionName "1.9"
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
|
||||
@@ -68,7 +68,7 @@ class RestBridgeRunner {
|
||||
val bridge = ResticRestBridge(transport, remoteBase, cacheDir)
|
||||
|
||||
try {
|
||||
bridge.start(60_000)
|
||||
bridge.start(0)
|
||||
val port = bridge.listeningPort
|
||||
if (port < 0) {
|
||||
throw IllegalStateException("REST bridge failed to bind a port")
|
||||
|
||||
@@ -110,13 +110,39 @@ class ResticRestBridge(
|
||||
* Returns the temp file (caller must delete).
|
||||
*/
|
||||
private fun streamBodyToFile(session: IHTTPSession, tmpDir: File): Result<File> {
|
||||
val started = System.currentTimeMillis()
|
||||
return try {
|
||||
val tmpFile = File(tmpDir, "restic_blob_${UUID.randomUUID()}")
|
||||
val contentLength = session.headers["content-length"]?.toLongOrNull() ?: -1L
|
||||
val input = (session as NanoHTTPD.HTTPSession).inputStream
|
||||
tmpFile.outputStream().use { output -> input.copyTo(output) }
|
||||
Log.d(TAG, "streamBodyToFile: reading body (content-length=$contentLength)...")
|
||||
tmpFile.outputStream().use { output ->
|
||||
if (contentLength > 0) {
|
||||
// Read exactly Content-Length bytes to avoid blocking on keep-alive
|
||||
val buf = ByteArray(8192)
|
||||
var remaining = contentLength
|
||||
while (remaining > 0) {
|
||||
val toRead = minOf(buf.size.toLong(), remaining).toInt()
|
||||
val n = input.read(buf, 0, toRead)
|
||||
if (n == -1) break
|
||||
output.write(buf, 0, n)
|
||||
remaining -= n
|
||||
}
|
||||
if (remaining > 0) {
|
||||
Log.w(TAG, "streamBodyToFile: body truncated, expected $contentLength bytes but got EOF after ${contentLength - remaining}")
|
||||
}
|
||||
Unit
|
||||
} else {
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
val elapsed = System.currentTimeMillis() - started
|
||||
val bytes = tmpFile.length()
|
||||
Log.i(TAG, "streamBodyToFile: read $bytes bytes in ${elapsed}ms")
|
||||
Result.success(tmpFile)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "stream body to file failed", e)
|
||||
val elapsed = System.currentTimeMillis() - started
|
||||
Log.w(TAG, "streamBodyToFile failed after ${elapsed}ms", e)
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import java.io.File
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
@@ -190,21 +189,12 @@ class ConfigViewModel(application: Application) : AndroidViewModel(application)
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
_operationEvents.emit(OperationEvent.InitStarted)
|
||||
val result = withTimeoutOrNull(60_000L) {
|
||||
ResticWrapper.init(form.repo, form.password,
|
||||
backend = form.backend, backendUrl = form.backendUrl,
|
||||
backendUser = form.backendUser, backendPass = form.backendPass,
|
||||
backendShare = form.backendShare,
|
||||
)
|
||||
}
|
||||
if (result == null) {
|
||||
_operationEvents.emit(OperationEvent.InitFailed)
|
||||
Log.w(TAG, "initResticRepo timed out after 1 minute")
|
||||
_uiState.update { it.copy(resticStatus = it.resticStatus.copy(
|
||||
message = "初始化超时(1分钟),请检查网络/SMB 服务器是否正常"
|
||||
))}
|
||||
refreshResticStatus(form)
|
||||
} else if (result.isSuccess) {
|
||||
val result = ResticWrapper.init(form.repo, form.password,
|
||||
backend = form.backend, backendUrl = form.backendUrl,
|
||||
backendUser = form.backendUser, backendPass = form.backendPass,
|
||||
backendShare = form.backendShare,
|
||||
)
|
||||
if (result.isSuccess) {
|
||||
_operationEvents.emit(OperationEvent.InitCompleted)
|
||||
_uiState.update { it.copy(resticStatus = it.resticStatus.copy(
|
||||
message = "仓库初始化成功: ${form.repo}"
|
||||
|
||||
Reference in New Issue
Block a user