Browse Source

fix(nextcloud): Fix WebDAV path construction

Signed-off-by: jld3103 <jld3103yt@gmail.com>
pull/1096/head
jld3103 1 year ago
parent
commit
8796b8c58f
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 19
      packages/nextcloud/lib/src/webdav/client.dart
  2. 14
      packages/nextcloud/lib/src/webdav/file.dart
  3. 35
      packages/nextcloud/test/webdav_test.dart

19
packages/nextcloud/lib/src/webdav/client.dart

@ -10,7 +10,7 @@ import 'package:universal_io/io.dart';
import 'package:xml/xml.dart' as xml;
/// Base path used on the server
const String webdavBasePath = '/remote.php/webdav';
final webdavBase = Uri(path: '/remote.php/webdav');
/// WebDavClient class
class WebDavClient {
@ -65,20 +65,11 @@ class WebDavClient {
@visibleForTesting
// ignore: public_member_api_docs
static Uri constructUri(final Uri baseURL, [final Uri? path]) {
assert(
path == null || path.path == '/' || !path.path.startsWith('/'),
"The path should not start a '/' unless indicating the root folder.",
);
assert(!baseURL.path.endsWith('/'), "The baseURL should not end with a '/'.");
final pathBuffer = StringBuffer(baseURL.path)..write(webdavBasePath);
if (path != null && path.path != '/') {
pathBuffer
..write('/')
..write(path.path);
final segments = baseURL.pathSegments.toList()..addAll(webdavBase.pathSegments);
if (path != null) {
segments.addAll(path.pathSegments);
}
return baseURL.replace(path: pathBuffer.toString());
return baseURL.replace(pathSegments: segments.where((final s) => s.isNotEmpty));
}
Future<WebDavMultistatus> _parseResponse(final HttpClientResponse response) async =>

14
packages/nextcloud/lib/src/webdav/file.dart

@ -25,8 +25,8 @@ class WebDavFile {
_response.propstats.singleWhere((final propstat) => propstat.status.contains('200')).prop;
/// The path of file
late final String path =
Uri.decodeFull(_response.href!.substring(Uri.encodeFull(webdavBasePath).length, _response.href!.length));
late final Uri path =
Uri(pathSegments: Uri(path: _response.href).pathSegments.sublist(webdavBase.pathSegments.length));
/// The fileid namespaced by the instance id, globally unique
late final String? id = props.ocid;
@ -79,17 +79,11 @@ class WebDavFile {
late final bool? hasPreview = props.nchaspreview;
/// Returns the decoded name of the file / folder without the whole path
late final String name = () {
// normalized path (remove trailing slash)
final end = path.endsWith('/') ? path.length - 1 : path.length;
final segments = Uri.parse(path, 0, end).pathSegments;
return segments.lastOrNull ?? '';
}();
late final String name = path.pathSegments.where((final s) => s.isNotEmpty).lastOrNull ?? '';
/// Whether the file is hidden.
late final bool isHidden = name.startsWith('.');
/// Whether the file is a directory
late final bool isDirectory = (isCollection ?? false) || path.endsWith('/');
late final bool isDirectory = (isCollection ?? false) || path.pathSegments.last.isEmpty;
}

35
packages/nextcloud/test/webdav_test.dart

@ -9,18 +9,25 @@ import 'package:universal_io/io.dart';
import 'helper.dart';
void main() {
test('constructUri', () {
var baseURL = Uri.parse('http://cloud.example.com');
expect(WebDavClient.constructUri(baseURL).toString(), '$baseURL$webdavBasePath');
expect(WebDavClient.constructUri(baseURL, Uri(path: '/')).toString(), '$baseURL$webdavBasePath');
expect(WebDavClient.constructUri(baseURL, Uri(path: 'test')).toString(), '$baseURL$webdavBasePath/test');
baseURL = Uri.parse('http://cloud.example.com/subdir');
expect(WebDavClient.constructUri(baseURL, Uri(path: 'test')).toString(), '$baseURL$webdavBasePath/test');
expect(() => WebDavClient.constructUri(baseURL, Uri(path: '/test')), throwsA(isA<AssertionError>()));
baseURL = Uri.parse('http://cloud.example.com/');
expect(() => WebDavClient.constructUri(baseURL), throwsA(isA<AssertionError>()));
group('constructUri', () {
for (final values in [
('http://cloud.example.com', 'http://cloud.example.com'),
('http://cloud.example.com/', 'http://cloud.example.com'),
('http://cloud.example.com/subdir', 'http://cloud.example.com/subdir'),
('http://cloud.example.com/subdir/', 'http://cloud.example.com/subdir'),
]) {
final baseURL = Uri.parse(values.$1);
final sanitizedBaseURL = Uri.parse(values.$2);
test('$baseURL', () {
expect(WebDavClient.constructUri(baseURL).toString(), '$sanitizedBaseURL$webdavBase');
expect(WebDavClient.constructUri(baseURL, Uri(path: '/')).toString(), '$sanitizedBaseURL$webdavBase');
expect(WebDavClient.constructUri(baseURL, Uri(path: 'test')).toString(), '$sanitizedBaseURL$webdavBase/test');
expect(WebDavClient.constructUri(baseURL, Uri(path: 'test/')).toString(), '$sanitizedBaseURL$webdavBase/test');
expect(WebDavClient.constructUri(baseURL, Uri(path: '/test')).toString(), '$sanitizedBaseURL$webdavBase/test');
expect(WebDavClient.constructUri(baseURL, Uri(path: '/test/')).toString(), '$sanitizedBaseURL$webdavBase/test');
});
}
});
group(
@ -100,7 +107,7 @@ void main() {
.toWebDavFiles()
.single;
expect(response.path, '/Nextcloud.png');
expect(response.path, Uri(path: 'Nextcloud.png'));
expect(response.id, isNotEmpty);
expect(response.fileId, isNotEmpty);
expect(response.isCollection, isFalse);
@ -165,7 +172,7 @@ void main() {
.toWebDavFiles()
.single;
expect(response.path, '/test/');
expect(response.path, Uri(path: 'test/'));
expect(response.isCollection, isTrue);
expect(response.mimeType, isNull);
expect(response.size, data.lengthInBytes);

Loading…
Cancel
Save