rims 0.2.6 → 0.3.1

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.
@@ -33,21 +33,7 @@ module RIMS
33
33
  end
34
34
 
35
35
  class RequestReader
36
- def initialize(input, output, logger)
37
- @input = input
38
- @output = output
39
- @logger = logger
40
- end
41
-
42
- def read_line
43
- line = @input.gets or return
44
- @logger.debug("read line: #{Protocol.io_data_log(line)}") if @logger.debug?
45
- line.chomp!("\n")
46
- line.chomp!("\r")
47
- scan_line(line)
48
- end
49
-
50
- def scan_line(line)
36
+ def self.scan(line)
51
37
  atom_list = line.scan(/BODY(?:\.\S+)?\[.*?\](?:<\d+\.\d+>)?|[\[\]()]|".*?"|[^\[\]()\s]+/i).map{|s|
52
38
  case (s)
53
39
  when '(', ')', '[', ']', /\A NIL \z/ix
@@ -77,22 +63,14 @@ module RIMS
77
63
  end
78
64
  }
79
65
  if ((atom_list[-1].is_a? String) && (atom_list[-1] =~ /\A {\d+} \z/x)) then
80
- next_size = $&[1..-2].to_i
81
- @logger.debug("found literal: #{next_size} octets.") if @logger.debug?
82
- @output.write("+ continue\r\n")
83
- @output.flush
84
- @logger.debug('continue literal.') if @logger.debug?
85
- literal_string = @input.read(next_size) or raise 'unexpected client close.'
86
- @logger.debug("read literal: #{Protocol.io_data_log(literal_string)}") if @logger.debug?
87
- atom_list[-1] = literal_string
88
- next_atom_list = read_line or raise 'unexpected client close.'
89
- atom_list += next_atom_list
66
+ literal_size = $&[1..-2].to_i
67
+ atom_list[-1] = [ :literal, literal_size ]
90
68
  end
91
69
 
92
70
  atom_list
93
71
  end
94
72
 
95
- def parse(atom_list, last_atom=nil)
73
+ def self.parse(atom_list, last_atom=nil)
96
74
  syntax_list = []
97
75
  while (atom = atom_list.shift)
98
76
  case (atom)
@@ -105,7 +83,7 @@ module RIMS
105
83
  else
106
84
  if ((atom.is_a? Array) && (atom[0] == :body)) then
107
85
  body = atom[1]
108
- body.section_list = parse(scan_line(body.section))
86
+ body.section_list = parse(scan(body.section))
109
87
  end
110
88
  syntax_list.push(atom)
111
89
  end
@@ -118,18 +96,90 @@ module RIMS
118
96
  syntax_list
119
97
  end
120
98
 
99
+ def initialize(input, output, logger, line_length_limit: 1024*8, literal_size_limit: (1024**2)*10, command_size_limit: (1024**2)*10)
100
+ @input = input
101
+ @output = output
102
+ @logger = logger
103
+ @line_length_limit = line_length_limit
104
+ @literal_size_limit = literal_size_limit
105
+ @command_size_limit = command_size_limit
106
+ @command_tag = nil
107
+ @read_size = 0
108
+ end
109
+
110
+ attr_reader :command_tag
111
+
112
+ def gets
113
+ if (line = @input.gets($/, @line_length_limit)) then # arguments compatible with OpenSSL::Buffering#gets
114
+ if (line.bytesize < @line_length_limit) then
115
+ line
116
+ elsif (line.bytesize == @line_length_limit && (line.end_with? $/)) then
117
+ line
118
+ else
119
+ raise LineTooLongError.new('line too long.', line_fragment: line)
120
+ end
121
+ end
122
+ end
123
+
124
+ def read_literal(size)
125
+ @logger.debug("found literal: #{size} octets.") if @logger.debug?
126
+ if (size > @literal_size_limit) then
127
+ raise LiteralSizeTooLargeError.new('literal size too large', @command_tag)
128
+ end
129
+ if (@read_size + size > @command_size_limit) then
130
+ raise CommandSizeTooLargeError.new('command size too large', @command_tag)
131
+ end
132
+ @output.write("+ continue\r\n")
133
+ @output.flush
134
+ @logger.debug('continue literal.') if @logger.debug?
135
+ literal_string = @input.read(size) or raise 'unexpected client close.'
136
+ @read_size += size
137
+ @logger.debug("read literal: #{Protocol.io_data_log(literal_string)}") if @logger.debug?
138
+
139
+ literal_string
140
+ end
141
+ private :read_literal
142
+
143
+ def read_line
144
+ line = gets or return
145
+ @logger.debug("read line: #{Protocol.io_data_log(line)}") if @logger.debug?
146
+ line.chomp!("\n")
147
+ line.chomp!("\r")
148
+ @read_size += line.bytesize
149
+ if (@read_size > @command_size_limit) then
150
+ raise CommandSizeTooLargeError.new('command size too large', @command_tag)
151
+ end
152
+ atom_list = self.class.scan(line)
153
+
154
+ if (@command_tag.nil? && ! atom_list.empty?) then
155
+ unless ((atom_list[0].is_a? String) && ! (atom_list[0].start_with? '*', '+')) then
156
+ raise SyntaxError, "invalid command tag: #{atom_list[0]}"
157
+ end
158
+ @command_tag = atom_list[0]
159
+ end
160
+
161
+ if ((atom_list[-1].is_a? Array) && (atom_list[-1][0] == :literal)) then
162
+ atom_list[-1] = read_literal(atom_list[-1][1])
163
+ next_atom_list = read_line or raise 'unexpected client close.'
164
+ atom_list += next_atom_list
165
+ end
166
+
167
+ atom_list
168
+ end
169
+ private :read_line
170
+
121
171
  def read_command
172
+ @command_tag = nil
173
+ @read_size = 0
122
174
  while (atom_list = read_line)
123
175
  if (atom_list.empty?) then
176
+ @read_size = 0
124
177
  next
125
178
  end
126
179
  if (atom_list.length < 2) then
127
- raise 'need for tag and command.'
128
- end
129
- if (atom_list[0] =~ /\A [*+]/x) then
130
- raise "invalid command tag: #{atom_list[0]}"
180
+ raise SyntaxError, 'need for tag and command.'
131
181
  end
132
- return parse(atom_list)
182
+ return self.class.parse(atom_list)
133
183
  end
134
184
 
135
185
  nil
@@ -228,13 +278,15 @@ module RIMS
228
278
  end
229
279
 
230
280
  class SearchParser
231
- def initialize(mail_store, folder)
281
+ def initialize(mail_store, folder, charset_aliases: RFC822::DEFAULT_CHARSET_ALIASES, charset_convert_options: nil)
232
282
  @mail_store = mail_store
233
283
  @folder = folder
284
+ @charset_aliases = charset_aliases
285
+ @charset_convert_options = charset_convert_options || {}
234
286
  @charset = nil
235
287
  @mail_cache = Hash.new{|hash, uid|
236
288
  if (msg_txt = @mail_store.msg_text(@folder.mbox_id, uid)) then
237
- hash[uid] = RFC822::Message.new(msg_txt)
289
+ hash[uid] = RFC822::Message.new(msg_txt, charset_aliases: @charset_aliases)
238
290
  end
239
291
  }
240
292
  end
@@ -247,47 +299,35 @@ module RIMS
247
299
  attr_reader :charset
248
300
 
249
301
  def charset=(new_charset)
250
- @charset = Encoding.find(new_charset)
302
+ charset_encoding = @charset_aliases[new_charset] || Encoding.find(new_charset)
303
+ if (charset_encoding.dummy?) then
304
+ # same error type as `Encoding.find'
305
+ raise ArgumentError, "not a searchable charset: #{new_charset}"
306
+ end
307
+ @charset = charset_encoding
251
308
  end
252
309
 
253
- def force_string_charset(string)
310
+ def force_charset(string)
254
311
  string = string.dup
255
312
  string.force_encoding(@charset)
256
313
  string.valid_encoding? or raise SyntaxError, "invalid #{@charset} string: #{string.inspect}"
257
314
  string
258
315
  end
259
- private :force_string_charset
316
+ private :force_charset
260
317
 
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
318
+ def encode_charset(string)
319
+ if (string.encoding == @charset) then
320
+ string
267
321
  else
268
- if (@charset) then
269
- text = text.encode(@charset)
270
- end
322
+ string.encode(@charset, **@charset_convert_options)
271
323
  end
272
-
273
- text.include? search_string
274
324
  end
275
- private :string_include?
325
+ private :encode_charset
276
326
 
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
327
+ def compile_search_regexp(search_string)
328
+ Regexp.new(Regexp.quote(search_string), true)
289
329
  end
290
- private :mail_body_text
330
+ private :compile_search_regexp
291
331
 
292
332
  def end_of_cond
293
333
  proc{|msg| true }
@@ -322,14 +362,29 @@ module RIMS
322
362
  private :parse_msg_flag_enabled
323
363
 
324
364
  def parse_search_header(field_name, search_string)
325
- search_string = force_string_charset(search_string) if @charset
365
+ if (@charset) then
366
+ search_string = force_charset(search_string)
367
+ search_regexp = compile_search_regexp(search_string)
368
+ search_header = proc{|mail|
369
+ mail.mime_decoded_header_field_value_list(field_name, @charset, charset_convert_options: @charset_convert_options).any?{|field_value|
370
+ search_regexp.match? field_value
371
+ }
372
+ }
373
+ else
374
+ search_string = search_string.b
375
+ search_regexp = compile_search_regexp(search_string)
376
+ search_header = proc{|mail|
377
+ mail.header.field_value_list(field_name).any?{|field_value|
378
+ search_regexp.match? field_value
379
+ }
380
+ }
381
+ end
382
+
326
383
  proc{|next_cond|
327
384
  proc{|msg|
328
385
  mail = get_mail(msg)
329
386
  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)
387
+ search_header.call(mail) && next_cond.call(msg)
333
388
  else
334
389
  false
335
390
  end
@@ -372,11 +427,40 @@ module RIMS
372
427
  private :parse_mail_bytesize
373
428
 
374
429
  def parse_body(search_string)
375
- search_string = force_string_charset(search_string) if @charset
430
+ if (@charset)
431
+ search_string = force_charset(search_string)
432
+ search_regexp = compile_search_regexp(search_string)
433
+ search_body = proc{|mail|
434
+ if (mail.text? || mail.messge?) then
435
+ search_regexp.match? encode_charset(mail.mime_charset_body_text)
436
+ elsif (mail.multipart?) then
437
+ mail.parts.any?{|next_mail|
438
+ search_body.call(next_mail)
439
+ }
440
+ else
441
+ false
442
+ end
443
+ }
444
+ else
445
+ search_string = search_string.b
446
+ search_regexp = compile_search_regexp(search_string)
447
+ search_body = proc{|mail|
448
+ if (mail.text? || mail.message?)then
449
+ search_regexp.match? mail.mime_binary_body_string
450
+ elsif (mail.multipart?) then
451
+ mail.parts.any?{|next_mail|
452
+ search_body.call(next_mail)
453
+ }
454
+ else
455
+ false
456
+ end
457
+ }
458
+ end
459
+
376
460
  proc{|next_cond|
377
461
  proc{|msg|
378
- if (text = mail_body_text(get_mail(msg))) then
379
- string_include?(search_string, text) && next_cond.call(msg)
462
+ if (mail = get_mail(msg)) then
463
+ search_body.call(mail) && next_cond.call(msg)
380
464
  else
381
465
  false
382
466
  end
@@ -435,20 +519,44 @@ module RIMS
435
519
  private :parse_or
436
520
 
437
521
  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
- }
522
+ if (@charset) then
523
+ search_string = force_charset(search_string)
524
+ search_regexp = compile_search_regexp(search_string)
525
+ search_text = proc{|mail|
526
+ if (search_regexp.match? mail.mime_decoded_header_text(@charset, charset_convert_options: @charset_convert_options)) then
527
+ true
528
+ elsif (mail.text? || mail.message?) then
529
+ search_regexp.match? encode_charset(mail.mime_charset_body_text)
530
+ elsif (mail.multipart?) then
531
+ mail.parts.any?{|next_mail|
532
+ search_text.call(next_mail)
533
+ }
534
+ else
535
+ false
536
+ end
537
+ }
538
+ else
539
+ search_string = search_string.b
540
+ search_regexp = compile_search_regexp(search_string)
541
+ search_text = proc{|mail|
542
+ if (search_regexp.match? mail.header.raw_source) then
543
+ true
544
+ elsif (mail.text? || mail.message?) then
545
+ search_regexp.match? mail.mime_binary_body_string
546
+ elsif (mail.multipart?) then
547
+ mail.parts.any?{|next_mail|
548
+ search_text.call(next_mail)
549
+ }
550
+ else
551
+ false
552
+ end
553
+ }
554
+ end
555
+
448
556
  proc{|next_cond|
449
557
  proc{|msg|
450
558
  mail = get_mail(msg)
451
- search_mail.call(mail) && next_cond.call(msg)
559
+ search_text.call(mail) && next_cond.call(msg)
452
560
  }
453
561
  }
454
562
  end
@@ -768,12 +876,12 @@ module RIMS
768
876
  end
769
877
  include Utils
770
878
 
771
- def initialize(mail_store, folder)
879
+ def initialize(mail_store, folder, charset_aliases: RFC822::DEFAULT_CHARSET_ALIASES)
772
880
  @mail_store = mail_store
773
881
  @folder = folder
774
882
  @mail_cache = Hash.new{|hash, uid|
775
883
  if (msg_txt = @mail_store.msg_text(@folder.mbox_id, uid)) then
776
- hash[uid] = RFC822::Message.new(msg_txt)
884
+ hash[uid] = RFC822::Message.new(msg_txt, charset_aliases: charset_aliases)
777
885
  end
778
886
  }
779
887
  end
@@ -118,6 +118,7 @@ module RIMS
118
118
  # daemon:
119
119
  # daemonize: true
120
120
  # debug: false
121
+ # umask: 0037
121
122
  # status_file: rims.pid
122
123
  # server_polling_interval_seconds: 3
123
124
  # server_privileged_user: nobody
@@ -157,10 +158,29 @@ module RIMS
157
158
  # send_buffer_limit_size: 16384
158
159
  # read_polling_interval_seconds: 1
159
160
  # command_wait_timeout_seconds: 1800
161
+ # protocol:
162
+ # line_length_limit: 8192
163
+ # literal_size_limit: 10485760
164
+ # command_size_limit: 10485760
165
+ # charset:
166
+ # use_default_aliases: true
167
+ # aliases:
168
+ # - name: euc-jp
169
+ # encoding: eucJP-ms
170
+ # - name: ios-2022-jp
171
+ # encoding: CP50221
172
+ # - name: Shift_JIS
173
+ # encoding: Windows-31J
174
+ # convert_options:
175
+ # replace_invalid_byte_sequence: false
176
+ # replace_undefined_character: true
177
+ # replaced_mark: "\uFFFD"
160
178
  # drb_services:
161
179
  # process_num: 4
180
+ # load_limit: 134217728
162
181
  # engine:
163
182
  # bulk_response_count: 100
183
+ # bulk_response_size: 33554432
164
184
  # read_lock_timeout_seconds: 30
165
185
  # write_lock_timeout_seconds: 30
166
186
  # cleanup_write_lock_timeout_seconds: 1
@@ -385,9 +405,8 @@ module RIMS
385
405
  end
386
406
 
387
407
  def daemonize?
388
- daemon_config = @config['daemon'] || {}
389
- if (daemon_config.key? 'daemonize') then
390
- daemon_config['daemonize']
408
+ if (@config.dig('daemon')&.key? 'daemonize') then
409
+ @config.dig('daemon', 'daemonize')
391
410
  else
392
411
  true
393
412
  end
@@ -398,14 +417,17 @@ module RIMS
398
417
  end
399
418
 
400
419
  def daemon_debug?
401
- daemon_config = @config['daemon'] || {}
402
- if (daemon_config.key? 'debug') then
403
- daemon_config['debug']
420
+ if (@config.dig('daemon')&.key? 'debug') then
421
+ @config.dig('daemon', 'debug')
404
422
  else
405
423
  false
406
424
  end
407
425
  end
408
426
 
427
+ def daemon_umask
428
+ @config.dig('daemon', 'umask') || 0037
429
+ end
430
+
409
431
  def status_file
410
432
  file_path = @config.dig('daemon', 'status_file') || 'rims.pid'
411
433
  file_path = Pathname(file_path)
@@ -521,22 +543,20 @@ module RIMS
521
543
  end
522
544
 
523
545
  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
546
+ if (@config.dig('openssl')&.key? 'use_ssl') then
547
+ use_ssl = @config.dig('openssl', 'use_ssl')
548
+ else
549
+ use_ssl = (@config.dig('openssl')&.key? 'ssl_context') || false
550
+ end
537
551
 
538
- ssl_context
552
+ if (use_ssl) then
553
+ ssl_context = OpenSSL::SSL::SSLContext.new
554
+ if (ssl_config_expr = @config.dig('openssl', 'ssl_context')) then
555
+ anon_mod = SSLContextConfigAttribute.new_module(ssl_context, base_dir)
556
+ SSLContextConfigAttribute.eval_config(anon_mod, ssl_config_expr, 'ssl_context')
539
557
  end
558
+
559
+ ssl_context
540
560
  end
541
561
  end
542
562
 
@@ -551,14 +571,102 @@ module RIMS
551
571
  @config.dig('connection', 'command_wait_timeout_seconds') || 60 * 30)
552
572
  end
553
573
 
574
+ def protocol_line_length_limit
575
+ @config.dig('protocol', 'line_length_limit') || 1024 * 8
576
+ end
577
+
578
+ def protocol_literal_size_limit
579
+ @config.dig('protocol', 'literal_size_limit') || 1024**2 * 10
580
+ end
581
+
582
+ def protocol_command_size_limit
583
+ @config.dig('protocol', 'command_size_limit') || 1024**2 * 10
584
+ end
585
+
586
+ def charset_aliases
587
+ charset_aliases = RFC822::CharsetAliases.new
588
+
589
+ if (@config.dig('charset')&.key? 'use_default_aliases') then
590
+ use_default_aliases = @config.dig('charset', 'use_default_aliases')
591
+ else
592
+ use_default_aliases = true
593
+ end
594
+
595
+ if (use_default_aliases) then
596
+ for name, encoding in RFC822::DEFAULT_CHARSET_ALIASES
597
+ charset_aliases.add_alias(name, encoding)
598
+ end
599
+ end
600
+
601
+ if (alias_list = @config.dig('charset', 'aliases')) then
602
+ for an_alias in alias_list
603
+ charset_aliases.add_alias(an_alias['name'], Encoding.find(an_alias['encoding']))
604
+ end
605
+ end
606
+
607
+ charset_aliases
608
+ end
609
+
610
+ def charset_convert_options
611
+ options = {}
612
+
613
+ if (@config.dig('charset', 'convert_options')&.key? 'replace_invalid_byte_sequence') then
614
+ replace_invalid_byte_sequence = @config.dig('charset', 'convert_options', 'replace_invalid_byte_sequence')
615
+ else
616
+ replace_invalid_byte_sequence = false
617
+ end
618
+
619
+ if (replace_invalid_byte_sequence) then
620
+ options[:invalid] = :replace
621
+ end
622
+
623
+ if (@config.dig('charset', 'convert_options')&.key? 'replace_undefined_character') then
624
+ replace_undefined_character = @config.dig('charset', 'convert_options', 'replace_undefined_character')
625
+ else
626
+ replace_undefined_character = true
627
+ end
628
+
629
+ if (replace_undefined_character) then
630
+ options[:undef] = :replace
631
+ end
632
+
633
+ if (replaced_mark = @config.dig('charset', 'convert_options', 'replaced_mark')) then
634
+ options[:replace] = replaced_mark
635
+ end
636
+
637
+ options
638
+ end
639
+
554
640
  def drb_process_num
555
641
  @config.dig('drb_services', 'process_num') || 0
556
642
  end
557
643
 
644
+ def drb_server_config
645
+ config = {}
646
+ if (load_limit = @config.dig('drb_services', 'load_limit')) then
647
+ config[:load_limit] = load_limit
648
+ end
649
+
650
+ config
651
+ end
652
+
653
+ def drb_client_config
654
+ config = {}
655
+ if (load_limit = @config.dig('drb_services', 'load_limit')) then
656
+ config[:load_limit] = load_limit
657
+ end
658
+
659
+ config
660
+ end
661
+
558
662
  def bulk_response_count
559
663
  @config.dig('drb_services', 'engine', 'bulk_response_count') || 100
560
664
  end
561
665
 
666
+ def bulk_response_size
667
+ @config.dig('drb_services', 'engine', 'bulk_response_size') || 1024**2 * 10
668
+ end
669
+
562
670
  def read_lock_timeout_seconds
563
671
  @config.dig('drb_services', 'engine', 'read_lock_timeout_seconds') ||
564
672
  @config.dig('read_lock_timeout_seconds') || # for backward compatibility
@@ -639,8 +747,8 @@ module RIMS
639
747
  end
640
748
 
641
749
  def make_authentication
642
- if ((@config.key? 'authentication') && (@config['authentication'].is_a? Hash)) then
643
- auth_conf = @config['authentication']
750
+ if (@config.dig('authentication')&.is_a? Hash) then
751
+ auth_conf = @config.dig('authentication')
644
752
  else
645
753
  auth_conf = {}
646
754
  end
@@ -679,8 +787,8 @@ module RIMS
679
787
  end
680
788
 
681
789
  # for backward compatibility
682
- if ((@config.key? 'authentication') && (@config['authentication'].is_a? Array)) then
683
- plug_in_list = @config['authentication']
790
+ if (@config.dig('authentication')&.is_a? Array) then
791
+ plug_in_list = @config.dig('authentication')
684
792
  for plug_in_conf in plug_in_list
685
793
  plug_in_name = plug_in_conf['plug_in'] or raise KeyError, 'not found an authentication plug_in.'
686
794
  plug_in_config = get_configuration(plug_in_conf)
@@ -717,16 +825,16 @@ module RIMS
717
825
  using Logger::JointPlus
718
826
 
719
827
  def setup(server, daemon: false)
720
- file_logger_params = @config.make_file_logger_params
721
- logger = Logger.new(*file_logger_params)
828
+ *file_logger_params, file_logger_opts = @config.make_file_logger_params
829
+ logger = Logger.new(*file_logger_params, **file_logger_opts)
722
830
 
723
- stdout_logger_params = @config.make_stdout_logger_params
831
+ *stdout_logger_params, stdout_logger_opts = @config.make_stdout_logger_params
724
832
  unless (daemon && @config.daemonize?) then
725
- logger += Logger.new(*stdout_logger_params)
833
+ logger += Logger.new(*stdout_logger_params, **stdout_logger_opts)
726
834
  end
727
835
 
728
- protocol_logger_params = @config.make_protocol_logger_params
729
- protocol_logger = Logger.new(*protocol_logger_params)
836
+ *protocol_logger_params, protocol_logger_opts = @config.make_protocol_logger_params
837
+ protocol_logger = Logger.new(*protocol_logger_params, **protocol_logger_opts)
730
838
 
731
839
  logger.info('preload libraries.')
732
840
  Riser.preload
@@ -780,16 +888,21 @@ module RIMS
780
888
  end
781
889
  end
782
890
 
783
- drb_services = Riser::DRbServices.new(drb_process_num)
891
+ drb_services = Riser::DRbServices.new(drb_process_num,
892
+ server_config: @config.drb_server_config,
893
+ client_config: @config.drb_client_config)
784
894
  drb_services.add_sticky_process_service(:engine,
785
895
  Riser::ResourceSet.build{|builder|
786
896
  builder.at_create{|unique_user_id|
787
897
  mail_store = MailStore.build(unique_user_id, kvs_meta_open, kvs_text_open)
788
898
  Protocol::Decoder::Engine.new(unique_user_id, mail_store, logger,
789
899
  bulk_response_count: @config.bulk_response_count,
900
+ bulk_response_size: @config.bulk_response_size,
790
901
  read_lock_timeout_seconds: @config.read_lock_timeout_seconds,
791
902
  write_lock_timeout_seconds: @config.write_lock_timeout_seconds,
792
- cleanup_write_lock_timeout_seconds: @config.cleanup_write_lock_timeout_seconds)
903
+ cleanup_write_lock_timeout_seconds: @config.cleanup_write_lock_timeout_seconds,
904
+ charset_aliases: @config.charset_aliases,
905
+ charset_convert_options: @config.charset_convert_options)
793
906
  }
794
907
  builder.at_destroy{|engine|
795
908
  engine.destroy
@@ -806,17 +919,17 @@ module RIMS
806
919
  file_logger_params[1..-2].each_with_index do |value, i|
807
920
  logger.info("file logging parameter: shift_args[#{i}]=#{value}")
808
921
  end
809
- for name, value in file_logger_params[-1]
922
+ for name, value in file_logger_opts
810
923
  logger.info("file logging parameter: #{name}=#{value}")
811
924
  end
812
- for name, value in stdout_logger_params[-1]
925
+ for name, value in stdout_logger_opts
813
926
  logger.info("stdout logging parameter: #{name}=#{value}")
814
927
  end
815
928
  logger.info("protocol logging parameter: path=#{protocol_logger_params[0]}")
816
929
  protocol_logger_params[1..-2].each_with_index do |value, i|
817
930
  logger.info("protocol logging parameter: shift_args[#{i}]=#{value}")
818
931
  end
819
- for name, value in protocol_logger_params[-1]
932
+ for name, value in protocol_logger_opts
820
933
  logger.info("protocol logging parameter: #{name}=#{value}")
821
934
  end
822
935
  logger.info("listen address: #{server_socket.local_address.inspect_sockaddr}")
@@ -895,11 +1008,27 @@ module RIMS
895
1008
  logger.info("connection parameter: send_buffer_limit_size=#{@config.send_buffer_limit_size}")
896
1009
  logger.info("connection parameter: read_polling_interval_seconds=#{conn_limits.read_polling_interval_seconds}")
897
1010
  logger.info("connection parameter: command_wait_timeout_seconds=#{conn_limits.command_wait_timeout_seconds}")
1011
+ logger.info("protocol parameter: line_length_limit=#{@config.protocol_line_length_limit}")
1012
+ logger.info("protocol parameter: literal_size_limit=#{@config.protocol_literal_size_limit}")
1013
+ logger.info("protocol parameter: command_size_limit=#{@config.protocol_command_size_limit}")
1014
+ @config.charset_aliases.each_with_index do |(name, enc), i|
1015
+ logger.info("charset aliases parameter: alias[#{i}]: #{name} -> #{enc.name}")
1016
+ end
1017
+ for name, value in @config.charset_convert_options
1018
+ logger.info("charset convert_options parameter: #{name}=#{value}")
1019
+ end
898
1020
  logger.info("drb_services parameter: process_num=#{drb_process_num}")
1021
+ for name, value in @config.drb_server_config
1022
+ logger.info("drb_services server config parameter: #{name}=#{value}")
1023
+ end
1024
+ for name, value in @config.drb_client_config
1025
+ logger.info("drb_services client config parameter: #{name}=#{value}")
1026
+ end
899
1027
  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}")
1028
+ logger.info("drb_services engine parameter: bulk_response_size=#{@config.bulk_response_size}")
1029
+ logger.info("drb_services engine parameter: read_lock_timeout_seconds=#{@config.read_lock_timeout_seconds}")
1030
+ logger.info("drb_services engine parameter: write_lock_timeout_seconds=#{@config.write_lock_timeout_seconds}")
1031
+ logger.info("drb_services engine parameter: cleanup_write_lock_timeout_seconds=#{@config.cleanup_write_lock_timeout_seconds}")
903
1032
  kvs_meta_log.call
904
1033
  kvs_text_log.call
905
1034
  logger.info("authentication parameter: hostname=#{auth.hostname}")
@@ -947,7 +1076,11 @@ module RIMS
947
1076
  stream = Riser::WriteBufferStream.new(socket, @config.send_buffer_limit_size)
948
1077
  end
949
1078
  stream = Riser::LoggingStream.new(stream, protocol_logger)
950
- decoder = Protocol::Decoder.new_decoder(drb_services, auth, logger, mail_delivery_user: @config.mail_delivery_user)
1079
+ decoder = Protocol::Decoder.new_decoder(drb_services, auth, logger,
1080
+ mail_delivery_user: @config.mail_delivery_user,
1081
+ line_length_limit: @config.protocol_line_length_limit,
1082
+ literal_size_limit: @config.protocol_literal_size_limit,
1083
+ command_size_limit: @config.protocol_command_size_limit)
951
1084
  Protocol::Decoder.repl(decoder, conn_limits, stream, stream, logger)
952
1085
  ensure
953
1086
  if (stream) then