ObjFW  Check-in [7ffbd24169]

Overview
Comment:ofhttp: Move formatting out of localized strings
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 7ffbd24169573cb77d59c08ea9dae979790d60f5c9ed6f8a3ccc3c7c6b348de6
User & Date: js on 2017-02-27 21:57:16
Other Links: manifest | tags
Context
2017-02-27
22:04
OFLocalization: Don't lower language and territory check-in: 0e82e3b843 user: js tags: trunk
21:57
ofhttp: Move formatting out of localized strings check-in: 7ffbd24169 user: js tags: trunk
21:36
Localize ofhash check-in: 3f2b4a8941 user: js tags: trunk
Changes

Modified utils/ofhttp/OFHTTP.m from [cc6aaa39b2] to [c3a4b738ae].

70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
@end

OF_APPLICATION_DELEGATE(OFHTTP)

static void
help(OFStream *stream, bool full, int status)
{
	[of_stderr writeString:
	    OF_LOCALIZED(@"usage",
	    @"Usage: %[prog] -[cehHmoOPqv] url1 [url2 ...]\n",
	    @"prog", [OFApplication programName])];

	if (full)
		[stream writeString: OF_LOCALIZED(@"full_usage",

		    @"\nOptions:\n    "
		    @"-b  --body           "
		    @"  Specify the file to send as body\n    "
		    @"-c  --continue       "
		    @"  Continue download of existing file\n    "
		    @"-f  --force          "
		    @"  Force / overwrite existing file\n    "
		    @"-h  --help           "







|

|


|
|
>
|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
@end

OF_APPLICATION_DELEGATE(OFHTTP)

static void
help(OFStream *stream, bool full, int status)
{
	[of_stderr writeLine:
	    OF_LOCALIZED(@"usage",
	    @"Usage: %[prog] -[cehHmoOPqv] url1 [url2 ...]",
	    @"prog", [OFApplication programName])];

	if (full) {
		[stream writeString: @"\n"];
		[stream writeLine: OF_LOCALIZED(@"full_usage",
		    @"Options:\n    "
		    @"-b  --body           "
		    @"  Specify the file to send as body\n    "
		    @"-c  --continue       "
		    @"  Continue download of existing file\n    "
		    @"-f  --force          "
		    @"  Force / overwrite existing file\n    "
		    @"-h  --help           "
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
		    @"-P  --proxy          "
		    @"  Specify SOCKS5 proxy\n    "
		    @"-q  --quiet          "
		    @"  Quiet mode (no output, except errors)\n    "
		    @"-v  --verbose        "
		    @"  Verbose mode (print headers)\n    "
		    @"    --insecure       "
		    @"  Ignore TLS errors\n")];


	[OFApplication terminateWithStatus: status];
}

@implementation OFHTTP
- init
{







|
>







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
		    @"-P  --proxy          "
		    @"  Specify SOCKS5 proxy\n    "
		    @"-q  --quiet          "
		    @"  Quiet mode (no output, except errors)\n    "
		    @"-v  --verbose        "
		    @"  Verbose mode (print headers)\n    "
		    @"    --insecure       "
		    @"  Ignore TLS errors")];
	}

	[OFApplication terminateWithStatus: status];
}

@implementation OFHTTP
- init
{
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

- (void)addHeader: (OFString*)header
{
	size_t pos = [header rangeOfString: @":"].location;
	OFString *name, *value;

	if (pos == OF_NOT_FOUND) {
		[of_stderr writeString: OF_LOCALIZED(@"invalid_input_header",
		    @"%[prog]: Headers must to be in format name:value!\n",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	name = [header substringWithRange: of_range(0, pos)];
	name = [name stringByDeletingEnclosingWhitespaces];








|
|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

- (void)addHeader: (OFString*)header
{
	size_t pos = [header rangeOfString: @":"].location;
	OFString *name, *value;

	if (pos == OF_NOT_FOUND) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_input_header",
		    @"%[prog]: Headers must to be in format name:value!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	name = [header substringWithRange: of_range(0, pos)];
	name = [name stringByDeletingEnclosingWhitespaces];

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
	else if ([method isEqual: @"PUT"])
		_method = OF_HTTP_REQUEST_METHOD_PUT;
	else if ([method isEqual: @"DELETE"])
		_method = OF_HTTP_REQUEST_METHOD_DELETE;
	else if ([method isEqual: @"TRACE"])
		_method = OF_HTTP_REQUEST_METHOD_TRACE;
	else {
		[of_stderr writeString: OF_LOCALIZED(@"invalid_input_method",
		    @"%[prog]: Invalid request method %[method]!\n",
		    @"prog", [OFApplication programName],
		    @"method", method)];
		[OFApplication terminateWithStatus: 1];
	}

	objc_autoreleasePoolPop(pool);
}







|
|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
	else if ([method isEqual: @"PUT"])
		_method = OF_HTTP_REQUEST_METHOD_PUT;
	else if ([method isEqual: @"DELETE"])
		_method = OF_HTTP_REQUEST_METHOD_DELETE;
	else if ([method isEqual: @"TRACE"])
		_method = OF_HTTP_REQUEST_METHOD_TRACE;
	else {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_input_method",
		    @"%[prog]: Invalid request method %[method]!",
		    @"prog", [OFApplication programName],
		    @"method", method)];
		[OFApplication terminateWithStatus: 1];
	}

	objc_autoreleasePoolPop(pool);
}
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

		if (port > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		[OFTCPSocket setSOCKS5Host: host];
		[OFTCPSocket setSOCKS5Port: (uint16_t)port];
	} @catch (OFInvalidFormatException *e) {
		[of_stderr writeString: OF_LOCALIZED(@"invalid_input_proxy",
		    @"%[prog]: Proxy must to be in format host:port!\n",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}
}

- (void)applicationDidFinishLaunching
{







|
|







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

		if (port > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		[OFTCPSocket setSOCKS5Host: host];
		[OFTCPSocket setSOCKS5Port: (uint16_t)port];
	} @catch (OFInvalidFormatException *e) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_input_proxy",
		    @"%[prog]: Proxy must to be in format host:port!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}
}

- (void)applicationDidFinishLaunching
{
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
			[self setMethod: [optionsParser argument]];
			break;
		case 'P':
			[self setProxy: [optionsParser argument]];
			break;
		case ':':
			if ([optionsParser lastLongOption] != nil)
				[of_stderr writeString:
				    OF_LOCALIZED(@"long_argument_missing",
				    @"%[prog]: Argument for option --%[opt] "
				    "missing\n"
				    @"prog", [OFApplication programName],
				    @"opt", [optionsParser lastLongOption])];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%c",
				    [optionsParser lastOption]];
				[of_stderr writeString:
				    OF_LOCALIZED(@"argument_missing",
				    @"%[prog]: Argument for option -%[opt] "
				    "missing\n",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		case '=':
			[of_stderr writeString:
			    OF_LOCALIZED(@"takes_no_argument",
			    @"%[prog]: Option --%[opt] takes no argument\n",
			    @"prog", [OFApplication programName],
			    @"opt", [optionsParser lastLongOption])];

			[OFApplication terminateWithStatus: 1];
			break;
		case '?':
			if ([optionsParser lastLongOption] != nil)
				[of_stderr writeString:
				    OF_LOCALIZED(@"unknown_long_option",
				    @"%[prog]: Unknown option: --%[opt]\n",
				    @"prog", [OFApplication programName],
				    @"opt", [optionsParser lastLongOption])];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%c",
				    [optionsParser lastOption]];
				[of_stderr writeString:
				    OF_LOCALIZED(@"unknown_option",
				    @"%[prog]: Unknown option: -%[opt]\n",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		}
	}

	_outputPath = [outputPath copy];
	_URLs = [[optionsParser remainingArguments] retain];

	if ([_URLs count] < 1)
		help(of_stderr, false, 1);

	if (_quiet && _verbose) {
		[of_stderr writeString: OF_LOCALIZED(@"quiet_xor_verbose",
		    @"%[prog]: -q / --quiet and -v / --verbose are mutually "
		    @"exclusive!\n",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	if (_outputPath != nil && [_URLs count] > 1) {
		[of_stderr writeString:
		    OF_LOCALIZED(@"output_only_with_one_url",
		    @"%[prog]: Cannot use -o / --output when more than one URL "
		    @"has been specified!\n",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}







|


|






|


|







|
|
|







|

|






|

|
















|

|





|


|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
			[self setMethod: [optionsParser argument]];
			break;
		case 'P':
			[self setProxy: [optionsParser argument]];
			break;
		case ':':
			if ([optionsParser lastLongOption] != nil)
				[of_stderr writeLine:
				    OF_LOCALIZED(@"long_argument_missing",
				    @"%[prog]: Argument for option --%[opt] "
				    @"missing"
				    @"prog", [OFApplication programName],
				    @"opt", [optionsParser lastLongOption])];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%c",
				    [optionsParser lastOption]];
				[of_stderr writeLine:
				    OF_LOCALIZED(@"argument_missing",
				    @"%[prog]: Argument for option -%[opt] "
				    @"missing",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		case '=':
			[of_stderr writeLine:
			    OF_LOCALIZED(@"option_takes_no_argument",
			    @"%[prog]: Option --%[opt] takes no argument",
			    @"prog", [OFApplication programName],
			    @"opt", [optionsParser lastLongOption])];

			[OFApplication terminateWithStatus: 1];
			break;
		case '?':
			if ([optionsParser lastLongOption] != nil)
				[of_stderr writeLine:
				    OF_LOCALIZED(@"unknown_long_option",
				    @"%[prog]: Unknown option: --%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", [optionsParser lastLongOption])];
			else {
				OFString *optStr = [OFString
				    stringWithFormat: @"%c",
				    [optionsParser lastOption]];
				[of_stderr writeLine:
				    OF_LOCALIZED(@"unknown_option",
				    @"%[prog]: Unknown option: -%[opt]",
				    @"prog", [OFApplication programName],
				    @"opt", optStr)];
			}

			[OFApplication terminateWithStatus: 1];
			break;
		}
	}

	_outputPath = [outputPath copy];
	_URLs = [[optionsParser remainingArguments] retain];

	if ([_URLs count] < 1)
		help(of_stderr, false, 1);

	if (_quiet && _verbose) {
		[of_stderr writeLine: OF_LOCALIZED(@"quiet_xor_verbose",
		    @"%[prog]: -q / --quiet and -v / --verbose are mutually "
		    @"exclusive!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	if (_outputPath != nil && [_URLs count] > 1) {
		[of_stderr writeLine:
		    OF_LOCALIZED(@"output_only_with_one_url",
		    @"%[prog]: Cannot use -o / --output when more than one URL "
		    @"has been specified!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481

	@try {
		response = [_HTTPClient performRequest: request];
	} @catch (OFAddressTranslationFailedException *e) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeString:
		    OF_LOCALIZED(@"download_failed_address_translation",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Address translation failed: %[exception]\n",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string],
		    @"exception", e)];
	} @catch (OFConnectionFailedException *e) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeString:
		    OF_LOCALIZED(@"download_failed_connection_failed",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Connection failed: %[exception]\n",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string],
		    @"exception", e)];
	} @catch (OFInvalidServerReplyException *e) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeString:
		    OF_LOCALIZED(@"download_failed_invalid_server_reply",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Invalid server reply!\n",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string])];
	} @catch (OFUnsupportedProtocolException *e) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeString: OF_LOCALIZED(@"no_ssl_library",
		    @"%[prog]: No TLS library loaded!\n"
		    @"  In order to download via https, you need to preload an "
		    @"TLS library for ObjFW\n"
		    "such as ObjOpenSSL!\n",
		    @"prog", [OFApplication programName])];
	} @catch (OFReadOrWriteFailedException *e) {
		OFString *error = OF_LOCALIZED(
		    @"download_failed_read_or_write_failed_any",
		    @"Read or write failed");

		if (!_quiet)
			[of_stdout writeString: @"\n"];

		if ([e isKindOfClass: [OFReadFailedException class]])
			error = OF_LOCALIZED(
			    @"download_failed_read_or_write_failed_read",
			    @"Read failed");
		else if ([e isKindOfClass: [OFWriteFailedException class]])
			error = OF_LOCALIZED(
			    @"download_failed_read_or_write_failed_write",
			    @"Write failed");

		[of_stderr writeString:
		    OF_LOCALIZED(@"download_failed_read_or_write_failed",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  %[error]: %[exception]\n",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string],
		    @"error", error,
		    @"exception", e)];
	} @catch (OFHTTPRequestFailedException *e) {
		if (!_quiet)
			[of_stdout writeFormat: @" ➜ %d\n",
						[[e response] statusCode]];

		[of_stderr writeString: OF_LOCALIZED(@"download_failed",
		    @"%[prog]: Failed to download <%[url]>!\n",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string])];
	}

	if (!_quiet && response != nil)
		[of_stdout writeFormat: @" ➜ %d\n", [response statusCode]];








|


|







|


|







|


|






|



|


















|


|









|
|







400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

	@try {
		response = [_HTTPClient performRequest: request];
	} @catch (OFAddressTranslationFailedException *e) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_failed_address_translation",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Address translation failed: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string],
		    @"exception", e)];
	} @catch (OFConnectionFailedException *e) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_failed_connection_failed",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Connection failed: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string],
		    @"exception", e)];
	} @catch (OFInvalidServerReplyException *e) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_failed_invalid_server_reply",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Invalid server reply!",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string])];
	} @catch (OFUnsupportedProtocolException *e) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeLine: OF_LOCALIZED(@"no_ssl_library",
		    @"%[prog]: No TLS library loaded!\n"
		    @"  In order to download via https, you need to preload an "
		    @"TLS library for ObjFW\n"
		    @"  such as ObjOpenSSL!",
		    @"prog", [OFApplication programName])];
	} @catch (OFReadOrWriteFailedException *e) {
		OFString *error = OF_LOCALIZED(
		    @"download_failed_read_or_write_failed_any",
		    @"Read or write failed");

		if (!_quiet)
			[of_stdout writeString: @"\n"];

		if ([e isKindOfClass: [OFReadFailedException class]])
			error = OF_LOCALIZED(
			    @"download_failed_read_or_write_failed_read",
			    @"Read failed");
		else if ([e isKindOfClass: [OFWriteFailedException class]])
			error = OF_LOCALIZED(
			    @"download_failed_read_or_write_failed_write",
			    @"Write failed");

		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_failed_read_or_write_failed",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  %[error]: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string],
		    @"error", error,
		    @"exception", e)];
	} @catch (OFHTTPRequestFailedException *e) {
		if (!_quiet)
			[of_stdout writeFormat: @" ➜ %d\n",
						[[e response] statusCode]];

		[of_stderr writeLine: OF_LOCALIZED(@"download_failed",
		    @"%[prog]: Failed to download <%[url]>!",
		    @"prog", [OFApplication programName],
		    @"url", [[request URL] string])];
	}

	if (!_quiet && response != nil)
		[of_stdout writeFormat: @" ➜ %d\n", [response statusCode]];

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet)
			[of_stdout writeString: @"\n  Error!\n"];

		URL = [_URLs objectAtIndex: _URLIndex - 1];
		[of_stderr writeString:
		    OF_LOCALIZED(@"download_failed_exception",
		    @"%[prog]: Failed to download <%[url]>: %[exception]\n",
		    @"prog", [OFApplication programName],
		    @"url", URL,
		    @"exception", e)];

		_errorCode = 1;
		goto next;
	}







|

|







617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet)
			[of_stdout writeString: @"\n  Error!\n"];

		URL = [_URLs objectAtIndex: _URLIndex - 1];
		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_failed_exception",
		    @"%[prog]: Failed to download <%[url]>: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", URL,
		    @"exception", e)];

		_errorCode = 1;
		goto next;
	}
640
641
642
643
644
645
646
647
648

649

650
651
652
653
654
655
656
	if ([response isAtEndOfStream] ||
	    (_length >= 0 && _received >= _length)) {
		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet)
			[of_stdout writeString:

			    OF_LOCALIZED(@"download_done", @"\n  Done!\n")];


		goto next;
	}

	return true;

next:







|
|
>
|
>







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
	if ([response isAtEndOfStream] ||
	    (_length >= 0 && _received >= _length)) {
		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet) {
			[of_stdout writeString: @"\n  "];
			[of_stdout writeLine:
			    OF_LOCALIZED(@"download_done", @"Done!")];
		}

		goto next;
	}

	return true;

next:
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
	if (_URLIndex >= [_URLs count])
		[OFApplication terminateWithStatus: _errorCode];

	@try {
		URLString = [_URLs objectAtIndex: _URLIndex++];
		URL = [OFURL URLWithString: URLString];
	} @catch (OFInvalidFormatException *e) {
		[of_stderr writeString: OF_LOCALIZED(@"invalid_url",
		    @"%[prog]: Invalid URL: <%[url]>!\n",
		    @"prog", [OFApplication programName],
		    @"url", URLString)];

		_errorCode = 1;
		goto next;
	}

	if (![[URL scheme] isEqual: @"http"] &&
	    ![[URL scheme] isEqual: @"https"]) {
		[of_stderr writeString: OF_LOCALIZED(@"invalid_scheme",
		    @"%[prog]: Invalid scheme: <%[scheme]:>!\n",
		    @"prog", [OFApplication programName],
		    @"scheme", URLString)];

		_errorCode = 1;
		goto next;
	}








|
|









|
|







684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
	if (_URLIndex >= [_URLs count])
		[OFApplication terminateWithStatus: _errorCode];

	@try {
		URLString = [_URLs objectAtIndex: _URLIndex++];
		URL = [OFURL URLWithString: URLString];
	} @catch (OFInvalidFormatException *e) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_url",
		    @"%[prog]: Invalid URL: <%[url]>!",
		    @"prog", [OFApplication programName],
		    @"url", URLString)];

		_errorCode = 1;
		goto next;
	}

	if (![[URL scheme] isEqual: @"http"] &&
	    ![[URL scheme] isEqual: @"https"]) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_scheme",
		    @"%[prog]: Invalid scheme: <%[scheme]:>!",
		    @"prog", [OFApplication programName],
		    @"scheme", URLString)];

		_errorCode = 1;
		goto next;
	}

810
811
812
813
814
815
816
817


818
819
820
821
822
823
824
825
826
827
828

829
830
831

832
833
834

835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
			OFDictionary OF_GENERIC(OFString*, OFString*) *headers =
			    [response headers];
			OFEnumerator *keyEnumerator = [headers keyEnumerator];
			OFEnumerator *objectEnumerator =
			    [headers objectEnumerator];
			OFString *key, *object;

			[of_stdout writeString: OF_LOCALIZED(@"info_name_nopad",


			    @"  Name: %[name]\n",
			    @"name", fileName)];

			while ((key = [keyEnumerator nextObject]) != nil &&
			    (object = [objectEnumerator nextObject]) != nil)
				[of_stdout writeFormat: @"  %@: %@\n",
							key, object];

			objc_autoreleasePoolPop(pool);
		} else {
			[of_stdout writeString: OF_LOCALIZED(@"info_name",

			    @"  Name: %[name]\n",
			    @"name", fileName)];
			[of_stdout writeString: OF_LOCALIZED(@"info_type",

			    @"  Type: %[type]\n",
			    @"type", type)];
			[of_stdout writeString: OF_LOCALIZED(@"info_size",

			    @"  Size: %[size]\n",
			    @"size", lengthString)];
		}
	}

	if ([_outputPath isEqual: @"-"])
		_output = of_stdout;
	else {
		if (!_continue && !_force &&
		    [fileManager fileExistsAtPath: fileName]) {
			[of_stderr writeString:
			    OF_LOCALIZED(@"ouput_already_exists",
			    @"%[prog]: File %[filename] already exists!\n",
			    @"prog", [OFApplication programName],
			    @"filename", fileName)];

			_errorCode = 1;
			goto next;
		}

		@try {
			OFString *mode =
			    ([response statusCode] == 206 ? @"ab" : @"wb");
			_output = [[OFFile alloc] initWithPath: fileName
							  mode: mode];
		} @catch (OFOpenItemFailedException *e) {
			[of_stderr writeString:
			    OF_LOCALIZED(@"failed_to_open_output",
			    @"%[prog]: Failed to open file %[filename]: "
			    @"%[exception]\n",
			    @"prog", [OFApplication programName],
			    @"filename",fileName,
			    @"exception", e)];

			_errorCode = 1;
			goto next;
		}







|
>
>
|









|
>
|

|
>
|

|
>
|









|
|
|













|


|







814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
			OFDictionary OF_GENERIC(OFString*, OFString*) *headers =
			    [response headers];
			OFEnumerator *keyEnumerator = [headers keyEnumerator];
			OFEnumerator *objectEnumerator =
			    [headers objectEnumerator];
			OFString *key, *object;

			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"info_name_unaligned",
			    @"Name: %[name]",
			    @"name", fileName)];

			while ((key = [keyEnumerator nextObject]) != nil &&
			    (object = [objectEnumerator nextObject]) != nil)
				[of_stdout writeFormat: @"  %@: %@\n",
							key, object];

			objc_autoreleasePoolPop(pool);
		} else {
			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(@"info_name",
			    @"Name: %[name]",
			    @"name", fileName)];
			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(@"info_type",
			    @"Type: %[type]",
			    @"type", type)];
			[of_stdout writeString: @"  "];
			[of_stdout writeLine: OF_LOCALIZED(@"info_size",
			    @"Size: %[size]",
			    @"size", lengthString)];
		}
	}

	if ([_outputPath isEqual: @"-"])
		_output = of_stdout;
	else {
		if (!_continue && !_force &&
		    [fileManager fileExistsAtPath: fileName]) {
			[of_stderr writeLine:
			    OF_LOCALIZED(@"output_already_exists",
			    @"%[prog]: File %[filename] already exists!",
			    @"prog", [OFApplication programName],
			    @"filename", fileName)];

			_errorCode = 1;
			goto next;
		}

		@try {
			OFString *mode =
			    ([response statusCode] == 206 ? @"ab" : @"wb");
			_output = [[OFFile alloc] initWithPath: fileName
							  mode: mode];
		} @catch (OFOpenItemFailedException *e) {
			[of_stderr writeLine:
			    OF_LOCALIZED(@"failed_to_open_output",
			    @"%[prog]: Failed to open file %[filename]: "
			    @"%[exception]",
			    @"prog", [OFApplication programName],
			    @"filename",fileName,
			    @"exception", e)];

			_errorCode = 1;
			goto next;
		}

Modified utils/ofhttp/ProgressBar.m from [f001d1016e] to [509373b942].

175
176
177
178
179
180
181


182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206


207
208
209
210
211
212
213
		    @"%[num] B/s  ",
		    @"num", num)];
	}
}

- (void)_drawReceived
{


	if (_resumedFrom + _received >= GIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / GIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_gib",
		    @"\r  %[num] GiB ",
		    @"num", num)];
	} else if (_resumedFrom + _received >= MEBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / MEBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_mib",
		    @"\r  %[num] MiB ",
		    @"num", num)];
	} else if (_resumedFrom + _received >= KIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / KIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_kib",
		    @"\r  %[num] KiB ",
		    @"num", num)];
	} else {
		OFString *num = [OFString stringWithFormat:
		    @"%jd", _resumedFrom + _received];
		[of_stdout writeString: OF_LOCALIZED(@"progress_bytes",
		    @"\r  %[num] bytes ",
		    @"num", num)];
	}



	if (_stopped)
		_BPS = (float)_received /
		    -(float)[_startDate timeIntervalSinceNow];

	if (_BPS >= GIBIBYTE) {
		OFString *num = [OFString stringWithFormat:







>
>




|





|





|





|


>
>







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
		    @"%[num] B/s  ",
		    @"num", num)];
	}
}

- (void)_drawReceived
{
	[of_stdout writeString: @"\r  "];

	if (_resumedFrom + _received >= GIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / GIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_gib",
		    @"%[num] GiB",
		    @"num", num)];
	} else if (_resumedFrom + _received >= MEBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / MEBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_mib",
		    @"%[num] MiB",
		    @"num", num)];
	} else if (_resumedFrom + _received >= KIBIBYTE) {
		OFString *num = [OFString stringWithFormat:
		    @"%,7.2f", (float)(_resumedFrom + _received) / KIBIBYTE];
		[of_stdout writeString: OF_LOCALIZED(@"progress_kib",
		    @"%[num] KiB",
		    @"num", num)];
	} else {
		OFString *num = [OFString stringWithFormat:
		    @"%jd", _resumedFrom + _received];
		[of_stdout writeString: OF_LOCALIZED(@"progress_bytes",
		    @"%[num] bytes",
		    @"num", num)];
	}

	[of_stdout writeString: @" "];

	if (_stopped)
		_BPS = (float)_received /
		    -(float)[_startDate timeIntervalSinceNow];

	if (_BPS >= GIBIBYTE) {
		OFString *num = [OFString stringWithFormat:

Modified utils/ofhttp/lang/de.json from [767e814d4b] to [4101cbff1a].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
{
    "usage": "Benutzung: %[prog] -[cehHmoOPqv] url1 [url2 ...]\n",
    "full_usage": [
        "\n",
        "Optionen:\n",
        "    -b  --body             Angegebene Datei als Body übergeben\n",
        "    -c  --continue         Download von existierender Datei ",
        "fortsetzen\n",
        "    -f  --force            Existierende Datei überschreiben\n",
        "    -h  --help             Diese Hilfe anzeigen\n",
        "    -H  --header           Einen Header (z.B. X-Foo:Bar) hinzufügen\n",
        "    -m  --method           HTTP Request-Methode setzen\n",
        "    -o  --output           Ausgabe-Dateiname angeben\n",
        "    -O  --detect-filename  Dateiname mittels HEAD-Request ermitteln\n",
        "    -P  --proxy            SOCKS5-Proxy angeben\n",
        "    -q  --quiet            Ruhiger Modus (keine Ausgabe außer Fehler)",
        "\n",
        "    -v  --verbose          Geschwätziger Modus (gibt Header aus)\n",
        "        --insecure         TLS-Fehler ignorieren\n"
    ],
    "invalid_input_header": [
        "%[prog]: Header müssen im Format Name:Wert sein!\n"
    ],
    "invalid_input_method": "%[prog]: Ungültige Request-Methode %[method]!\n",
    "invalid_input_proxy": "%[prog]: Proxy muss im Format Host:Port sein!\n",
    "long_argument_missing": "%[prog]: Argument für Option --%[opt] fehlt\n",
    "argument_missing": "%[prog]: Argument für option -%[opt] fehlt\n",
    "takes_no_argument": "%[prog]: Option --%[opt] nimmt kein Argument\n",
    "unknown_long_option": "%[prog]: Unbekannte Option: --%[opt]\n",
    "unknown_option": "%[prog]: Unbekannte Option: -%[opt]\n",
    "quiet_xor_verbose": [
        "%[prog]: -q / --quiet und -v / --verbose schließen sich gegenseitig ",
        "aus!\n"
    ],
    "output_only_with_one_url": [
        "%[prog]: -o / --output kann nicht mit mehr als einer URL benutzt ",
        "werden!\n"
    ],
    "download_failed_address_translation": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  Adressauflösung fehlgeschlagen: %[exception]\n"
    ],
    "download_failed_connection_failed": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  Verbindung fehlgeschlagen: %[exception]\n"
    ],
    "download_failed_invalid_server_reply": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  Ungültige Antwort vom Server!\n"
    ],
    "no_ssl_library": [
        "%[prog]: Keine TLS-Bibliothek geladen!\n",
        "  Um Dateien über https zu laden, müssen Sie eine TLS-Bibliothek für ",
        "ObjFW,\n",
        "  wie z.B. ObjOpenSSL, mittels LD_PRELOAD laden."
    ],
    "download_failed_read_or_write_failed_any": "Lesen oder Schreiben",
    "download_failed_read_or_write_failed_read": "Lesen",
    "download_failed_read_or_write_failed_write": "Schreiben",
    "download_failed_read_or_write_failed": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  %[error]: %[exception]\n"
    ],
    "download_failed": "%[prog]: Fehler beim Download von <%[url]>!\n",
    "download_failed_exception": [
        "%[prog]: Fehler beim Download von <%[url]>: %[exception]\n"
    ],
    "download_done": "\n  Fertig!\n",
    "invalid_url": "%[prog]: Ungültige URL: <%[url]>!\n",
    "invalid_scheme": "%[prog]: Ungültiges Schema: <%[scheme]:>!\n",
    "type_unknown": "unbekannt",
    "size_gib": "%[num] GiB",
    "size_mib": "%[num] MiB",
    "size_kib": "%[num] KiB",
    "size_bytes": "%[num] Bytes",
    "size_unknown": "unbekannt",
    "info_name_nopad": "  Name: %[name]\n",
    "info_name": "  Name:  %[name]\n",
    "info_type": "  Typ:   %[type]\n",
    "info_size": "  Größe: %[size]\n",
    "output_already_exists": "%[prog]: Datei %[filename] existiert bereits!\n",
    "failed_to_open_output": [
        "%[prog]: Kann Datei %[filename] nicht öffnen: %[exception]\n"
    ],
    "eta_days": "%[num] t ",
    "progress_bytes": "\r  %[num] Bytes"
}

|

<













|
|

<
|
<
|
|
|
|
|
|
|


|



|



|



|



|












|

|

|

|
|
|






|
|
|
|
|

|


|

1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
{
    "usage": "Benutzung: %[prog] -[cehHmoOPqv] url1 [url2 ...]",
    "full_usage": [

        "Optionen:\n",
        "    -b  --body             Angegebene Datei als Body übergeben\n",
        "    -c  --continue         Download von existierender Datei ",
        "fortsetzen\n",
        "    -f  --force            Existierende Datei überschreiben\n",
        "    -h  --help             Diese Hilfe anzeigen\n",
        "    -H  --header           Einen Header (z.B. X-Foo:Bar) hinzufügen\n",
        "    -m  --method           HTTP Request-Methode setzen\n",
        "    -o  --output           Ausgabe-Dateiname angeben\n",
        "    -O  --detect-filename  Dateiname mittels HEAD-Request ermitteln\n",
        "    -P  --proxy            SOCKS5-Proxy angeben\n",
        "    -q  --quiet            Ruhiger Modus (keine Ausgabe außer Fehler)",
        "\n",
        "    -v  --verbose          Ausführlicher Modus (gibt Header aus)\n",
        "        --insecure         TLS-Fehler ignorieren"
    ],

    "invalid_input_header": "%[prog]: Header müssen im Format Name:Wert sein!",

    "invalid_input_method": "%[prog]: Ungültige Request-Methode %[method]!",
    "invalid_input_proxy": "%[prog]: Proxy muss im Format Host:Port sein!",
    "long_argument_missing": "%[prog]: Argument für Option --%[opt] fehlt",
    "argument_missing": "%[prog]: Argument für option -%[opt] fehlt",
    "option_takes_no_argument": "%[prog]: Option --%[opt] nimmt kein Argument",
    "unknown_long_option": "%[prog]: Unbekannte Option: --%[opt]",
    "unknown_option": "%[prog]: Unbekannte Option: -%[opt]",
    "quiet_xor_verbose": [
        "%[prog]: -q / --quiet und -v / --verbose schließen sich gegenseitig ",
        "aus!"
    ],
    "output_only_with_one_url": [
        "%[prog]: -o / --output kann nicht mit mehr als einer URL benutzt ",
        "werden!"
    ],
    "download_failed_address_translation": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  Adressauflösung fehlgeschlagen: %[exception]"
    ],
    "download_failed_connection_failed": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  Verbindung fehlgeschlagen: %[exception]"
    ],
    "download_failed_invalid_server_reply": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  Ungültige Antwort vom Server!"
    ],
    "no_ssl_library": [
        "%[prog]: Keine TLS-Bibliothek geladen!\n",
        "  Um Dateien über https zu laden, müssen Sie eine TLS-Bibliothek für ",
        "ObjFW,\n",
        "  wie z.B. ObjOpenSSL, mittels LD_PRELOAD laden."
    ],
    "download_failed_read_or_write_failed_any": "Lesen oder Schreiben",
    "download_failed_read_or_write_failed_read": "Lesen",
    "download_failed_read_or_write_failed_write": "Schreiben",
    "download_failed_read_or_write_failed": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  %[error]: %[exception]"
    ],
    "download_failed": "%[prog]: Fehler beim Download von <%[url]>!",
    "download_failed_exception": [
        "%[prog]: Fehler beim Download von <%[url]>: %[exception]"
    ],
    "download_done": "Fertig!",
    "invalid_url": "%[prog]: Ungültige URL: <%[url]>!",
    "invalid_scheme": "%[prog]: Ungültiges Schema: <%[scheme]:>!",
    "type_unknown": "unbekannt",
    "size_gib": "%[num] GiB",
    "size_mib": "%[num] MiB",
    "size_kib": "%[num] KiB",
    "size_bytes": "%[num] Bytes",
    "size_unknown": "unbekannt",
    "info_name_unaligned": "Name: %[name]",
    "info_name": "Name:  %[name]",
    "info_type": "Typ:   %[type]",
    "info_size": "Größe: %[size]",
    "output_already_exists": "%[prog]: Datei %[filename] existiert bereits!",
    "failed_to_open_output": [
        "%[prog]: Kann Datei %[filename] nicht öffnen: %[exception]"
    ],
    "eta_days": "%[num] t ",
    "progress_bytes": "%[num] Bytes"
}

Modified utils/ofzip/lang/de.json from [2dd0fdfbcd] to [0196b6a721].

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    "unknown_long_option": "%[prog]: Unbekannte Option: --%[opt]",
    "unknown_option": "%[prog]: Unbekannte Option: -%[opt]",
    "failed_to_create_directory": [
        "Fehler beim Erstellen des Verzeichnis %[dir]: %[error]"
    ],
    "failed_to_open_file": "Fehler beim Öffnen der Datei %[file]: %[error]",
    "unknown_archive_type": "Unbekannter Archivtyp: %[type]",
    "failed_to_read_file": "Fehler beim Lesen von Datei %[file]: %[error]",
    "failed_to_write_file": "Fehler beim Schreiben Datei %[file]: %[error]",
    "failed_to_seek_in_file": "Fehler beim Suchen in Datei %[file]: %[error]",
    "file_is_not_a_valid_archiv": "Datei %[file] ist kein gültiges Archiv!",
    "file_skipped": "übersprungen",
    "ask_overwrite": "%[file] überschreiben? [ynAN?]",
    "ask_overwrite_help": [
        " y: Ja\n",
        " n: Nein\n",







|
|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    "unknown_long_option": "%[prog]: Unbekannte Option: --%[opt]",
    "unknown_option": "%[prog]: Unbekannte Option: -%[opt]",
    "failed_to_create_directory": [
        "Fehler beim Erstellen des Verzeichnis %[dir]: %[error]"
    ],
    "failed_to_open_file": "Fehler beim Öffnen der Datei %[file]: %[error]",
    "unknown_archive_type": "Unbekannter Archivtyp: %[type]",
    "failed_to_read_file": "Fehler beim Lesen der Datei %[file]: %[error]",
    "failed_to_write_file": "Fehler beim Schreiben der Datei %[file]: %[error]",
    "failed_to_seek_in_file": "Fehler beim Suchen in Datei %[file]: %[error]",
    "file_is_not_a_valid_archiv": "Datei %[file] ist kein gültiges Archiv!",
    "file_skipped": "übersprungen",
    "ask_overwrite": "%[file] überschreiben? [ynAN?]",
    "ask_overwrite_help": [
        " y: Ja\n",
        " n: Nein\n",