rims 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f51adf08f317981cdec3bb1067edd7a6c4befcf2f3e3e9c3ab4ac97702dad80
4
- data.tar.gz: d0089e4150ad0768b0267c3c34980fad6a5251f0953997bd75a8c00e590120bb
3
+ metadata.gz: 8f01bbf0c8b6eb4045ff043dcdd0b45f4a4d1fed52e56faba3d9de19862945a0
4
+ data.tar.gz: ef55b1ce253f09885b12d31462ddf403953d8c7f71cc10804519683320b783dd
5
5
  SHA512:
6
- metadata.gz: 4be9394ccaa4e2081dcc4040f197f375444b04953706c050aad5b1e255121cfec2d49753f31160f0dc458dcac139296b37c5efe0685f749904e5a0d74c705b24
7
- data.tar.gz: a1a1a3f16b3069b2fd0e2ee9016349fbb2bb43401220ed9d00beec44914b4ef0206582c41a2bfb94c895d91ea6eb62ba76dcdd342338aa5becb8670777a3343a
6
+ metadata.gz: 4b4895651585be46229c11f5224fa00b70fbbd255a6ebea958a49cc042b5d3998c07b3bf2dd9ede7901c9198ab7cb7cbfb493eb0c278eb47599475ef4af4ceb1
7
+ data.tar.gz: 32d599e976f82f303cb7d7fffcc8d0fd511729523852e20daac9dbc52744c80962955164146fa2f8bdc9cc39ff3c2510742abb2d91ffd572f97fbdfed00126e8
data/.gitignore CHANGED
@@ -14,6 +14,7 @@
14
14
  /tmp/
15
15
  /vendor/
16
16
  /Gemfile.lock
17
+ /Gemfile_local*
17
18
  /README.html
18
19
  *~
19
20
  *.log
data/ChangeLog CHANGED
@@ -1,3 +1,34 @@
1
+ 2019-07-25 TOKI Yoshinori <toki@freedom.ne.jp>
2
+
3
+ * lib/rims/cmd.rb, lib/rims/protocol/decoder.rb,
4
+ lib/rims/protocol/parser.rb, lib/rims/service.rb: message charset
5
+ encoding conversion options.
6
+
7
+ 2019-07-22 TOKI Yoshinori <toki@freedom.ne.jp>
8
+
9
+ * lib/rims/cmd.rb, lib/rims/protocol/decoder.rb,
10
+ lib/rims/protocol/parser.rb, lib/rims/service.rb: charset aliases
11
+ option.
12
+
13
+ 2019-07-20 TOKI Yoshinori <toki@freedom.ne.jp>
14
+
15
+ * lib/rims/protocol/decoder.rb, lib/rims/protocol/parser.rb:
16
+ case-insensitive matching of SEARCH command.
17
+
18
+ See RFC3501 / 6.4.4. SEARCH Command
19
+ <https://tools.ietf.org/html/rfc3501#section-6.4.4>
20
+
21
+ In all search keys that use strings, a message matches the key if
22
+ the string is a substring of the field. The matching is
23
+ case-insensitive.
24
+
25
+ * lib/rims/protocol/parser.rb: search for MIME encoded header
26
+ fields.
27
+
28
+ 2019-07-09 TOKI Yoshinori <toki@freedom.ne.jp>
29
+
30
+ * RIMS version 0.2.6 is released.
31
+
1
32
  2019-07-08 TOKI Yoshinori <toki@freedom.ne.jp>
2
33
 
3
34
  * lib/rims/cmd.rb: disable plug-in name list on plug-in command
data/lib/rims/cmd.rb CHANGED
@@ -462,6 +462,58 @@ module RIMS
462
462
  })
463
463
  }
464
464
  end
465
+ options.on('--[no-]use-default-charset-aliases'
466
+ ) do |use_default_aliases|
467
+ build.chain{|c|
468
+ c.load(charset: {
469
+ use_default_aliases: use_default_aliases
470
+ })
471
+ }
472
+ end
473
+ options.on('--add-charset-alias=NAME_TO_ENCODING',
474
+ /\A \S+,\S+ \z/x,
475
+ "Set the alias name and encoding separated with comma (,)."
476
+ ) do |name_to_encoding|
477
+ name, encoding = name_to_encoding.split(',', 2)
478
+ build.chain{|c|
479
+ c.load(charset: {
480
+ aliases: [
481
+ { name: name, encoding: encoding }
482
+ ]
483
+ })
484
+ }
485
+ end
486
+ options.on('--[no-]replace-charset-invalid'
487
+ ) do |replace|
488
+ build.chain{|c|
489
+ c.load(charset: {
490
+ convert_options: {
491
+ replace_invalid_byte_sequence: replace
492
+ }
493
+ })
494
+ }
495
+ end
496
+ options.on('--[no-]replace-charset-undef'
497
+ ) do |replace|
498
+ build.chain{|c|
499
+ c.load(charset: {
500
+ convert_options: {
501
+ replace_undefined_character: replace
502
+ }
503
+ })
504
+ }
505
+ end
506
+ options.on('--charset-replaced-mark=MARK',
507
+ String
508
+ ) do |mark|
509
+ build.chain{|c|
510
+ c.load(charset: {
511
+ convert_options: {
512
+ replaced_mark: mark
513
+ }
514
+ })
515
+ }
516
+ end
465
517
  options.on('--drb-process-num=NUMBER',
466
518
  Integer
467
519
  ) do |num|
@@ -515,7 +567,6 @@ module RIMS
515
567
  }
516
568
  end
517
569
  options.on('--meta-kvs-type=TYPE',
518
- KeyValueStore::FactoryBuilder.plug_in_names,
519
570
  "Choose key-value store type of mailbox meta-data database. default is `" +
520
571
  KeyValueStore::FactoryBuilder.plug_in_names[0] +
521
572
  "'."
@@ -558,7 +609,6 @@ module RIMS
558
609
  }
559
610
  end
560
611
  options.on('--text-kvs-type=TYPE',
561
- KeyValueStore::FactoryBuilder.plug_in_names,
562
612
  "Choose key-value store type of mailbox text-data database. default is `" +
563
613
  KeyValueStore::FactoryBuilder.plug_in_names[0] +
564
614
  "'."
@@ -684,7 +734,6 @@ module RIMS
684
734
  build.chain{|c| c.load(ip_port: port) }
685
735
  end
686
736
  options.on('--kvs-type=TYPE',
687
- KeyValueStore::FactoryBuilder.plug_in_names,
688
737
  'Deplicated.'
689
738
  ) do |kvs_type|
690
739
  warn("warning: `--kvs-type=TYPE' is deplicated option and should use `--meta-kvs-type=TYPE' or `--text-kvs-type=TYPE'.")
@@ -668,7 +668,9 @@ module RIMS
668
668
  bulk_response_count: 100,
669
669
  read_lock_timeout_seconds: ReadWriteLock::DEFAULT_TIMEOUT_SECONDS,
670
670
  write_lock_timeout_seconds: ReadWriteLock::DEFAULT_TIMEOUT_SECONDS,
671
- cleanup_write_lock_timeout_seconds: 1)
671
+ cleanup_write_lock_timeout_seconds: 1,
672
+ charset_aliases: RFC822::DEFAULT_CHARSET_ALIASES,
673
+ charset_convert_options: nil)
672
674
  @unique_user_id = unique_user_id
673
675
  @mail_store = mail_store
674
676
  @logger = logger
@@ -676,6 +678,8 @@ module RIMS
676
678
  @read_lock_timeout_seconds = read_lock_timeout_seconds
677
679
  @write_lock_timeout_seconds = write_lock_timeout_seconds
678
680
  @cleanup_write_lock_timeout_seconds = cleanup_write_lock_timeout_seconds
681
+ @charset_aliases = charset_aliases
682
+ @charset_convert_options = charset_convert_options
679
683
  @folders = {}
680
684
  end
681
685
 
@@ -1240,7 +1244,9 @@ module RIMS
1240
1244
  folder = @folders[token] or raise KeyError.new("undefined folder token: #{token}", key: token, receiver: self)
1241
1245
  folder.should_be_alive
1242
1246
  folder.reload if folder.updated?
1243
- parser = SearchParser.new(@mail_store, folder)
1247
+ parser = SearchParser.new(@mail_store, folder,
1248
+ charset_aliases: @charset_aliases,
1249
+ charset_convert_options: @charset_convert_options)
1244
1250
 
1245
1251
  if (! cond_args.empty? && cond_args[0].upcase == 'CHARSET') then
1246
1252
  cond_args.shift
@@ -1250,7 +1256,7 @@ module RIMS
1250
1256
  parser.charset = charset_string
1251
1257
  rescue ArgumentError
1252
1258
  @logger.warn("unknown charset: #{charset_string}")
1253
- return yield([ "#{tag} NO [BADCHARSET (#{Encoding.list.map(&:to_s).join(' ')})] unknown charset\r\n" ])
1259
+ return yield([ "#{tag} NO [BADCHARSET (#{Encoding.list.reject(&:dummy?).map(&:to_s).join(' ')})] unknown charset\r\n" ])
1254
1260
  end
1255
1261
  end
1256
1262
 
@@ -1261,18 +1267,18 @@ module RIMS
1261
1267
  if (cond_args[0].upcase == 'UID' && cond_args.length >= 2) then
1262
1268
  begin
1263
1269
  msg_set = folder.parse_msg_set(cond_args[1], uid: true)
1264
- msg_src = folder.msg_find_all(msg_set, uid: true)
1270
+ msg_list = folder.msg_find_all(msg_set, uid: true)
1265
1271
  cond_args.shift(2)
1266
1272
  rescue MessageSetSyntaxError
1267
- msg_src = folder.each_msg
1273
+ msg_list = folder.each_msg
1268
1274
  end
1269
1275
  else
1270
1276
  begin
1271
1277
  msg_set = folder.parse_msg_set(cond_args[0], uid: false)
1272
- msg_src = folder.msg_find_all(msg_set, uid: false)
1278
+ msg_list = folder.msg_find_all(msg_set, uid: false)
1273
1279
  cond_args.shift
1274
1280
  rescue MessageSetSyntaxError
1275
- msg_src = folder.each_msg
1281
+ msg_list = folder.each_msg
1276
1282
  end
1277
1283
  end
1278
1284
  cond = parser.parse(cond_args)
@@ -1289,7 +1295,7 @@ module RIMS
1289
1295
  res << '* SEARCH'
1290
1296
  begin
1291
1297
  begin
1292
- for msg in msg_src
1298
+ for msg in msg_list
1293
1299
  begin
1294
1300
  if (cond.call(msg)) then
1295
1301
  if (uid) then
@@ -1339,7 +1345,7 @@ module RIMS
1339
1345
  end
1340
1346
  end
1341
1347
 
1342
- parser = FetchParser.new(@mail_store, folder)
1348
+ parser = FetchParser.new(@mail_store, folder, charset_aliases: @charset_aliases)
1343
1349
  fetch = parser.parse(data_item_group)
1344
1350
 
1345
1351
  res = []
@@ -228,13 +228,15 @@ module RIMS
228
228
  end
229
229
 
230
230
  class SearchParser
231
- def initialize(mail_store, folder)
231
+ def initialize(mail_store, folder, charset_aliases: RFC822::DEFAULT_CHARSET_ALIASES, charset_convert_options: nil)
232
232
  @mail_store = mail_store
233
233
  @folder = folder
234
+ @charset_aliases = charset_aliases
235
+ @charset_convert_options = charset_convert_options
234
236
  @charset = nil
235
237
  @mail_cache = Hash.new{|hash, uid|
236
238
  if (msg_txt = @mail_store.msg_text(@folder.mbox_id, uid)) then
237
- hash[uid] = RFC822::Message.new(msg_txt)
239
+ hash[uid] = RFC822::Message.new(msg_txt, charset_aliases: @charset_aliases)
238
240
  end
239
241
  }
240
242
  end
@@ -247,47 +249,35 @@ module RIMS
247
249
  attr_reader :charset
248
250
 
249
251
  def charset=(new_charset)
250
- @charset = Encoding.find(new_charset)
252
+ charset_encoding = @charset_aliases[new_charset] || Encoding.find(new_charset)
253
+ if (charset_encoding.dummy?) then
254
+ # same error type as `Encoding.find'
255
+ raise ArgumentError, "not a searchable charset: #{new_charset}"
256
+ end
257
+ @charset = charset_encoding
251
258
  end
252
259
 
253
- def force_string_charset(string)
260
+ def force_charset(string)
254
261
  string = string.dup
255
262
  string.force_encoding(@charset)
256
263
  string.valid_encoding? or raise SyntaxError, "invalid #{@charset} string: #{string.inspect}"
257
264
  string
258
265
  end
259
- private :force_string_charset
266
+ private :force_charset
260
267
 
261
- # should set `search_string' encoding to `@charset'
262
- def string_include?(search_string, text)
263
- if (search_string.ascii_only?) then
264
- unless (text.encoding.ascii_compatible?) then
265
- text = text.encode('utf-8')
266
- end
268
+ def encode_charset(string)
269
+ if (string.encoding == @charset) then
270
+ string
267
271
  else
268
- if (@charset) then
269
- text = text.encode(@charset)
270
- end
272
+ string.encode(@charset, @charset_convert_options)
271
273
  end
272
-
273
- text.include? search_string
274
274
  end
275
- private :string_include?
276
-
277
- def mail_body_text(mail)
278
- if (mail.text? || mail.message?) then
279
- body_txt = mail.body.raw_source
280
- if (charset = mail.charset) then
281
- if (body_txt.encoding != charset) then
282
- body_txt = body_txt.dup.force_encoding(charset)
283
- end
284
- end
285
- body_txt
286
- else
287
- nil
288
- end
275
+ private :encode_charset
276
+
277
+ def compile_search_regexp(search_string)
278
+ Regexp.new(Regexp.quote(search_string), true)
289
279
  end
290
- private :mail_body_text
280
+ private :compile_search_regexp
291
281
 
292
282
  def end_of_cond
293
283
  proc{|msg| true }
@@ -322,14 +312,29 @@ module RIMS
322
312
  private :parse_msg_flag_enabled
323
313
 
324
314
  def parse_search_header(field_name, search_string)
325
- search_string = force_string_charset(search_string) if @charset
315
+ if (@charset) then
316
+ search_string = force_charset(search_string)
317
+ search_regexp = compile_search_regexp(search_string)
318
+ search_header = proc{|mail|
319
+ mail.mime_decoded_header_field_value_list(field_name, @charset, charset_convert_options: @charset_convert_options).any?{|field_value|
320
+ search_regexp.match? field_value
321
+ }
322
+ }
323
+ else
324
+ search_string = search_string.b
325
+ search_regexp = compile_search_regexp(search_string)
326
+ search_header = proc{|mail|
327
+ mail.header.field_value_list(field_name).any?{|field_value|
328
+ search_regexp.match? field_value
329
+ }
330
+ }
331
+ end
332
+
326
333
  proc{|next_cond|
327
334
  proc{|msg|
328
335
  mail = get_mail(msg)
329
336
  if (mail.header.key? field_name) then
330
- mail.header.field_value_list(field_name).any?{|field_value|
331
- string_include?(search_string, field_value)
332
- } && next_cond.call(msg)
337
+ search_header.call(mail) && next_cond.call(msg)
333
338
  else
334
339
  false
335
340
  end
@@ -372,11 +377,40 @@ module RIMS
372
377
  private :parse_mail_bytesize
373
378
 
374
379
  def parse_body(search_string)
375
- search_string = force_string_charset(search_string) if @charset
380
+ if (@charset)
381
+ search_string = force_charset(search_string)
382
+ search_regexp = compile_search_regexp(search_string)
383
+ search_body = proc{|mail|
384
+ if (mail.text? || mail.messge?) then
385
+ search_regexp.match? encode_charset(mail.mime_charset_body_text)
386
+ elsif (mail.multipart?) then
387
+ mail.parts.any?{|next_mail|
388
+ search_body.call(next_mail)
389
+ }
390
+ else
391
+ false
392
+ end
393
+ }
394
+ else
395
+ search_string = search_string.b
396
+ search_regexp = compile_search_regexp(search_string)
397
+ search_body = proc{|mail|
398
+ if (mail.text? || mail.message?)then
399
+ search_regexp.match? mail.mime_binary_body_string
400
+ elsif (mail.multipart?) then
401
+ mail.parts.any?{|next_mail|
402
+ search_body.call(next_mail)
403
+ }
404
+ else
405
+ false
406
+ end
407
+ }
408
+ end
409
+
376
410
  proc{|next_cond|
377
411
  proc{|msg|
378
- if (text = mail_body_text(get_mail(msg))) then
379
- string_include?(search_string, text) && next_cond.call(msg)
412
+ if (mail = get_mail(msg)) then
413
+ search_body.call(mail) && next_cond.call(msg)
380
414
  else
381
415
  false
382
416
  end
@@ -435,20 +469,44 @@ module RIMS
435
469
  private :parse_or
436
470
 
437
471
  def parse_text(search_string)
438
- search_string = force_string_charset(search_string) if @charset
439
- search_text = proc{|message_text| string_include?(search_string, message_text) }
440
- search_mail = proc{|mail|
441
- if (mail.multipart?) then
442
- search_text.call(mail.header.raw_source) || mail.parts.any?{|m| search_mail.call(m) }
443
- else
444
- body_text = mail_body_text(mail)
445
- search_text.call(mail.header.raw_source) || (body_text && search_text.call(body_text))
446
- end
447
- }
472
+ if (@charset) then
473
+ search_string = force_charset(search_string)
474
+ search_regexp = compile_search_regexp(search_string)
475
+ search_text = proc{|mail|
476
+ if (search_regexp.match? mail.mime_decoded_header_text(@charset, charset_convert_options: @charset_convert_options)) then
477
+ true
478
+ elsif (mail.text? || mail.message?) then
479
+ search_regexp.match? encode_charset(mail.mime_charset_body_text)
480
+ elsif (mail.multipart?) then
481
+ mail.parts.any?{|next_mail|
482
+ search_text.call(next_mail)
483
+ }
484
+ else
485
+ false
486
+ end
487
+ }
488
+ else
489
+ search_string = search_string.b
490
+ search_regexp = compile_search_regexp(search_string)
491
+ search_text = proc{|mail|
492
+ if (search_regexp.match? mail.header.raw_source) then
493
+ true
494
+ elsif (mail.text? || mail.message?) then
495
+ search_regexp.match? mail.mime_binary_body_string
496
+ elsif (mail.multipart?) then
497
+ mail.parts.any?{|next_mail|
498
+ search_text.call(next_mail)
499
+ }
500
+ else
501
+ false
502
+ end
503
+ }
504
+ end
505
+
448
506
  proc{|next_cond|
449
507
  proc{|msg|
450
508
  mail = get_mail(msg)
451
- search_mail.call(mail) && next_cond.call(msg)
509
+ search_text.call(mail) && next_cond.call(msg)
452
510
  }
453
511
  }
454
512
  end
@@ -768,12 +826,12 @@ module RIMS
768
826
  end
769
827
  include Utils
770
828
 
771
- def initialize(mail_store, folder)
829
+ def initialize(mail_store, folder, charset_aliases: RFC822::DEFAULT_CHARSET_ALIASES)
772
830
  @mail_store = mail_store
773
831
  @folder = folder
774
832
  @mail_cache = Hash.new{|hash, uid|
775
833
  if (msg_txt = @mail_store.msg_text(@folder.mbox_id, uid)) then
776
- hash[uid] = RFC822::Message.new(msg_txt)
834
+ hash[uid] = RFC822::Message.new(msg_txt, charset_aliases: charset_aliases)
777
835
  end
778
836
  }
779
837
  end
data/lib/rims/service.rb CHANGED
@@ -157,6 +157,19 @@ module RIMS
157
157
  # send_buffer_limit_size: 16384
158
158
  # read_polling_interval_seconds: 1
159
159
  # command_wait_timeout_seconds: 1800
160
+ # charset:
161
+ # use_default_aliases: true
162
+ # aliases:
163
+ # - name: euc-jp
164
+ # encoding: eucJP-ms
165
+ # - name: ios-2022-jp
166
+ # encoding: CP50221
167
+ # - name: Shift_JIS
168
+ # encoding: Windows-31J
169
+ # convert_options:
170
+ # replace_invalid_byte_sequence: false
171
+ # replace_undefined_character: true
172
+ # replaced_mark: "\uFFFD"
160
173
  # drb_services:
161
174
  # process_num: 4
162
175
  # engine:
@@ -385,9 +398,8 @@ module RIMS
385
398
  end
386
399
 
387
400
  def daemonize?
388
- daemon_config = @config['daemon'] || {}
389
- if (daemon_config.key? 'daemonize') then
390
- daemon_config['daemonize']
401
+ if (@config.dig('daemon')&.key? 'daemonize') then
402
+ @config.dig('daemon', 'daemonize')
391
403
  else
392
404
  true
393
405
  end
@@ -398,9 +410,8 @@ module RIMS
398
410
  end
399
411
 
400
412
  def daemon_debug?
401
- daemon_config = @config['daemon'] || {}
402
- if (daemon_config.key? 'debug') then
403
- daemon_config['debug']
413
+ if (@config.dig('daemon')&.key? 'debug') then
414
+ @config.dig('daemon', 'debug')
404
415
  else
405
416
  false
406
417
  end
@@ -521,22 +532,20 @@ module RIMS
521
532
  end
522
533
 
523
534
  def ssl_context
524
- if (openssl_config = @config['openssl']) then
525
- if (openssl_config.key? 'use_ssl') then
526
- use_ssl = openssl_config['use_ssl']
527
- else
528
- use_ssl = openssl_config.key? 'ssl_context'
529
- end
530
-
531
- if (use_ssl) then
532
- ssl_context = OpenSSL::SSL::SSLContext.new
533
- if (ssl_config_expr = openssl_config['ssl_context']) then
534
- anon_mod = SSLContextConfigAttribute.new_module(ssl_context, base_dir)
535
- SSLContextConfigAttribute.eval_config(anon_mod, ssl_config_expr, 'ssl_context')
536
- end
535
+ if (@config.dig('openssl')&.key? 'use_ssl') then
536
+ use_ssl = @config.dig('openssl', 'use_ssl')
537
+ else
538
+ use_ssl = (@config.dig('openssl')&.key? 'ssl_context') || false
539
+ end
537
540
 
538
- ssl_context
541
+ if (use_ssl) then
542
+ ssl_context = OpenSSL::SSL::SSLContext.new
543
+ if (ssl_config_expr = @config.dig('openssl', 'ssl_context')) then
544
+ anon_mod = SSLContextConfigAttribute.new_module(ssl_context, base_dir)
545
+ SSLContextConfigAttribute.eval_config(anon_mod, ssl_config_expr, 'ssl_context')
539
546
  end
547
+
548
+ ssl_context
540
549
  end
541
550
  end
542
551
 
@@ -551,6 +560,60 @@ module RIMS
551
560
  @config.dig('connection', 'command_wait_timeout_seconds') || 60 * 30)
552
561
  end
553
562
 
563
+ def charset_aliases
564
+ charset_aliases = RFC822::CharsetAliases.new
565
+
566
+ if (@config.dig('charset')&.key? 'use_default_aliases') then
567
+ use_default_aliases = @config.dig('charset', 'use_default_aliases')
568
+ else
569
+ use_default_aliases = true
570
+ end
571
+
572
+ if (use_default_aliases) then
573
+ for name, encoding in RFC822::DEFAULT_CHARSET_ALIASES
574
+ charset_aliases.add_alias(name, encoding)
575
+ end
576
+ end
577
+
578
+ if (alias_list = @config.dig('charset', 'aliases')) then
579
+ for an_alias in alias_list
580
+ charset_aliases.add_alias(an_alias['name'], Encoding.find(an_alias['encoding']))
581
+ end
582
+ end
583
+
584
+ charset_aliases
585
+ end
586
+
587
+ def charset_convert_options
588
+ options = {}
589
+
590
+ if (@config.dig('charset', 'convert_options')&.key? 'replace_invalid_byte_sequence') then
591
+ replace_invalid_byte_sequence = @config.dig('charset', 'convert_options', 'replace_invalid_byte_sequence')
592
+ else
593
+ replace_invalid_byte_sequence = false
594
+ end
595
+
596
+ if (replace_invalid_byte_sequence) then
597
+ options[:invalid] = :replace
598
+ end
599
+
600
+ if (@config.dig('charset', 'convert_options')&.key? 'replace_undefined_character') then
601
+ replace_undefined_character = @config.dig('charset', 'convert_options', 'replace_undefined_character')
602
+ else
603
+ replace_undefined_character = true
604
+ end
605
+
606
+ if (replace_undefined_character) then
607
+ options[:undef] = :replace
608
+ end
609
+
610
+ if (replaced_mark = @config.dig('charset', 'convert_options', 'replaced_mark')) then
611
+ options[:replace] = replaced_mark
612
+ end
613
+
614
+ options
615
+ end
616
+
554
617
  def drb_process_num
555
618
  @config.dig('drb_services', 'process_num') || 0
556
619
  end
@@ -639,8 +702,8 @@ module RIMS
639
702
  end
640
703
 
641
704
  def make_authentication
642
- if ((@config.key? 'authentication') && (@config['authentication'].is_a? Hash)) then
643
- auth_conf = @config['authentication']
705
+ if (@config.dig('authentication')&.is_a? Hash) then
706
+ auth_conf = @config.dig('authentication')
644
707
  else
645
708
  auth_conf = {}
646
709
  end
@@ -679,8 +742,8 @@ module RIMS
679
742
  end
680
743
 
681
744
  # for backward compatibility
682
- if ((@config.key? 'authentication') && (@config['authentication'].is_a? Array)) then
683
- plug_in_list = @config['authentication']
745
+ if (@config.dig('authentication')&.is_a? Array) then
746
+ plug_in_list = @config.dig('authentication')
684
747
  for plug_in_conf in plug_in_list
685
748
  plug_in_name = plug_in_conf['plug_in'] or raise KeyError, 'not found an authentication plug_in.'
686
749
  plug_in_config = get_configuration(plug_in_conf)
@@ -789,7 +852,9 @@ module RIMS
789
852
  bulk_response_count: @config.bulk_response_count,
790
853
  read_lock_timeout_seconds: @config.read_lock_timeout_seconds,
791
854
  write_lock_timeout_seconds: @config.write_lock_timeout_seconds,
792
- cleanup_write_lock_timeout_seconds: @config.cleanup_write_lock_timeout_seconds)
855
+ cleanup_write_lock_timeout_seconds: @config.cleanup_write_lock_timeout_seconds,
856
+ charset_aliases: @config.charset_aliases,
857
+ charset_convert_options: @config.charset_convert_options)
793
858
  }
794
859
  builder.at_destroy{|engine|
795
860
  engine.destroy
@@ -895,11 +960,17 @@ module RIMS
895
960
  logger.info("connection parameter: send_buffer_limit_size=#{@config.send_buffer_limit_size}")
896
961
  logger.info("connection parameter: read_polling_interval_seconds=#{conn_limits.read_polling_interval_seconds}")
897
962
  logger.info("connection parameter: command_wait_timeout_seconds=#{conn_limits.command_wait_timeout_seconds}")
963
+ @config.charset_aliases.each_with_index do |(name, enc), i|
964
+ logger.info("charset aliases parameter: alias[#{i}]: #{name} -> #{enc.name}")
965
+ end
966
+ for name, value in @config.charset_convert_options
967
+ logger.info("charset convert_options parameter: #{name}=#{value}")
968
+ end
898
969
  logger.info("drb_services parameter: process_num=#{drb_process_num}")
899
970
  logger.info("drb_services engine parameter: bulk_response_count=#{@config.bulk_response_count}")
900
- logger.info("lock parameter: read_lock_timeout_seconds=#{@config.read_lock_timeout_seconds}")
901
- logger.info("lock parameter: write_lock_timeout_seconds=#{@config.write_lock_timeout_seconds}")
902
- logger.info("lock parameter: cleanup_write_lock_timeout_seconds=#{@config.cleanup_write_lock_timeout_seconds}")
971
+ logger.info("drb_services engine parameter: read_lock_timeout_seconds=#{@config.read_lock_timeout_seconds}")
972
+ logger.info("drb_services engine parameter: write_lock_timeout_seconds=#{@config.write_lock_timeout_seconds}")
973
+ logger.info("drb_services engine parameter: cleanup_write_lock_timeout_seconds=#{@config.cleanup_write_lock_timeout_seconds}")
903
974
  kvs_meta_log.call
904
975
  kvs_text_log.call
905
976
  logger.info("authentication parameter: hostname=#{auth.hostname}")