Skip to content

Commit 2e06a67

Browse files
committed
compose: For uploads, use verbatim URL string from server
Fixes #1709. Round-tripping through `Uri.parse` and `.toString()` had the effect of percent-encoding any non-ASCII characters in the given URL string. The server expects, reasonably enough, that the client will refer to the upload using the same URL string the server provided at upload time; so do that.
1 parent c7f336c commit 2e06a67

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

lib/widgets/compose_box.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,9 @@ class ComposeContentController extends ComposeController<ContentValidationError>
359359

360360
/// Tells the controller that a file upload has ended, with success or error.
361361
///
362-
/// To indicate success, pass the URL to be used for the Markdown link.
362+
/// To indicate success, pass the URL string to be used for the Markdown link.
363363
/// If `url` is null, failure is assumed.
364-
void registerUploadEnd(int tag, Uri? url) {
364+
void registerUploadEnd(int tag, String? url) {
365365
final val = _uploads[tag];
366366
assert(val != null, 'registerUploadEnd called twice for same tag');
367367
final (:filename, :placeholder) = val!;
@@ -372,7 +372,7 @@ class ComposeContentController extends ComposeController<ContentValidationError>
372372

373373
value = value.replaced(
374374
replacementRange,
375-
url == null ? '' : inlineLink(filename, url.toString()));
375+
url == null ? '' : inlineLink(filename, url));
376376
_uploads.remove(tag);
377377
notifyListeners(); // _uploads change could affect validationErrors
378378
}
@@ -971,15 +971,15 @@ Future<void> _uploadFiles({
971971

972972
for (final (tag, file) in uploadsInProgress) {
973973
final _File(:content, :length, :filename, :mimeType) = file;
974-
Uri? url;
974+
String? url;
975975
try {
976976
final result = await uploadFile(store.connection,
977977
content: content,
978978
length: length,
979979
filename: filename,
980980
contentType: mimeType,
981981
);
982-
url = Uri.parse(result.url);
982+
url = result.url;
983983
} catch (e) {
984984
if (!context.mounted) return;
985985
// TODO(#741): Specifically handle `413 Payload Too Large`

test/widgets/compose_box_test.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,34 @@ void main() {
11681168
// target platform the test is simulating.
11691169
// TODO(upstream): unskip after fix to https://github.com/flutter/flutter/issues/161073
11701170
skip: Platform.isWindows);
1171+
1172+
testWidgets('use verbatim URL string from server, not re-encoded', (tester) async {
1173+
// Regression test for: https://github.com/zulip/zulip-flutter/issues/1709
1174+
TypingNotifier.debugEnable = false;
1175+
addTearDown(TypingNotifier.debugReset);
1176+
1177+
final channel = eg.stream();
1178+
final narrow = eg.topicNarrow(channel.streamId, 'a topic');
1179+
await prepareComposeBox(tester, narrow: narrow, streams: [channel]);
1180+
1181+
testBinding.pickFilesResult = FilePickerResult([PlatformFile(
1182+
readStream: Stream.fromIterable(['asdf'.codeUnits]),
1183+
path: '/some/path/한국어 파일.txt',
1184+
name: '한국어 파일.txt',
1185+
size: 4,
1186+
)]);
1187+
connection.prepare(json: UploadFileResult(url:
1188+
'/user_uploads/1/4e/m2A3MSqFnWRLUf9SaPzQ0Up_/한국어 파일.txt').toJson());
1189+
await tester.tap(find.byIcon(ZulipIcons.image));
1190+
await tester.pump();
1191+
check(controller!.content.text)
1192+
.equals('[Uploading 한국어 파일.txt…]()\n\n');
1193+
1194+
await tester.pump(Duration.zero);
1195+
check(controller!.content.text)
1196+
.equals('[한국어 파일.txt]('
1197+
'/user_uploads/1/4e/m2A3MSqFnWRLUf9SaPzQ0Up_/한국어 파일.txt)\n\n');
1198+
});
11711199
});
11721200

11731201
group('error banner', () {

0 commit comments

Comments
 (0)