最近在给自己的二步验证项目开发基于 webdav 的备份功能,按套路,自然是先去 pub 仓库搜索相关的包。然后就顺利地发现了这么个东西:webdav_client。
可是在实际使用时,发现虽然可以顺利备份文件,但是在恢复的时候却爆出了读取错误。
I/flutter ( 9654): Response Text:
I/flutter ( 9654): [60, 97, 32, 104, 114, 101, 102, 61, 34, 104, 116, 116, 112, 115, 58, 47, 47, 99, 110, 45, 98, 101, 105, 106, 105, 110, 103, 45, 100, 97, 116, 97, 46, 97, 108
I/flutter ( 9654):
I/flutter ( 9654): ERROR ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter ( 9654): ERROR │ #0 Log.e (package:kakunin/utils/log.dart:22:13)
log.dart:22
I/flutter ( 9654): ERROR │ #1 CloudAccountNotifier.restoreWebDav (package:kakunin/provider.dart:304:11)
provider.dart:304
I/flutter ( 9654): ERROR ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter ( 9654): ERROR │ ⛔ DioError [bad response]: null
I/flutter ( 9654): ERROR │ ⛔ Error: Found
I/flutter ( 9654): ERROR └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
首先,我连接的 webdav 是在局域网的树莓派上,通过 Alist 转发的阿里云盘。粗略看了下,既然日志显示已经打印了 Response Text
的数组,最后却报错为空,那估计应该是作者没能正确处理状态码为 3xx 时转发的情况,而直接抛出了错误。
那么思路就很清晰了:
克隆其源代码,运行 example,根据抛错很容易定位到文件 lib/src/webdav_dio.dart
,可见有如此内容:
if (resp.statusCode != 200) {
throw newResponseError(resp);
}
果然,只要不是 200 就抛错了,没有进一步处理。
那处理起来也是很简单的,只要针对 3XX 的情况做一些额外判断即可,追加如下内容:
if (resp.statusCode! >= 300 && resp.statusCode! < 400) {
return (await this.req(
self,
'GET',
resp.headers["location"]!.first, // 获取到重定向的正确地址,再次请求一遍
optionsHandler: (options) =>
options.responseType = ResponseType.bytes,
onReceiveProgress: onProgress,
cancelToken: cancelToken,
)).data;
}
然后发现在请求时被强行拼接了原本的 host,导致依旧出错。再次修正 req
方法内的请求地址即可:
var resp = await this.requestUri<T>(
Uri.parse(
'${path.startsWith(RegExp(r'(http|https)://')) ? path : join(self.uri, path)}'),
options: options,
data: data,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
cancelToken: cancelToken,
);
此时经过测试,已经可以读取到 Alist 转发的阿里云盘内容。
总的来说,问题不大,稍有糟心而已。