rims 0.2.5 → 0.3.0
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 +4 -4
- data/.gitignore +3 -0
- data/CHANGELOG.md +96 -0
- data/ChangeLog +109 -0
- data/Rakefile +8 -4
- data/lib/rims.rb +31 -29
- data/lib/rims/channel.rb +35 -10
- data/lib/rims/cmd.rb +153 -31
- data/lib/rims/error.rb +15 -0
- data/lib/rims/protocol.rb +28 -7
- data/lib/rims/protocol/decoder.rb +763 -469
- data/lib/rims/protocol/parser.rb +316 -181
- data/lib/rims/service.rb +190 -57
- data/lib/rims/test.rb +46 -17
- data/lib/rims/version.rb +1 -1
- data/load_test/Rakefile +3 -1
- data/rims.gemspec +14 -12
- data/test/cmd/test_command.rb +135 -23
- data/test/test_channel.rb +2 -1
- data/test/test_error.rb +33 -1
- data/test/test_lock.rb +4 -4
- data/test/test_passwd.rb +1 -1
- data/test/test_protocol_decoder.rb +733 -75
- data/test/test_protocol_fetch.rb +384 -189
- data/test/test_protocol_request.rb +305 -280
- data/test/test_protocol_search.rb +771 -892
- data/test/test_service.rb +165 -0
- metadata +34 -8
- data/lib/rims/rfc822.rb +0 -463
- data/test/test_rfc822.rb +0 -696
data/lib/rims/version.rb
CHANGED
data/load_test/Rakefile
CHANGED
@@ -78,6 +78,8 @@ task :imap_append do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
CLOBBER.include('imap_append')
|
82
|
+
|
81
83
|
desc 'run server'
|
82
84
|
task :run_server do
|
83
85
|
run_server_conf('imap_server', USER_CONF, *%w[ -v debug -l debug --imap-host=localhost --imap-port=14300 ]) do
|
@@ -85,7 +87,7 @@ task :run_server do
|
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
88
|
-
CLOBBER.include('
|
90
|
+
CLOBBER.include('imap_server')
|
89
91
|
|
90
92
|
# Local Variables:
|
91
93
|
# mode: Ruby
|
data/rims.gemspec
CHANGED
@@ -5,10 +5,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
require 'rims/version'
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name =
|
8
|
+
spec.name = 'rims'
|
9
9
|
spec.version = RIMS::VERSION
|
10
|
-
spec.authors = [
|
11
|
-
spec.email = [
|
10
|
+
spec.authors = ['TOKI Yoshinori']
|
11
|
+
spec.email = ['toki@freedom.ne.jp']
|
12
12
|
spec.summary = %q{RIMS is Ruby IMap Server}
|
13
13
|
spec.description = <<-'EOF'
|
14
14
|
RIMS is Ruby IMap Server.
|
@@ -16,22 +16,24 @@ Gem::Specification.new do |spec|
|
|
16
16
|
server can run as a daemon, mailboxes are provided and messages
|
17
17
|
can be delivered to them.
|
18
18
|
EOF
|
19
|
-
spec.homepage =
|
20
|
-
spec.license =
|
19
|
+
spec.homepage = 'https://github.com/y10k/rims'
|
20
|
+
spec.license = 'MIT'
|
21
21
|
|
22
22
|
spec.files = `git ls-files`.split($/)
|
23
23
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
24
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
|
-
spec.require_paths = [
|
25
|
+
spec.require_paths = ['lib']
|
26
26
|
|
27
27
|
spec.required_ruby_version = '>= 2.0.0'
|
28
28
|
|
29
|
-
spec.add_runtime_dependency
|
30
|
-
spec.add_runtime_dependency
|
31
|
-
spec.
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
29
|
+
spec.add_runtime_dependency 'rims-rfc822', '>= 0.2.2'
|
30
|
+
spec.add_runtime_dependency 'riser', '>= 0.2.0'
|
31
|
+
spec.add_runtime_dependency 'logger-joint'
|
32
|
+
spec.add_development_dependency 'bundler'
|
33
|
+
spec.add_development_dependency 'rake'
|
34
|
+
spec.add_development_dependency 'test-unit'
|
35
|
+
spec.add_development_dependency 'rdoc'
|
36
|
+
spec.add_development_dependency 'irb'
|
35
37
|
end
|
36
38
|
|
37
39
|
# Local Variables:
|
data/test/cmd/test_command.rb
CHANGED
@@ -119,6 +119,7 @@ module RIMS::Test
|
|
119
119
|
'--no-daemonize' => [ %W[ -f #{BASE_DIR}/config.yml --no-daemonize ] ],
|
120
120
|
'--daemon-debug' => [ %W[ -f #{BASE_DIR}/config.yml --daemon-debug ] ],
|
121
121
|
'--no-daemon-debug' => [ %W[ -f #{BASE_DIR}/config.yml --no-daemon-debug ] ],
|
122
|
+
'--daemon-umask' => [ %W[ -f #{BASE_DIR}/config.yml --daemon-umask=0022 ] ],
|
122
123
|
'--status-file' => [ %W[ -f #{BASE_DIR}/config.yml --status-file=status.yml ] ],
|
123
124
|
'--privilege-user' => [ %W[ -f #{BASE_DIR}/config.yml --privilege-user=#{Process::UID.eid} ] ],
|
124
125
|
'--privilege-group' => [ %W[ -f #{BASE_DIR}/config.yml --privilege-group=#{Process::GID.eid} ] ],
|
@@ -140,11 +141,30 @@ module RIMS::Test
|
|
140
141
|
'--read-polling-interval' => [ %W[ -f #{BASE_DIR}/config.yml --read-polling-interval=5 ] ],
|
141
142
|
'--command-wait-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --command-wait-timeout=3600 ] ],
|
142
143
|
|
144
|
+
# protocol:
|
145
|
+
'--line-length-limit' => [ %W[ -f #{BASE_DIR}/config.yml --line-length-limit=16384 ] ],
|
146
|
+
'--literal-size-limit' => [ %W[ -f #{BASE_DIR}/config.yml --literal-size-limit=16777216 ] ],
|
147
|
+
'--command-size-limit' => [ %W[ -f #{BASE_DIR}/config.yml --command-size-limit=16777216 ] ],
|
148
|
+
|
149
|
+
# charset aliases:
|
150
|
+
'--use-default-charset-aliases' => [ %W[ -f #{BASE_DIR}/config.yml --use-default-charset-aliases ] ],
|
151
|
+
'--no-use-default-charset-aliases' => [ %W[ -f #{BASE_DIR}/config.yml --no-use-default-charset-aliases ] ],
|
152
|
+
'--add-charset-alias' => [ %W[ -f #{BASE_DIR}/config.yml --no-use-default-charset-aliases --add-charset-alias=iso-2022-jp,CP50221 ] ],
|
153
|
+
|
154
|
+
# charset convert_options:
|
155
|
+
'--replace-charset-invalid' => [ %W[ -f #{BASE_DIR}/config.yml --replace-charset-invalid ] ],
|
156
|
+
'--no-replace-charset-invalid' => [ %W[ -f #{BASE_DIR}/config.yml --no-replace-charset-invalid ] ],
|
157
|
+
'--replace-charset-undef' => [ %W[ -f #{BASE_DIR}/config.yml --replace-charset-undef ] ],
|
158
|
+
'--no-replace-charset-undef' => [ %W[ -f #{BASE_DIR}/config.yml --no-replace-charset-undef ] ],
|
159
|
+
'--charset-replaced-mark' => [ %W[ -f #{BASE_DIR}/config.yml --charset-replaced-mark=? ] ],
|
160
|
+
|
143
161
|
# drb_services:
|
144
162
|
'--drb-process-num' => [ %W[ -f #{BASE_DIR}/config.yml --drb-process-num=4 ] ],
|
163
|
+
'--drb-load-limit' => [ %W[ -f #{BASE_DIR}/config.yml --drb-load-limit=134217728 ] ],
|
145
164
|
|
146
165
|
# drb_services engine:
|
147
166
|
'--bulk-response-count' => [ %W[ -f #{BASE_DIR}/config.yml --bulk-response-count=128 ] ],
|
167
|
+
'--bulk-response-size' => [ %W[ -f #{BASE_DIR}/config.yml --bulk-response-size=33554432 ] ],
|
148
168
|
'--read-lock-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --read-lock-timeout=10 ] ],
|
149
169
|
'--write-lock-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --write-lock-timeout=10 ] ],
|
150
170
|
'--clenup-write-lock-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --write-lock-timeout=5 ] ],
|
@@ -334,6 +354,35 @@ module RIMS::Test
|
|
334
354
|
assert_equal(0, status.exitstatus)
|
335
355
|
end
|
336
356
|
|
357
|
+
data('default' => [ false, %w[] ],
|
358
|
+
'-r' => [ false, %w[ -r prime ] ],
|
359
|
+
'--required-feature' => [ false, %w[ --required-feature=prime ] ],
|
360
|
+
'--format=yaml' => [ false, %w[ --format=yaml ] ],
|
361
|
+
'--format=json' => [ false, %w[ --format=json ] ],
|
362
|
+
|
363
|
+
# deplicated options
|
364
|
+
'deplicated:--load-library' => [ true, %w[ --load-library=prime ] ])
|
365
|
+
def test_environment(data)
|
366
|
+
deplicated, options = data
|
367
|
+
|
368
|
+
stdout, stderr, status = Open3.capture3('rims', 'environment', *options)
|
369
|
+
pp [ stdout, stderr, status ] if $DEBUG
|
370
|
+
|
371
|
+
assert_equal(0, status.exitstatus)
|
372
|
+
if (deplicated) then
|
373
|
+
assert_match(/^warning:/, stderr)
|
374
|
+
else
|
375
|
+
assert_equal('', stderr)
|
376
|
+
end
|
377
|
+
|
378
|
+
assert_match(/RIMS Environment/, stdout)
|
379
|
+
assert_match(/RUBY VERSION.*#{Regexp.quote(RUBY_DESCRIPTION)}/, stdout)
|
380
|
+
assert_match(/RIMS VERSION.*#{Regexp.quote(RIMS::VERSION)}/, stdout)
|
381
|
+
assert_match(/AUTHENTICATION PLUG-IN.*plain/m, stdout)
|
382
|
+
assert_match(/AUTHENTICATION PLUG-IN.*hash/m, stdout)
|
383
|
+
assert_match(/KEY-VALUE STORE PLUG-IN.*gdbm/m, stdout)
|
384
|
+
end
|
385
|
+
|
337
386
|
tls_dir = Pathname(__FILE__).parent.parent / "tls"
|
338
387
|
TLS_CA_CERT = tls_dir / 'ca.cert'
|
339
388
|
TLS_SERVER_CERT = tls_dir / 'server_localhost.cert'
|
@@ -1203,7 +1252,7 @@ Hello world.
|
|
1203
1252
|
assert_equal(seqno[1], imap_search.call([ 'ANSWERED' ])) # *a
|
1204
1253
|
assert_equal(seqno[3], imap_search.call([ 'BCC', 'foo' ])) # *b
|
1205
1254
|
assert_equal(seqno[1], imap_search.call([ 'BEFORE', @mpart_mail.date ]))
|
1206
|
-
assert_equal(seqno[1, 3],
|
1255
|
+
assert_equal(seqno[1, 2, 3], imap_search.call([ 'BODY', 'Hello world.' ]))
|
1207
1256
|
assert_equal(seqno[3], imap_search.call([ 'CC', 'kate' ]))
|
1208
1257
|
assert_equal(seqno[], imap_search.call([ 'DELETED' ]))
|
1209
1258
|
assert_equal(seqno[2], imap_search.call([ 'DRAFT' ]))
|
@@ -1277,49 +1326,112 @@ Hello world.
|
|
1277
1326
|
envelope = lambda{|mail|
|
1278
1327
|
Net::IMAP::Envelope.new(mail.header['Date'],
|
1279
1328
|
mail.header['Subject'],
|
1280
|
-
mail.from ? mail.from.map{|addr| Net::IMAP::Address.new(*addr) } : nil,
|
1281
|
-
mail.reply_to ? mail.reply_to.map{|addr| Net::IMAP::Address.new(*addr) } : nil,
|
1282
|
-
mail.sender ? mail.sender.map{|addr| Net::IMAP::Address.new(*addr) } : nil,
|
1283
|
-
mail.to ? mail.to.map{|addr| Net::IMAP::Address.new(*addr) } : nil,
|
1284
|
-
mail.cc ? mail.cc.map{|addr| Net::IMAP::Address.new(*addr) } : nil,
|
1285
|
-
mail.bcc ? mail.bcc.map{|addr| Net::IMAP::Address.new(*addr) } : nil,
|
1329
|
+
mail.from ? mail.from.map{|addr| Net::IMAP::Address.new(*addr.to_a) } : nil,
|
1330
|
+
mail.reply_to ? mail.reply_to.map{|addr| Net::IMAP::Address.new(*addr.to_a) } : nil,
|
1331
|
+
mail.sender ? mail.sender.map{|addr| Net::IMAP::Address.new(*addr.to_a) } : nil,
|
1332
|
+
mail.to ? mail.to.map{|addr| Net::IMAP::Address.new(*addr.to_a) } : nil,
|
1333
|
+
mail.cc ? mail.cc.map{|addr| Net::IMAP::Address.new(*addr.to_a) } : nil,
|
1334
|
+
mail.bcc ? mail.bcc.map{|addr| Net::IMAP::Address.new(*addr.to_a) } : nil,
|
1286
1335
|
mail.header['In-Reply-To'],
|
1287
1336
|
mail.header['Message-Id'])
|
1288
1337
|
}
|
1289
|
-
body_type = lambda{|mail|
|
1290
|
-
|
1291
|
-
|
1338
|
+
body_type = lambda{|mail, extension=false|
|
1339
|
+
body_params = lambda{|params|
|
1340
|
+
if (params && ! params.empty?) then
|
1341
|
+
Hash[params.map{|n, v| [ n.upcase, v ] }]
|
1342
|
+
end
|
1343
|
+
}
|
1344
|
+
body_disposition = lambda{|mail|
|
1345
|
+
if (mail.content_disposition) then
|
1346
|
+
Net::IMAP::ContentDisposition.new(mail.content_disposition_upcase,
|
1347
|
+
body_params[mail.content_disposition_parameter_list])
|
1348
|
+
end
|
1349
|
+
}
|
1350
|
+
body_language = lambda{|mail|
|
1351
|
+
if (mail.content_language) then
|
1352
|
+
if (mail.content_language.length > 1) then
|
1353
|
+
mail.content_language_upcase
|
1354
|
+
else
|
1355
|
+
mail.content_language_upcase[0]
|
1356
|
+
end
|
1357
|
+
end
|
1358
|
+
}
|
1359
|
+
if (mail.text?) then
|
1292
1360
|
Net::IMAP::BodyTypeText.new(mail.media_main_type_upcase,
|
1293
1361
|
mail.media_sub_type_upcase,
|
1294
|
-
|
1362
|
+
body_params[mail.content_type_parameter_list],
|
1295
1363
|
mail.header['Content-Id'],
|
1296
1364
|
mail.header['Content-Description'],
|
1297
1365
|
mail.header.fetch_upcase('Content-Transfer-Encoding'),
|
1298
1366
|
mail.raw_source.bytesize,
|
1299
|
-
mail.raw_source.each_line.count
|
1300
|
-
|
1367
|
+
mail.raw_source.each_line.count,
|
1368
|
+
*(
|
1369
|
+
if (extension) then
|
1370
|
+
[ mail.header['Content-MD5'],
|
1371
|
+
body_disposition[mail],
|
1372
|
+
body_language[mail],
|
1373
|
+
[ mail.header['Content-Location'] ]
|
1374
|
+
]
|
1375
|
+
else
|
1376
|
+
[]
|
1377
|
+
end
|
1378
|
+
))
|
1379
|
+
elsif (mail.message?) then
|
1301
1380
|
Net::IMAP::BodyTypeMessage.new(mail.media_main_type_upcase,
|
1302
1381
|
mail.media_sub_type_upcase,
|
1303
|
-
|
1382
|
+
body_params[mail.content_type_parameter_list],
|
1304
1383
|
mail.header['Content-Id'],
|
1305
1384
|
mail.header['Content-Description'],
|
1306
1385
|
mail.header.fetch_upcase('Content-Transfer-Encoding'),
|
1307
1386
|
mail.raw_source.bytesize,
|
1308
1387
|
envelope[mail.message],
|
1309
|
-
body_type[mail.message],
|
1310
|
-
mail.raw_source.each_line.count
|
1311
|
-
|
1388
|
+
body_type[mail.message, extension],
|
1389
|
+
mail.raw_source.each_line.count,
|
1390
|
+
*(
|
1391
|
+
if (extension) then
|
1392
|
+
[ mail.header['Content-MD5'],
|
1393
|
+
body_disposition[mail],
|
1394
|
+
body_language[mail],
|
1395
|
+
[ mail.header['Content-Location'] ]
|
1396
|
+
]
|
1397
|
+
else
|
1398
|
+
[]
|
1399
|
+
end
|
1400
|
+
))
|
1401
|
+
elsif (mail.multipart?) then
|
1312
1402
|
Net::IMAP::BodyTypeMultipart.new(mail.media_main_type_upcase,
|
1313
1403
|
mail.media_sub_type_upcase,
|
1314
|
-
mail.parts.map{|m| body_type[m] }
|
1404
|
+
mail.parts.map{|m| body_type[m, extension] },
|
1405
|
+
*(
|
1406
|
+
if (extension) then
|
1407
|
+
[ body_params[mail.content_type_parameter_list],
|
1408
|
+
body_disposition[mail],
|
1409
|
+
body_language[mail],
|
1410
|
+
[ mail.header['Content-Location'] ]
|
1411
|
+
]
|
1412
|
+
else
|
1413
|
+
[]
|
1414
|
+
end
|
1415
|
+
))
|
1315
1416
|
else
|
1316
1417
|
Net::IMAP::BodyTypeBasic.new(mail.media_main_type_upcase,
|
1317
1418
|
mail.media_sub_type_upcase,
|
1318
|
-
|
1419
|
+
body_params[mail.content_type_parameter_list],
|
1319
1420
|
mail.header['Content-Id'],
|
1320
1421
|
mail.header['Content-Description'],
|
1321
1422
|
mail.header.fetch_upcase('Content-Transfer-Encoding'),
|
1322
|
-
mail.raw_source.bytesize
|
1423
|
+
mail.raw_source.bytesize,
|
1424
|
+
*(
|
1425
|
+
if (extension) then
|
1426
|
+
[ mail.header['Content-MD5'],
|
1427
|
+
body_disposition[mail],
|
1428
|
+
body_language[mail],
|
1429
|
+
[ mail.header['Content-Location'] ]
|
1430
|
+
]
|
1431
|
+
else
|
1432
|
+
[]
|
1433
|
+
end
|
1434
|
+
))
|
1323
1435
|
end
|
1324
1436
|
}
|
1325
1437
|
|
@@ -1406,9 +1518,9 @@ Hello world.
|
|
1406
1518
|
imap_fetch.call(msg_set[1..-1], 'BODY'))
|
1407
1519
|
|
1408
1520
|
assert_equal(fetch_data[
|
1409
|
-
[ 1, { 'BODYSTRUCTURE' => body_type[@simple_mail] } ],
|
1410
|
-
[ 2, { 'BODYSTRUCTURE' => body_type[@mpart_mail] } ],
|
1411
|
-
[ 3, { 'BODYSTRUCTURE' => body_type[@mime_subject_mail] } ]
|
1521
|
+
[ 1, { 'BODYSTRUCTURE' => body_type[@simple_mail, true] } ],
|
1522
|
+
[ 2, { 'BODYSTRUCTURE' => body_type[@mpart_mail, true] } ],
|
1523
|
+
[ 3, { 'BODYSTRUCTURE' => body_type[@mime_subject_mail, true] } ]
|
1412
1524
|
],
|
1413
1525
|
imap_fetch.call(msg_set[1..-1], 'BODYSTRUCTURE'))
|
1414
1526
|
|
data/test/test_channel.rb
CHANGED
@@ -55,7 +55,8 @@ module RIMS::Test
|
|
55
55
|
pub1.publish('msg1')
|
56
56
|
pub2.publish('msg2')
|
57
57
|
|
58
|
-
error = assert_raise(
|
58
|
+
error = assert_raise(RIMS::ServerResponseChannelPublishError) { pub3.publish('msg3') }
|
59
|
+
pp error, error.optional_data if $DEBUG
|
59
60
|
assert_match(/detached/, error.message)
|
60
61
|
|
61
62
|
assert_equal(%w[ msg2 ], sub1.enum_for(:fetch).to_a)
|
data/test/test_error.rb
CHANGED
@@ -4,7 +4,19 @@ require 'rims'
|
|
4
4
|
require 'test/unit'
|
5
5
|
|
6
6
|
module RIMS::Test
|
7
|
-
class
|
7
|
+
class ErrorTest < Test::Unit::TestCase
|
8
|
+
def test_optional_data
|
9
|
+
error = RIMS::Error.new('test', foo: 1, bar: '2')
|
10
|
+
assert_equal('test', error.message)
|
11
|
+
assert_equal({ foo: 1, bar: '2' }, error.optional_data)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_no_optional_data
|
15
|
+
error = RIMS::Error.new('test')
|
16
|
+
assert_equal('test', error.message)
|
17
|
+
assert_predicate(error.optional_data, :empty?)
|
18
|
+
end
|
19
|
+
|
8
20
|
def test_trace_error_chain
|
9
21
|
exception = assert_raise(RuntimeError) {
|
10
22
|
begin
|
@@ -32,6 +44,26 @@ module RIMS::Test
|
|
32
44
|
'error level 0'
|
33
45
|
], errors.map(&:message))
|
34
46
|
end
|
47
|
+
|
48
|
+
def test_optional_data_block
|
49
|
+
count = 0
|
50
|
+
error = RIMS::Error.new('test', foo: 1, bar: '2')
|
51
|
+
RIMS::Error.optional_data(error) do |e, data|
|
52
|
+
count += 1
|
53
|
+
assert_equal(error, e)
|
54
|
+
assert_equal({ foo: 1, bar: '2' }, data)
|
55
|
+
end
|
56
|
+
assert_equal(1, count)
|
57
|
+
end
|
58
|
+
|
59
|
+
data('not a RIMS::Error' => StandardError.new('test'),
|
60
|
+
'no optional data' => RIMS::Error.new('test'))
|
61
|
+
def test_no_optional_data_block(data)
|
62
|
+
error = data
|
63
|
+
RIMS::Error.optional_data(error) do |e, data|
|
64
|
+
flunk
|
65
|
+
end
|
66
|
+
end
|
35
67
|
end
|
36
68
|
end
|
37
69
|
|
data/test/test_lock.rb
CHANGED
@@ -51,7 +51,7 @@ module RIMS::Test
|
|
51
51
|
assert_equal('write-lock wait timeout', error.message)
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def calculate_thread_work_seconds
|
55
55
|
t0 = Time.now
|
56
56
|
1000.times{|i| i.succ }
|
57
57
|
t1 = Time.now
|
@@ -60,10 +60,10 @@ module RIMS::Test
|
|
60
60
|
|
61
61
|
wait_seconds
|
62
62
|
end
|
63
|
-
private :
|
63
|
+
private :calculate_thread_work_seconds
|
64
64
|
|
65
65
|
def test_read_write_lock_multithread
|
66
|
-
lock_wait_seconds =
|
66
|
+
lock_wait_seconds = calculate_thread_work_seconds
|
67
67
|
|
68
68
|
count = 0
|
69
69
|
read_thread_num = 10
|
@@ -116,7 +116,7 @@ module RIMS::Test
|
|
116
116
|
def test_write_lock_timeout_detach
|
117
117
|
logger = Logger.new(STDOUT)
|
118
118
|
logger.level = ($DEBUG) ? Logger::DEBUG : Logger::FATAL
|
119
|
-
wait_seconds =
|
119
|
+
wait_seconds = calculate_thread_work_seconds
|
120
120
|
|
121
121
|
t_list = []
|
122
122
|
assert_nil(RIMS::ReadWriteLock.write_lock_timeout_detach(wait_seconds, wait_seconds * 2, logger: logger ) {|timeout_seconds|
|
data/test/test_passwd.rb
CHANGED
@@ -127,6 +127,7 @@ module RIMS::Test
|
|
127
127
|
cmd_name, cmd_args, cmd_client_output = parse_imap_command(tag, imap_command_message)
|
128
128
|
normalized_cmd_name = RIMS::Protocol::Decoder.imap_command_normalize(cmd_name)
|
129
129
|
cmd_id = RIMS::Protocol::Decoder::IMAP_CMDs[normalized_cmd_name] or flunk("not a imap command: #{cmd_name}")
|
130
|
+
cmd_kw_args = {}
|
130
131
|
|
131
132
|
input = nil
|
132
133
|
output = nil
|
@@ -135,8 +136,10 @@ module RIMS::Test
|
|
135
136
|
output = StringIO.new('', 'w')
|
136
137
|
input_gets = input.method(:gets)
|
137
138
|
output_write = lambda{|res|
|
138
|
-
for
|
139
|
-
|
139
|
+
for data in res
|
140
|
+
if (data != :flush) then
|
141
|
+
output << data
|
142
|
+
end
|
140
143
|
end
|
141
144
|
}
|
142
145
|
inout_args = [ input_gets, output_write ]
|
@@ -144,30 +147,29 @@ module RIMS::Test
|
|
144
147
|
cmd_args = inout_args + cmd_args
|
145
148
|
end
|
146
149
|
unless (uid.nil?) then
|
147
|
-
|
150
|
+
cmd_kw_args[:uid] = uid
|
148
151
|
end
|
149
152
|
|
150
153
|
block_call = 0
|
151
154
|
ret_val = nil
|
152
155
|
|
156
|
+
response_message = cmd_client_output.b
|
153
157
|
pp [ :debug_imap_command, imap_command_message, cmd_id, cmd_args ] if $DEBUG
|
154
|
-
@decoder.__send__(cmd_id, tag, *cmd_args) {|
|
158
|
+
@decoder.__send__(cmd_id, tag, *cmd_args, **cmd_kw_args) {|response|
|
155
159
|
block_call += 1
|
156
|
-
|
157
|
-
if (output) then
|
160
|
+
if (block_call == 1 && output) then
|
158
161
|
response_message << output.string
|
159
162
|
end
|
160
|
-
|
163
|
+
if (response != :flush) then
|
161
164
|
response_message << response
|
162
165
|
end
|
163
|
-
response_lines = StringIO.new(response_message, 'r').each_line
|
164
|
-
ret_val = yield(response_lines)
|
165
|
-
assert_raise(StopIteration) { response_lines.next }
|
166
166
|
}
|
167
|
+
response_lines = StringIO.new(response_message, 'r').each_line
|
168
|
+
ret_val = yield(response_lines)
|
169
|
+
assert_raise(StopIteration) { response_lines.next }
|
167
170
|
if (client_input_text) then
|
168
171
|
pp input.string, output.string if $DEBUG
|
169
172
|
end
|
170
|
-
assert_equal(1, block_call, 'IMAP command block should be called only once.')
|
171
173
|
|
172
174
|
@decoder = @decoder.next_decoder
|
173
175
|
|
@@ -242,7 +244,7 @@ module RIMS::Test
|
|
242
244
|
extend Forwardable
|
243
245
|
|
244
246
|
def open_mail_store
|
245
|
-
@
|
247
|
+
@drb_services.call_service(:engine, @unique_user_id) {|engine|
|
246
248
|
begin
|
247
249
|
@mail_store = engine.mail_store
|
248
250
|
@mail_store.write_synchronize{
|
@@ -255,8 +257,15 @@ module RIMS::Test
|
|
255
257
|
end
|
256
258
|
private :open_mail_store
|
257
259
|
|
260
|
+
LINE_LENGTH_LIMIT = 128
|
261
|
+
LITERAL_SIZE_LIMIT = 1024**2
|
262
|
+
COMMAND_SIZE_LIMIT = LITERAL_SIZE_LIMIT + LINE_LENGTH_LIMIT
|
263
|
+
|
258
264
|
def make_decoder
|
259
|
-
RIMS::Protocol::Decoder.new_decoder(@
|
265
|
+
RIMS::Protocol::Decoder.new_decoder(@drb_services, @auth, @logger,
|
266
|
+
line_length_limit: LINE_LENGTH_LIMIT,
|
267
|
+
literal_size_limit: LITERAL_SIZE_LIMIT,
|
268
|
+
command_size_limit: COMMAND_SIZE_LIMIT)
|
260
269
|
end
|
261
270
|
private :make_decoder
|
262
271
|
|
@@ -288,20 +297,26 @@ module RIMS::Test
|
|
288
297
|
}
|
289
298
|
@unique_user_id = RIMS::Authentication.unique_user_id('foo')
|
290
299
|
|
291
|
-
@
|
292
|
-
@
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
300
|
+
@bulk_response_count = 10
|
301
|
+
@charset_aliases = RIMS::RFC822::CharsetAliases.new
|
302
|
+
@charset_convert_options = {}
|
303
|
+
@drb_services = Riser::DRbServices.new(0)
|
304
|
+
@drb_services.add_sticky_process_service(:engine,
|
305
|
+
Riser::ResourceSet.build{|builder|
|
306
|
+
builder.at_create{|unique_user_id|
|
307
|
+
mail_store = RIMS::MailStore.build(unique_user_id, @kvs_open, @kvs_open)
|
308
|
+
RIMS::Protocol::Decoder::Engine.new(unique_user_id, mail_store, @logger,
|
309
|
+
bulk_response_count: @bulk_response_count,
|
310
|
+
charset_aliases: @charset_aliases,
|
311
|
+
charset_convert_options: @charset_convert_options)
|
312
|
+
}
|
313
|
+
builder.at_destroy{|engine|
|
314
|
+
engine.destroy
|
315
|
+
}
|
316
|
+
builder.alias_unref(:destroy)
|
317
|
+
})
|
318
|
+
@drb_services.start_server
|
319
|
+
@drb_services.start_client
|
305
320
|
|
306
321
|
open_mail_store{
|
307
322
|
@inbox_id = @mail_store.mbox_id('INBOX')
|
@@ -328,8 +343,8 @@ module RIMS::Test
|
|
328
343
|
end
|
329
344
|
|
330
345
|
def teardown
|
331
|
-
assert_equal(0, @
|
332
|
-
@
|
346
|
+
assert_equal(0, @drb_services.get_service(:engine, @unique_user_id).proxy_count)
|
347
|
+
@drb_services.stop_server
|
333
348
|
pp @kvs if $DEBUG
|
334
349
|
end
|
335
350
|
|
@@ -372,6 +387,17 @@ module RIMS::Test
|
|
372
387
|
end
|
373
388
|
private :assert_imap_command
|
374
389
|
|
390
|
+
def assert_imap_closed
|
391
|
+
if (stream_test?) then
|
392
|
+
assert_raise(Errno::EPIPE, StopIteration) {
|
393
|
+
assert_imap_command('NOOP') {|assert|
|
394
|
+
assert.equal("#{tag} OK NOOP completed")
|
395
|
+
}
|
396
|
+
}
|
397
|
+
end
|
398
|
+
end
|
399
|
+
private :assert_imap_closed
|
400
|
+
|
375
401
|
def client_plain_response_base64(authentication_id, plain_password)
|
376
402
|
response_txt = [ authentication_id, authentication_id, plain_password ].join("\0")
|
377
403
|
RIMS::Protocol.encode_base64(response_txt)
|
@@ -554,6 +580,8 @@ module RIMS::Test
|
|
554
580
|
assert.match(/^\* BYE /)
|
555
581
|
assert.equal("#{tag} OK LOGOUT completed")
|
556
582
|
}
|
583
|
+
|
584
|
+
assert_imap_closed
|
557
585
|
}
|
558
586
|
end
|
559
587
|
|
@@ -599,6 +627,8 @@ module RIMS::Test
|
|
599
627
|
}
|
600
628
|
|
601
629
|
assert_equal(false, @decoder.auth?) if command_test?
|
630
|
+
|
631
|
+
assert_imap_closed
|
602
632
|
}
|
603
633
|
end
|
604
634
|
|
@@ -650,6 +680,8 @@ module RIMS::Test
|
|
650
680
|
}
|
651
681
|
|
652
682
|
assert_equal(false, @decoder.auth?) if command_test?
|
683
|
+
|
684
|
+
assert_imap_closed
|
653
685
|
}
|
654
686
|
end
|
655
687
|
|
@@ -705,6 +737,8 @@ module RIMS::Test
|
|
705
737
|
}
|
706
738
|
|
707
739
|
assert_equal(false, @decoder.auth?) if command_test?
|
740
|
+
|
741
|
+
assert_imap_closed
|
708
742
|
}
|
709
743
|
end
|
710
744
|
|
@@ -747,6 +781,8 @@ module RIMS::Test
|
|
747
781
|
}
|
748
782
|
|
749
783
|
assert_equal(false, @decoder.auth?) if command_test?
|
784
|
+
|
785
|
+
assert_imap_closed
|
750
786
|
}
|
751
787
|
end
|
752
788
|
|
@@ -828,6 +864,8 @@ module RIMS::Test
|
|
828
864
|
assert_equal(false, @decoder.selected?)
|
829
865
|
end
|
830
866
|
|
867
|
+
assert_imap_closed
|
868
|
+
|
831
869
|
open_mail_store{
|
832
870
|
assert_msg_uid( 2, 3)
|
833
871
|
assert_flag_enabled_msgs('answered', )
|
@@ -878,6 +916,8 @@ module RIMS::Test
|
|
878
916
|
assert.match(/^\* BYE /)
|
879
917
|
assert.equal("#{tag} OK LOGOUT completed")
|
880
918
|
}
|
919
|
+
|
920
|
+
assert_imap_closed
|
881
921
|
}
|
882
922
|
end
|
883
923
|
|
@@ -959,6 +999,8 @@ module RIMS::Test
|
|
959
999
|
assert_equal(false, @decoder.selected?)
|
960
1000
|
end
|
961
1001
|
|
1002
|
+
assert_imap_closed
|
1003
|
+
|
962
1004
|
open_mail_store{
|
963
1005
|
assert_msg_uid( 1, 2, 3)
|
964
1006
|
assert_flag_enabled_msgs('answered', )
|
@@ -1009,6 +1051,8 @@ module RIMS::Test
|
|
1009
1051
|
assert.match(/^\* BYE /)
|
1010
1052
|
assert.equal("#{tag} OK LOGOUT completed")
|
1011
1053
|
}
|
1054
|
+
|
1055
|
+
assert_imap_closed
|
1012
1056
|
}
|
1013
1057
|
end
|
1014
1058
|
|
@@ -1058,6 +1102,8 @@ module RIMS::Test
|
|
1058
1102
|
assert.match(/^\* BYE /)
|
1059
1103
|
assert.equal("#{tag} OK LOGOUT completed")
|
1060
1104
|
}
|
1105
|
+
|
1106
|
+
assert_imap_closed
|
1061
1107
|
}
|
1062
1108
|
end
|
1063
1109
|
|
@@ -1094,6 +1140,8 @@ module RIMS::Test
|
|
1094
1140
|
assert.match(/^\* BYE /)
|
1095
1141
|
assert.equal("#{tag} OK LOGOUT completed")
|
1096
1142
|
}
|
1143
|
+
|
1144
|
+
assert_imap_closed
|
1097
1145
|
}
|
1098
1146
|
end
|
1099
1147
|
|
@@ -1166,6 +1214,8 @@ module RIMS::Test
|
|
1166
1214
|
assert.match(/^\* BYE /)
|
1167
1215
|
assert.equal("#{tag} OK LOGOUT completed")
|
1168
1216
|
}
|
1217
|
+
|
1218
|
+
assert_imap_closed
|
1169
1219
|
}
|
1170
1220
|
end
|
1171
1221
|
|
@@ -1206,6 +1256,8 @@ module RIMS::Test
|
|
1206
1256
|
assert.match(/^\* BYE /)
|
1207
1257
|
assert.equal("#{tag} OK LOGOUT completed")
|
1208
1258
|
}
|
1259
|
+
|
1260
|
+
assert_imap_closed
|
1209
1261
|
}
|
1210
1262
|
end
|
1211
1263
|
|
@@ -1285,6 +1337,8 @@ module RIMS::Test
|
|
1285
1337
|
assert.match(/^\* BYE /)
|
1286
1338
|
assert.equal("#{tag} OK LOGOUT completed")
|
1287
1339
|
}
|
1340
|
+
|
1341
|
+
assert_imap_closed
|
1288
1342
|
}
|
1289
1343
|
end
|
1290
1344
|
|
@@ -1332,6 +1386,8 @@ module RIMS::Test
|
|
1332
1386
|
assert.match(/^\* BYE /)
|
1333
1387
|
assert.equal("#{tag} OK LOGOUT completed")
|
1334
1388
|
}
|
1389
|
+
|
1390
|
+
assert_imap_closed
|
1335
1391
|
}
|
1336
1392
|
end
|
1337
1393
|
|
@@ -1401,6 +1457,8 @@ module RIMS::Test
|
|
1401
1457
|
assert.match(/^\* BYE /)
|
1402
1458
|
assert.equal("#{tag} OK LOGOUT completed")
|
1403
1459
|
}
|
1460
|
+
|
1461
|
+
assert_imap_closed
|
1404
1462
|
}
|
1405
1463
|
end
|
1406
1464
|
|
@@ -1511,6 +1569,8 @@ module RIMS::Test
|
|
1511
1569
|
assert.match(/^\* BYE /)
|
1512
1570
|
assert.equal("#{tag} OK LOGOUT completed")
|
1513
1571
|
}
|
1572
|
+
|
1573
|
+
assert_imap_closed
|
1514
1574
|
}
|
1515
1575
|
end
|
1516
1576
|
|
@@ -1549,6 +1609,8 @@ module RIMS::Test
|
|
1549
1609
|
assert.match(/^\* BYE /)
|
1550
1610
|
assert.equal("#{tag} OK LOGOUT completed")
|
1551
1611
|
}
|
1612
|
+
|
1613
|
+
assert_imap_closed
|
1552
1614
|
}
|
1553
1615
|
end
|
1554
1616
|
|
@@ -1655,6 +1717,8 @@ module RIMS::Test
|
|
1655
1717
|
assert.match(/^\* BYE /)
|
1656
1718
|
assert.equal("#{tag} OK LOGOUT completed")
|
1657
1719
|
}
|
1720
|
+
|
1721
|
+
assert_imap_closed
|
1658
1722
|
}
|
1659
1723
|
end
|
1660
1724
|
|
@@ -1686,6 +1750,8 @@ module RIMS::Test
|
|
1686
1750
|
assert.match(/^\* BYE /)
|
1687
1751
|
assert.equal("#{tag} OK LOGOUT completed")
|
1688
1752
|
}
|
1753
|
+
|
1754
|
+
assert_imap_closed
|
1689
1755
|
}
|
1690
1756
|
end
|
1691
1757
|
|
@@ -1753,6 +1819,8 @@ module RIMS::Test
|
|
1753
1819
|
assert.match(/^\* BYE /)
|
1754
1820
|
assert.equal("#{tag} OK LOGOUT completed")
|
1755
1821
|
}
|
1822
|
+
|
1823
|
+
assert_imap_closed
|
1756
1824
|
}
|
1757
1825
|
end
|
1758
1826
|
|
@@ -1873,6 +1941,8 @@ module RIMS::Test
|
|
1873
1941
|
assert.match(/^\* BYE /)
|
1874
1942
|
assert.equal("#{tag} OK LOGOUT completed")
|
1875
1943
|
}
|
1944
|
+
|
1945
|
+
assert_imap_closed
|
1876
1946
|
}
|
1877
1947
|
end
|
1878
1948
|
|
@@ -1912,6 +1982,8 @@ module RIMS::Test
|
|
1912
1982
|
assert.match(/^\* BYE /)
|
1913
1983
|
assert.equal("#{tag} OK LOGOUT completed")
|
1914
1984
|
}
|
1985
|
+
|
1986
|
+
assert_imap_closed
|
1915
1987
|
}
|
1916
1988
|
end
|
1917
1989
|
|
@@ -1920,6 +1992,69 @@ module RIMS::Test
|
|
1920
1992
|
test_append_utf7_mbox_name
|
1921
1993
|
end
|
1922
1994
|
|
1995
|
+
def test_append_literal_stream
|
1996
|
+
make_mail_simple
|
1997
|
+
make_mail_multipart
|
1998
|
+
make_mail_mime_subject
|
1999
|
+
|
2000
|
+
use_imap_stream_decode_engine # always run in stream
|
2001
|
+
imap_decode_engine_evaluate{
|
2002
|
+
if (stream_test?) then
|
2003
|
+
assert_untagged_response{|assert|
|
2004
|
+
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
2005
|
+
}
|
2006
|
+
end
|
2007
|
+
|
2008
|
+
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
2009
|
+
assert.equal("#{tag} OK LOGIN completed")
|
2010
|
+
}
|
2011
|
+
|
2012
|
+
open_mail_store{
|
2013
|
+
assert_msg_uid()
|
2014
|
+
}
|
2015
|
+
|
2016
|
+
assert_imap_command("APPEND INBOX #{literal(@simple_mail.raw_source)}") {|assert|
|
2017
|
+
assert.match(/^\+ /)
|
2018
|
+
assert.match(/^#{tag} OK \[APPENDUID \d+ \d+\] APPEND completed/)
|
2019
|
+
}
|
2020
|
+
|
2021
|
+
open_mail_store{
|
2022
|
+
assert_msg_uid(1)
|
2023
|
+
assert_equal(@simple_mail.raw_source, get_msg_text(1))
|
2024
|
+
assert_msg_flags(1, recent: true)
|
2025
|
+
}
|
2026
|
+
|
2027
|
+
assert_imap_command("APPEND INBOX #{literal(@mpart_mail.raw_source)}") {|assert|
|
2028
|
+
assert.match(/^\+ /)
|
2029
|
+
assert.match(/^#{tag} OK \[APPENDUID \d+ \d+\] APPEND completed/)
|
2030
|
+
}
|
2031
|
+
|
2032
|
+
open_mail_store{
|
2033
|
+
assert_msg_uid(1, 2)
|
2034
|
+
assert_equal(@mpart_mail.raw_source, get_msg_text(2))
|
2035
|
+
assert_msg_flags(2, recent: true)
|
2036
|
+
}
|
2037
|
+
|
2038
|
+
assert_imap_command("APPEND INBOX #{literal(@mime_subject_mail.raw_source)}") {|assert|
|
2039
|
+
assert.match(/^\+ /)
|
2040
|
+
assert.match(/^#{tag} OK \[APPENDUID \d+ \d+\] APPEND completed/)
|
2041
|
+
}
|
2042
|
+
|
2043
|
+
open_mail_store{
|
2044
|
+
assert_msg_uid(1, 2, 3)
|
2045
|
+
assert_equal(@mime_subject_mail.raw_source, get_msg_text(3))
|
2046
|
+
assert_msg_flags(3, recent: true)
|
2047
|
+
}
|
2048
|
+
|
2049
|
+
assert_imap_command('LOGOUT') {|assert|
|
2050
|
+
assert.match(/^\* BYE /)
|
2051
|
+
assert.equal("#{tag} OK LOGOUT completed")
|
2052
|
+
}
|
2053
|
+
|
2054
|
+
assert_imap_closed
|
2055
|
+
}
|
2056
|
+
end
|
2057
|
+
|
1923
2058
|
def test_check
|
1924
2059
|
imap_decode_engine_evaluate{
|
1925
2060
|
if (stream_test?) then
|
@@ -1956,7 +2091,7 @@ module RIMS::Test
|
|
1956
2091
|
}
|
1957
2092
|
|
1958
2093
|
assert_imap_command('SELECT INBOX') {|assert|
|
1959
|
-
assert.skip_while{|line| line =~ /^\* /}
|
2094
|
+
assert.skip_while{|line| line =~ /^\* / }
|
1960
2095
|
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
1961
2096
|
}
|
1962
2097
|
|
@@ -1973,6 +2108,8 @@ module RIMS::Test
|
|
1973
2108
|
assert.match(/^\* BYE /)
|
1974
2109
|
assert.equal("#{tag} OK LOGOUT completed")
|
1975
2110
|
}
|
2111
|
+
|
2112
|
+
assert_imap_closed
|
1976
2113
|
}
|
1977
2114
|
end
|
1978
2115
|
|
@@ -2084,6 +2221,8 @@ module RIMS::Test
|
|
2084
2221
|
assert_equal(false, @decoder.auth?)
|
2085
2222
|
assert_equal(false, @decoder.selected?)
|
2086
2223
|
end
|
2224
|
+
|
2225
|
+
assert_imap_closed
|
2087
2226
|
}
|
2088
2227
|
end
|
2089
2228
|
|
@@ -2188,6 +2327,8 @@ module RIMS::Test
|
|
2188
2327
|
assert_equal(false, @decoder.auth?)
|
2189
2328
|
assert_equal(false, @decoder.selected?)
|
2190
2329
|
end
|
2330
|
+
|
2331
|
+
assert_imap_closed
|
2191
2332
|
}
|
2192
2333
|
end
|
2193
2334
|
|
@@ -2338,6 +2479,8 @@ module RIMS::Test
|
|
2338
2479
|
assert.match(/^\* BYE /)
|
2339
2480
|
assert.equal("#{tag} OK LOGOUT completed")
|
2340
2481
|
}
|
2482
|
+
|
2483
|
+
assert_imap_closed
|
2341
2484
|
}
|
2342
2485
|
end
|
2343
2486
|
|
@@ -2414,6 +2557,8 @@ module RIMS::Test
|
|
2414
2557
|
assert.match(/^\* BYE /)
|
2415
2558
|
assert.equal("#{tag} OK LOGOUT completed")
|
2416
2559
|
}
|
2560
|
+
|
2561
|
+
assert_imap_closed
|
2417
2562
|
}
|
2418
2563
|
end
|
2419
2564
|
|
@@ -2439,11 +2584,6 @@ module RIMS::Test
|
|
2439
2584
|
assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
|
2440
2585
|
}
|
2441
2586
|
|
2442
|
-
if (command_test?) then
|
2443
|
-
assert_equal(false, @decoder.auth?)
|
2444
|
-
assert_equal(false, @decoder.selected?)
|
2445
|
-
end
|
2446
|
-
|
2447
2587
|
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
2448
2588
|
assert.equal("#{tag} OK LOGIN completed")
|
2449
2589
|
}
|
@@ -2548,6 +2688,8 @@ module RIMS::Test
|
|
2548
2688
|
assert.match(/^\* BYE /)
|
2549
2689
|
assert.equal("#{tag} OK LOGOUT completed")
|
2550
2690
|
}
|
2691
|
+
|
2692
|
+
assert_imap_closed
|
2551
2693
|
}
|
2552
2694
|
end
|
2553
2695
|
|
@@ -2591,15 +2733,10 @@ module RIMS::Test
|
|
2591
2733
|
assert_equal(false, @decoder.selected?)
|
2592
2734
|
end
|
2593
2735
|
|
2594
|
-
assert_imap_command('SEARCH CHARSET
|
2736
|
+
assert_imap_command('SEARCH CHARSET us-ascii ALL') {|assert|
|
2595
2737
|
assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
|
2596
2738
|
}
|
2597
2739
|
|
2598
|
-
if (command_test?) then
|
2599
|
-
assert_equal(false, @decoder.auth?)
|
2600
|
-
assert_equal(false, @decoder.selected?)
|
2601
|
-
end
|
2602
|
-
|
2603
2740
|
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
2604
2741
|
assert.equal("#{tag} OK LOGIN completed")
|
2605
2742
|
}
|
@@ -2609,7 +2746,7 @@ module RIMS::Test
|
|
2609
2746
|
assert_equal(false, @decoder.selected?)
|
2610
2747
|
end
|
2611
2748
|
|
2612
|
-
assert_imap_command('SEARCH CHARSET
|
2749
|
+
assert_imap_command('SEARCH CHARSET us-ascii ALL') {|assert|
|
2613
2750
|
assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
|
2614
2751
|
}
|
2615
2752
|
|
@@ -2623,28 +2760,37 @@ module RIMS::Test
|
|
2623
2760
|
assert_equal(true, @decoder.selected?)
|
2624
2761
|
end
|
2625
2762
|
|
2626
|
-
assert_imap_command('SEARCH CHARSET
|
2763
|
+
assert_imap_command('SEARCH CHARSET us-ascii ALL') {|assert|
|
2627
2764
|
assert.equal("* SEARCH 1 2 3 4 5\r\n")
|
2628
2765
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2629
2766
|
}
|
2630
2767
|
|
2631
|
-
assert_imap_command('SEARCH CHARSET
|
2768
|
+
assert_imap_command('SEARCH CHARSET us-ascii BODY foo') {|assert|
|
2632
2769
|
assert.equal("* SEARCH 1 2 3\r\n")
|
2633
2770
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2634
2771
|
}
|
2635
2772
|
|
2636
|
-
assert_imap_command('SEARCH CHARSET
|
2773
|
+
assert_imap_command('SEARCH CHARSET us-ascii BODY bar') {|assert|
|
2637
2774
|
assert.equal("* SEARCH\r\n")
|
2638
2775
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2639
2776
|
}
|
2640
2777
|
|
2641
2778
|
utf8_msg = "\u306F\u306B\u307B"
|
2642
|
-
assert_imap_command("SEARCH CHARSET utf-8 BODY
|
2779
|
+
assert_imap_command("SEARCH CHARSET utf-8 BODY #{literal(utf8_msg)}".b) {|assert|
|
2643
2780
|
assert.match(/^\+ /)
|
2644
2781
|
assert.equal("* SEARCH 4 5\r\n")
|
2645
2782
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2646
2783
|
}
|
2647
2784
|
|
2785
|
+
assert_imap_command("SEARCH CHARSET euc-jp BODY #{literal(utf8_msg)}".b) {|assert|
|
2786
|
+
assert.match(/^\+ /)
|
2787
|
+
assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
|
2788
|
+
}
|
2789
|
+
|
2790
|
+
assert_imap_command('SEARCH CHARSET x-nothing BODY foo') {|assert|
|
2791
|
+
assert.match(/^#{tag} NO \[BADCHARSET \(\S+( \S+)*\)\] unknown charset/)
|
2792
|
+
}
|
2793
|
+
|
2648
2794
|
assert_imap_command('SEARCH CHARSET') {|assert|
|
2649
2795
|
assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
|
2650
2796
|
}
|
@@ -2661,6 +2807,8 @@ module RIMS::Test
|
|
2661
2807
|
assert.match(/^\* BYE /)
|
2662
2808
|
assert.equal("#{tag} OK LOGOUT completed")
|
2663
2809
|
}
|
2810
|
+
|
2811
|
+
assert_imap_closed
|
2664
2812
|
}
|
2665
2813
|
end
|
2666
2814
|
|
@@ -2679,6 +2827,7 @@ module RIMS::Test
|
|
2679
2827
|
|
2680
2828
|
open_mail_store{
|
2681
2829
|
add_msg("Content-Type: text/plain\r\n" +
|
2830
|
+
"\r\n" +
|
2682
2831
|
"foo")
|
2683
2832
|
add_msg("Content-Type: text/plain; charset=utf-8\r\n" +
|
2684
2833
|
"X-foo: dummy\r\n" +
|
@@ -2705,15 +2854,10 @@ module RIMS::Test
|
|
2705
2854
|
assert_equal(false, @decoder.selected?)
|
2706
2855
|
end
|
2707
2856
|
|
2708
|
-
assert_imap_command('SEARCH CHARSET
|
2857
|
+
assert_imap_command('SEARCH CHARSET us-ascii ALL') {|assert|
|
2709
2858
|
assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
|
2710
2859
|
}
|
2711
2860
|
|
2712
|
-
if (command_test?) then
|
2713
|
-
assert_equal(false, @decoder.auth?)
|
2714
|
-
assert_equal(false, @decoder.selected?)
|
2715
|
-
end
|
2716
|
-
|
2717
2861
|
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
2718
2862
|
assert.equal("#{tag} OK LOGIN completed")
|
2719
2863
|
}
|
@@ -2723,7 +2867,7 @@ module RIMS::Test
|
|
2723
2867
|
assert_equal(false, @decoder.selected?)
|
2724
2868
|
end
|
2725
2869
|
|
2726
|
-
assert_imap_command('SEARCH CHARSET
|
2870
|
+
assert_imap_command('SEARCH CHARSET us-ascii ALL') {|assert|
|
2727
2871
|
assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
|
2728
2872
|
}
|
2729
2873
|
|
@@ -2737,12 +2881,12 @@ module RIMS::Test
|
|
2737
2881
|
assert_equal(true, @decoder.selected?)
|
2738
2882
|
end
|
2739
2883
|
|
2740
|
-
assert_imap_command('SEARCH CHARSET
|
2884
|
+
assert_imap_command('SEARCH CHARSET us-ascii ALL') {|assert|
|
2741
2885
|
assert.equal("* SEARCH 1 2 3 4 5\r\n")
|
2742
2886
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2743
2887
|
}
|
2744
2888
|
|
2745
|
-
assert_imap_command('SEARCH CHARSET
|
2889
|
+
assert_imap_command('SEARCH CHARSET us-ascii TEXT foo') {|assert|
|
2746
2890
|
assert.equal("* SEARCH 1 2 3\r\n")
|
2747
2891
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2748
2892
|
}
|
@@ -2752,18 +2896,27 @@ module RIMS::Test
|
|
2752
2896
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2753
2897
|
}
|
2754
2898
|
|
2755
|
-
assert_imap_command('SEARCH CHARSET
|
2899
|
+
assert_imap_command('SEARCH CHARSET us-ascii TEXT baz') {|assert|
|
2756
2900
|
assert.equal("* SEARCH\r\n")
|
2757
2901
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2758
2902
|
}
|
2759
2903
|
|
2760
2904
|
utf8_msg = "\u306F\u306B\u307B"
|
2761
|
-
assert_imap_command("SEARCH CHARSET utf-8 TEXT
|
2905
|
+
assert_imap_command("SEARCH CHARSET utf-8 TEXT #{literal(utf8_msg)}".b) {|assert|
|
2762
2906
|
assert.match(/^\+ /)
|
2763
2907
|
assert.equal("* SEARCH 4 5\r\n")
|
2764
2908
|
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2765
2909
|
}
|
2766
2910
|
|
2911
|
+
assert_imap_command("SEARCH CHARSET euc-jp TEXT #{literal(utf8_msg)}".b) {|assert|
|
2912
|
+
assert.match(/^\+ /)
|
2913
|
+
assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
|
2914
|
+
}
|
2915
|
+
|
2916
|
+
assert_imap_command('SEARCH CHARSET x-nothing TEXT foo') {|assert|
|
2917
|
+
assert.match(/^#{tag} NO \[BADCHARSET \(\S+( \S+)*\)\] unknown charset/)
|
2918
|
+
}
|
2919
|
+
|
2767
2920
|
assert_imap_command('SEARCH CHARSET') {|assert|
|
2768
2921
|
assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
|
2769
2922
|
}
|
@@ -2780,6 +2933,8 @@ module RIMS::Test
|
|
2780
2933
|
assert.match(/^\* BYE /)
|
2781
2934
|
assert.equal("#{tag} OK LOGOUT completed")
|
2782
2935
|
}
|
2936
|
+
|
2937
|
+
assert_imap_closed
|
2783
2938
|
}
|
2784
2939
|
end
|
2785
2940
|
|
@@ -2788,6 +2943,146 @@ module RIMS::Test
|
|
2788
2943
|
test_search_charset_text
|
2789
2944
|
end
|
2790
2945
|
|
2946
|
+
def test_search_charset_skip_encoding_error
|
2947
|
+
imap_decode_engine_evaluate{
|
2948
|
+
if (stream_test?) then
|
2949
|
+
assert_untagged_response{|assert|
|
2950
|
+
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
2951
|
+
}
|
2952
|
+
end
|
2953
|
+
|
2954
|
+
open_mail_store{
|
2955
|
+
add_msg("Content-Type: text/plain\r\n" +
|
2956
|
+
"\r\n" +
|
2957
|
+
"foo")
|
2958
|
+
add_msg("Content-Type: text/plain; charset=iso-2022-jp\r\n" +
|
2959
|
+
"\r\n" +
|
2960
|
+
# utf-8
|
2961
|
+
"\u3053\u3093\u306B\u3061\u306F\r\n" +
|
2962
|
+
"\u3044\u308D\u306F\u306B\u307B\u3078\u3068\r\n" +
|
2963
|
+
"\u3042\u3044\u3046\u3048\u304A\r\n" +
|
2964
|
+
"foo\r\n")
|
2965
|
+
|
2966
|
+
assert_msg_uid(1, 2)
|
2967
|
+
}
|
2968
|
+
|
2969
|
+
if (command_test?) then
|
2970
|
+
assert_equal(false, @decoder.auth?)
|
2971
|
+
assert_equal(false, @decoder.selected?)
|
2972
|
+
end
|
2973
|
+
|
2974
|
+
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
2975
|
+
assert.equal("#{tag} OK LOGIN completed")
|
2976
|
+
}
|
2977
|
+
|
2978
|
+
if (command_test?) then
|
2979
|
+
assert_equal(true, @decoder.auth?)
|
2980
|
+
assert_equal(false, @decoder.selected?)
|
2981
|
+
end
|
2982
|
+
|
2983
|
+
assert_imap_command('SELECT INBOX') {|assert|
|
2984
|
+
assert.skip_while{|line| line =~ /^\* / }
|
2985
|
+
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
2986
|
+
}
|
2987
|
+
|
2988
|
+
if (command_test?) then
|
2989
|
+
assert_equal(true, @decoder.auth?)
|
2990
|
+
assert_equal(true, @decoder.selected?)
|
2991
|
+
end
|
2992
|
+
|
2993
|
+
assert_imap_command('SEARCH CHARSET us-ascii BODY foo') {|assert|
|
2994
|
+
assert.equal("* SEARCH 1\r\n")
|
2995
|
+
assert.equal("#{tag} OK SEARCH completed\r\n")
|
2996
|
+
}
|
2997
|
+
|
2998
|
+
utf8_msg = "\u306F\u306B\u307B"
|
2999
|
+
assert_imap_command("SEARCH CHARSET utf-8 TEXT #{literal(utf8_msg)}".b) {|assert|
|
3000
|
+
assert.match(/^\+ /)
|
3001
|
+
assert.equal("* SEARCH\r\n")
|
3002
|
+
assert.equal("#{tag} OK SEARCH completed\r\n")
|
3003
|
+
}
|
3004
|
+
|
3005
|
+
assert_imap_command('LOGOUT') {|assert|
|
3006
|
+
assert.match(/^\* BYE /)
|
3007
|
+
assert.equal("#{tag} OK LOGOUT completed")
|
3008
|
+
}
|
3009
|
+
|
3010
|
+
assert_imap_closed
|
3011
|
+
}
|
3012
|
+
end
|
3013
|
+
|
3014
|
+
def test_search_charset_skip_encoding_error_stream
|
3015
|
+
use_imap_stream_decode_engine
|
3016
|
+
test_search_charset_skip_encoding_error
|
3017
|
+
end
|
3018
|
+
|
3019
|
+
# skip this test because `EncodingError' is ignored.
|
3020
|
+
def _test_search_interrupt_by_bad_response
|
3021
|
+
imap_decode_engine_evaluate{
|
3022
|
+
if (stream_test?) then
|
3023
|
+
assert_untagged_response{|assert|
|
3024
|
+
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
3025
|
+
}
|
3026
|
+
end
|
3027
|
+
|
3028
|
+
open_mail_store{
|
3029
|
+
@bulk_response_count.times do
|
3030
|
+
add_msg("Content-Type: text/plain\r\n" +
|
3031
|
+
"\r\n" +
|
3032
|
+
"foo")
|
3033
|
+
end
|
3034
|
+
|
3035
|
+
add_msg("Content-Type: text/plain; charset=x-nothing\r\n" +
|
3036
|
+
"\r\n" +
|
3037
|
+
"foo")
|
3038
|
+
|
3039
|
+
assert_msg_uid(*(1..(@bulk_response_count.succ)).to_a)
|
3040
|
+
}
|
3041
|
+
|
3042
|
+
if (command_test?) then
|
3043
|
+
assert_equal(false, @decoder.auth?)
|
3044
|
+
assert_equal(false, @decoder.selected?)
|
3045
|
+
end
|
3046
|
+
|
3047
|
+
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
3048
|
+
assert.equal("#{tag} OK LOGIN completed")
|
3049
|
+
}
|
3050
|
+
|
3051
|
+
if (command_test?) then
|
3052
|
+
assert_equal(true, @decoder.auth?)
|
3053
|
+
assert_equal(false, @decoder.selected?)
|
3054
|
+
end
|
3055
|
+
|
3056
|
+
assert_imap_command('SELECT INBOX') {|assert|
|
3057
|
+
assert.skip_while{|line| line =~ /^\* / }
|
3058
|
+
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
3059
|
+
}
|
3060
|
+
|
3061
|
+
if (command_test?) then
|
3062
|
+
assert_equal(true, @decoder.auth?)
|
3063
|
+
assert_equal(true, @decoder.selected?)
|
3064
|
+
end
|
3065
|
+
|
3066
|
+
assert_imap_command('SEARCH CHARSET utf-8 TEXT foo') {|assert|
|
3067
|
+
assert.match(/\A\* SEARCH( \d+)+\r\n\z/, peek_next_line: true).no_match(/ #{@bulk_response_count.succ}/)
|
3068
|
+
assert.equal("#{tag} BAD internal server error\r\n")
|
3069
|
+
}
|
3070
|
+
|
3071
|
+
assert_imap_command('LOGOUT') {|assert|
|
3072
|
+
assert.match(/^\* BYE /)
|
3073
|
+
assert.equal("#{tag} OK LOGOUT completed")
|
3074
|
+
}
|
3075
|
+
|
3076
|
+
assert_imap_closed
|
3077
|
+
}
|
3078
|
+
end
|
3079
|
+
|
3080
|
+
# skip this test because `EncodingError' is ignored.
|
3081
|
+
def _test_search_interrupt_by_bad_response_stream
|
3082
|
+
use_imap_stream_decode_engine
|
3083
|
+
test_search_interrupt_by_bad_response
|
3084
|
+
end
|
3085
|
+
|
2791
3086
|
def test_fetch
|
2792
3087
|
imap_decode_engine_evaluate{
|
2793
3088
|
if (stream_test?) then
|
@@ -2932,6 +3227,8 @@ module RIMS::Test
|
|
2932
3227
|
assert.match(/^\* BYE /)
|
2933
3228
|
assert.equal("#{tag} OK LOGOUT completed")
|
2934
3229
|
}
|
3230
|
+
|
3231
|
+
assert_imap_closed
|
2935
3232
|
}
|
2936
3233
|
end
|
2937
3234
|
|
@@ -3084,6 +3381,8 @@ module RIMS::Test
|
|
3084
3381
|
assert.match(/^\* BYE /)
|
3085
3382
|
assert.equal("#{tag} OK LOGOUT completed")
|
3086
3383
|
}
|
3384
|
+
|
3385
|
+
assert_imap_closed
|
3087
3386
|
}
|
3088
3387
|
end
|
3089
3388
|
|
@@ -3436,6 +3735,8 @@ module RIMS::Test
|
|
3436
3735
|
assert.match(/^\* BYE /)
|
3437
3736
|
assert.equal("#{tag} OK LOGOUT completed")
|
3438
3737
|
}
|
3738
|
+
|
3739
|
+
assert_imap_closed
|
3439
3740
|
}
|
3440
3741
|
end
|
3441
3742
|
|
@@ -3738,6 +4039,8 @@ module RIMS::Test
|
|
3738
4039
|
assert.match(/^\* BYE /)
|
3739
4040
|
assert.equal("#{tag} OK LOGOUT completed")
|
3740
4041
|
}
|
4042
|
+
|
4043
|
+
assert_imap_closed
|
3741
4044
|
}
|
3742
4045
|
end
|
3743
4046
|
|
@@ -4090,6 +4393,8 @@ module RIMS::Test
|
|
4090
4393
|
assert.match(/^\* BYE /)
|
4091
4394
|
assert.equal("#{tag} OK LOGOUT completed")
|
4092
4395
|
}
|
4396
|
+
|
4397
|
+
assert_imap_closed
|
4093
4398
|
}
|
4094
4399
|
end
|
4095
4400
|
|
@@ -4392,6 +4697,8 @@ module RIMS::Test
|
|
4392
4697
|
assert.match(/^\* BYE /)
|
4393
4698
|
assert.equal("#{tag} OK LOGOUT completed")
|
4394
4699
|
}
|
4700
|
+
|
4701
|
+
assert_imap_closed
|
4395
4702
|
}
|
4396
4703
|
end
|
4397
4704
|
|
@@ -4561,6 +4868,8 @@ module RIMS::Test
|
|
4561
4868
|
assert.match(/^\* BYE /)
|
4562
4869
|
assert.equal("#{tag} OK LOGOUT completed")
|
4563
4870
|
}
|
4871
|
+
|
4872
|
+
assert_imap_closed
|
4564
4873
|
}
|
4565
4874
|
end
|
4566
4875
|
|
@@ -4765,6 +5074,8 @@ module RIMS::Test
|
|
4765
5074
|
assert.match(/^\* BYE /)
|
4766
5075
|
assert.equal("#{tag} OK LOGOUT completed")
|
4767
5076
|
}
|
5077
|
+
|
5078
|
+
assert_imap_closed
|
4768
5079
|
}
|
4769
5080
|
end
|
4770
5081
|
|
@@ -4969,6 +5280,8 @@ module RIMS::Test
|
|
4969
5280
|
assert.match(/^\* BYE /)
|
4970
5281
|
assert.equal("#{tag} OK LOGOUT completed")
|
4971
5282
|
}
|
5283
|
+
|
5284
|
+
assert_imap_closed
|
4972
5285
|
}
|
4973
5286
|
end
|
4974
5287
|
|
@@ -5022,6 +5335,8 @@ module RIMS::Test
|
|
5022
5335
|
assert.match(/^\* BYE /)
|
5023
5336
|
assert.equal("#{tag} OK LOGOUT completed")
|
5024
5337
|
}
|
5338
|
+
|
5339
|
+
assert_imap_closed
|
5025
5340
|
}
|
5026
5341
|
end
|
5027
5342
|
|
@@ -5065,7 +5380,7 @@ module RIMS::Test
|
|
5065
5380
|
}
|
5066
5381
|
|
5067
5382
|
assert_imap_command('SELECT INBOX') {|assert|
|
5068
|
-
assert.skip_while{|line| line =~ /^\* /}
|
5383
|
+
assert.skip_while{|line| line =~ /^\* / }
|
5069
5384
|
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
5070
5385
|
}
|
5071
5386
|
|
@@ -5092,7 +5407,7 @@ module RIMS::Test
|
|
5092
5407
|
}
|
5093
5408
|
|
5094
5409
|
assert_imap_command('EXAMINE INBOX') {|assert|
|
5095
|
-
assert.skip_while{|line| line =~ /^\* /}
|
5410
|
+
assert.skip_while{|line| line =~ /^\* / }
|
5096
5411
|
assert.equal("#{tag} OK [READ-ONLY] EXAMINE completed")
|
5097
5412
|
}
|
5098
5413
|
|
@@ -5114,6 +5429,8 @@ module RIMS::Test
|
|
5114
5429
|
assert_equal(false, @decoder.auth?)
|
5115
5430
|
assert_equal(false, @decoder.selected?)
|
5116
5431
|
end
|
5432
|
+
|
5433
|
+
assert_imap_closed
|
5117
5434
|
}
|
5118
5435
|
end
|
5119
5436
|
|
@@ -5153,7 +5470,7 @@ module RIMS::Test
|
|
5153
5470
|
}
|
5154
5471
|
|
5155
5472
|
assert_imap_command('SELECT INBOX') {|assert|
|
5156
|
-
assert.skip_while{|line| line =~ /^\* /}
|
5473
|
+
assert.skip_while{|line| line =~ /^\* / }
|
5157
5474
|
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
5158
5475
|
}
|
5159
5476
|
|
@@ -5199,7 +5516,7 @@ module RIMS::Test
|
|
5199
5516
|
}
|
5200
5517
|
|
5201
5518
|
assert_imap_command('EXAMINE INBOX') {|assert|
|
5202
|
-
assert.skip_while{|line| line =~ /^\* /}
|
5519
|
+
assert.skip_while{|line| line =~ /^\* / }
|
5203
5520
|
assert.equal("#{tag} OK [READ-ONLY] EXAMINE completed")
|
5204
5521
|
}
|
5205
5522
|
|
@@ -5222,6 +5539,8 @@ module RIMS::Test
|
|
5222
5539
|
assert_equal(false, @decoder.auth?)
|
5223
5540
|
assert_equal(false, @decoder.selected?)
|
5224
5541
|
end
|
5542
|
+
|
5543
|
+
assert_imap_closed
|
5225
5544
|
}
|
5226
5545
|
end
|
5227
5546
|
|
@@ -5231,11 +5550,11 @@ module RIMS::Test
|
|
5231
5550
|
end
|
5232
5551
|
|
5233
5552
|
def test_error_handling_stream
|
5234
|
-
use_imap_stream_decode_engine
|
5553
|
+
use_imap_stream_decode_engine # always run in stream
|
5235
5554
|
imap_decode_engine_evaluate{
|
5236
5555
|
assert_imap_command('') {|assert|
|
5237
5556
|
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
5238
|
-
assert.equal(
|
5557
|
+
assert.equal("#{tag} BAD client command syntax error")
|
5239
5558
|
}
|
5240
5559
|
|
5241
5560
|
assert_imap_command('no_command') {|assert|
|
@@ -5253,6 +5572,30 @@ module RIMS::Test
|
|
5253
5572
|
assert_imap_command('noop detarame') {|assert|
|
5254
5573
|
assert.equal("#{tag} BAD invalid command parameter")
|
5255
5574
|
}
|
5575
|
+
|
5576
|
+
assert_imap_command("APPEND INBOX {#{LITERAL_SIZE_LIMIT + 1}}") {|assert|
|
5577
|
+
assert.equal("#{tag} BAD literal size too large")
|
5578
|
+
}
|
5579
|
+
|
5580
|
+
assert_imap_command("APPEND #{literal('x' * LITERAL_SIZE_LIMIT)} #{'y' * (LINE_LENGTH_LIMIT - 3)}") {|assert|
|
5581
|
+
assert.match(/^\+ /)
|
5582
|
+
assert.equal("#{tag} BAD command size too large") # by last line
|
5583
|
+
}
|
5584
|
+
|
5585
|
+
assert_imap_command("APPEND #{literal('x' * LITERAL_SIZE_LIMIT)} {#{LITERAL_SIZE_LIMIT}}") {|assert|
|
5586
|
+
assert.match(/^\+ /)
|
5587
|
+
assert.equal("#{tag} BAD command size too large") # by last literal
|
5588
|
+
}
|
5589
|
+
|
5590
|
+
@tag = '*T000'
|
5591
|
+
assert_imap_command('noop') {|assert|
|
5592
|
+
assert.equal('* BAD client command syntax error')
|
5593
|
+
}
|
5594
|
+
|
5595
|
+
@tag = '+T000'
|
5596
|
+
assert_imap_command('noop') {|assert|
|
5597
|
+
assert.equal('* BAD client command syntax error')
|
5598
|
+
}
|
5256
5599
|
}
|
5257
5600
|
end
|
5258
5601
|
|
@@ -5284,6 +5627,8 @@ module RIMS::Test
|
|
5284
5627
|
}
|
5285
5628
|
|
5286
5629
|
assert_equal(false, @decoder.auth?) if command_test?
|
5630
|
+
|
5631
|
+
assert_imap_closed
|
5287
5632
|
}
|
5288
5633
|
end
|
5289
5634
|
|
@@ -5440,6 +5785,8 @@ module RIMS::Test
|
|
5440
5785
|
}
|
5441
5786
|
|
5442
5787
|
assert_equal(false, @decoder.auth?) if command_test?
|
5788
|
+
|
5789
|
+
assert_imap_closed
|
5443
5790
|
}
|
5444
5791
|
end
|
5445
5792
|
|
@@ -5498,6 +5845,8 @@ module RIMS::Test
|
|
5498
5845
|
}
|
5499
5846
|
|
5500
5847
|
assert_equal(false, @decoder.auth?) if command_test?
|
5848
|
+
|
5849
|
+
assert_imap_closed
|
5501
5850
|
}
|
5502
5851
|
end
|
5503
5852
|
|
@@ -5580,7 +5929,7 @@ module RIMS::Test
|
|
5580
5929
|
}
|
5581
5930
|
|
5582
5931
|
assert_imap_command('SELECT INBOX') {|assert|
|
5583
|
-
assert.skip_while{|line| line =~ /^\* /}
|
5932
|
+
assert.skip_while{|line| line =~ /^\* / }
|
5584
5933
|
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
5585
5934
|
}
|
5586
5935
|
|
@@ -5604,7 +5953,7 @@ module RIMS::Test
|
|
5604
5953
|
}
|
5605
5954
|
|
5606
5955
|
assert_imap_command('SELECT INBOX') {|assert|
|
5607
|
-
assert.skip_while{|line| line =~ /^\* /}
|
5956
|
+
assert.skip_while{|line| line =~ /^\* / }
|
5608
5957
|
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
5609
5958
|
}
|
5610
5959
|
|
@@ -5628,7 +5977,7 @@ module RIMS::Test
|
|
5628
5977
|
}
|
5629
5978
|
|
5630
5979
|
assert_imap_command('SELECT INBOX') {|assert|
|
5631
|
-
assert.skip_while{|line| line =~ /^\* /}
|
5980
|
+
assert.skip_while{|line| line =~ /^\* / }
|
5632
5981
|
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
5633
5982
|
}
|
5634
5983
|
|
@@ -5656,7 +6005,7 @@ module RIMS::Test
|
|
5656
6005
|
}
|
5657
6006
|
|
5658
6007
|
assert_imap_command('SELECT INBOX') {|assert|
|
5659
|
-
assert.skip_while{|line| line =~ /^\* /}
|
6008
|
+
assert.skip_while{|line| line =~ /^\* / }
|
5660
6009
|
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
5661
6010
|
}
|
5662
6011
|
|
@@ -5689,10 +6038,8 @@ module RIMS::Test
|
|
5689
6038
|
}
|
5690
6039
|
|
5691
6040
|
another_decoder = make_decoder
|
5692
|
-
another_writer = proc{|
|
5693
|
-
|
5694
|
-
p line if $DEBUG
|
5695
|
-
end
|
6041
|
+
another_writer = proc{|response|
|
6042
|
+
p response if $DEBUG
|
5696
6043
|
}
|
5697
6044
|
|
5698
6045
|
another_decoder.login('tag', 'foo', 'open_sesame', &another_writer)
|
@@ -5967,10 +6314,8 @@ module RIMS::Test
|
|
5967
6314
|
}
|
5968
6315
|
|
5969
6316
|
another_decoder = make_decoder
|
5970
|
-
another_writer = proc{|
|
5971
|
-
|
5972
|
-
p line if $DEBUG
|
5973
|
-
end
|
6317
|
+
another_writer = proc{|response|
|
6318
|
+
p response if $DEBUG
|
5974
6319
|
}
|
5975
6320
|
|
5976
6321
|
another_decoder.login('tag', 'foo', 'open_sesame', &another_writer)
|
@@ -6031,6 +6376,232 @@ module RIMS::Test
|
|
6031
6376
|
use_imap_stream_decode_engine
|
6032
6377
|
test_idle_untagged_server_response
|
6033
6378
|
end
|
6379
|
+
|
6380
|
+
def test_charset_aliases
|
6381
|
+
imap_decode_engine_evaluate{
|
6382
|
+
if (stream_test?) then
|
6383
|
+
assert_untagged_response{|assert|
|
6384
|
+
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
6385
|
+
}
|
6386
|
+
end
|
6387
|
+
|
6388
|
+
platform_dependent_character = "\u2460"
|
6389
|
+
open_mail_store{
|
6390
|
+
add_msg("Content-Type: text/plain; charset=iso-2022-jp\r\n" +
|
6391
|
+
"\r\n" +
|
6392
|
+
"#{platform_dependent_character.encode(Encoding::CP50221).b}")
|
6393
|
+
}
|
6394
|
+
|
6395
|
+
if (command_test?) then
|
6396
|
+
assert_equal(false, @decoder.auth?)
|
6397
|
+
assert_equal(false, @decoder.selected?)
|
6398
|
+
end
|
6399
|
+
|
6400
|
+
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
6401
|
+
assert.equal("#{tag} OK LOGIN completed")
|
6402
|
+
}
|
6403
|
+
|
6404
|
+
if (command_test?) then
|
6405
|
+
assert_equal(true, @decoder.auth?)
|
6406
|
+
assert_equal(false, @decoder.selected?)
|
6407
|
+
end
|
6408
|
+
|
6409
|
+
assert_imap_command('SELECT INBOX') {|assert|
|
6410
|
+
assert.skip_while{|line| line =~ /^\* / }
|
6411
|
+
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
6412
|
+
}
|
6413
|
+
|
6414
|
+
if (command_test?) then
|
6415
|
+
assert_equal(true, @decoder.auth?)
|
6416
|
+
assert_equal(true, @decoder.selected?)
|
6417
|
+
end
|
6418
|
+
|
6419
|
+
assert_imap_command("SEARCH CHARSET utf-8 TEXT #{literal(platform_dependent_character)}") {|assert|
|
6420
|
+
assert.match(/^\+ /)
|
6421
|
+
assert.equal("* SEARCH\r\n") # skip by `EncodingError'
|
6422
|
+
assert.equal("#{tag} OK SEARCH completed\r\n")
|
6423
|
+
}
|
6424
|
+
|
6425
|
+
# not recommend changing charset aliases after passing them to the decoder.
|
6426
|
+
# here, the charset aliases are reluctantly changed for testing.
|
6427
|
+
@charset_aliases.add_alias('iso-2022-jp', Encoding::CP50221)
|
6428
|
+
|
6429
|
+
assert_imap_command("SEARCH CHARSET utf-8 TEXT #{literal(platform_dependent_character)}") {|assert|
|
6430
|
+
assert.match(/^\+ /)
|
6431
|
+
assert.equal("* SEARCH 1\r\n") # matched!
|
6432
|
+
assert.equal("#{tag} OK SEARCH completed\r\n")
|
6433
|
+
}
|
6434
|
+
|
6435
|
+
assert_imap_command('CLOSE') {|assert|
|
6436
|
+
assert.equal("#{tag} OK CLOSE completed")
|
6437
|
+
}
|
6438
|
+
|
6439
|
+
if (command_test?) then
|
6440
|
+
assert_equal(true, @decoder.auth?)
|
6441
|
+
assert_equal(false, @decoder.selected?)
|
6442
|
+
end
|
6443
|
+
|
6444
|
+
assert_imap_command('LOGOUT') {|assert|
|
6445
|
+
assert.match(/^\* BYE /)
|
6446
|
+
assert.equal("#{tag} OK LOGOUT completed")
|
6447
|
+
}
|
6448
|
+
|
6449
|
+
if (command_test?) then
|
6450
|
+
assert_equal(false, @decoder.auth?)
|
6451
|
+
assert_equal(false, @decoder.selected?)
|
6452
|
+
end
|
6453
|
+
|
6454
|
+
assert_imap_closed
|
6455
|
+
}
|
6456
|
+
end
|
6457
|
+
|
6458
|
+
def test_charset_aliases_stream
|
6459
|
+
use_imap_stream_decode_engine
|
6460
|
+
test_charset_aliases
|
6461
|
+
end
|
6462
|
+
|
6463
|
+
def test_charset_convert_options
|
6464
|
+
imap_decode_engine_evaluate{
|
6465
|
+
if (stream_test?) then
|
6466
|
+
assert_untagged_response{|assert|
|
6467
|
+
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
6468
|
+
}
|
6469
|
+
end
|
6470
|
+
|
6471
|
+
platform_dependent_character = "\u2460"
|
6472
|
+
open_mail_store{
|
6473
|
+
add_msg("Content-Type: text/plain; charset=iso-2022-jp\r\n" +
|
6474
|
+
"\r\n" +
|
6475
|
+
"#{platform_dependent_character.encode(Encoding::CP50221).b}")
|
6476
|
+
}
|
6477
|
+
|
6478
|
+
if (command_test?) then
|
6479
|
+
assert_equal(false, @decoder.auth?)
|
6480
|
+
assert_equal(false, @decoder.selected?)
|
6481
|
+
end
|
6482
|
+
|
6483
|
+
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
6484
|
+
assert.equal("#{tag} OK LOGIN completed")
|
6485
|
+
}
|
6486
|
+
|
6487
|
+
if (command_test?) then
|
6488
|
+
assert_equal(true, @decoder.auth?)
|
6489
|
+
assert_equal(false, @decoder.selected?)
|
6490
|
+
end
|
6491
|
+
|
6492
|
+
assert_imap_command('SELECT INBOX') {|assert|
|
6493
|
+
assert.skip_while{|line| line =~ /^\* / }
|
6494
|
+
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
6495
|
+
}
|
6496
|
+
|
6497
|
+
if (command_test?) then
|
6498
|
+
assert_equal(true, @decoder.auth?)
|
6499
|
+
assert_equal(true, @decoder.selected?)
|
6500
|
+
end
|
6501
|
+
|
6502
|
+
assert_imap_command(%Q'SEARCH CHARSET utf-8 TEXT #{literal("\uFFFD")}') {|assert|
|
6503
|
+
assert.match(/^\+ /)
|
6504
|
+
assert.equal("* SEARCH\r\n") # skip by `EncodingError'
|
6505
|
+
assert.equal("#{tag} OK SEARCH completed\r\n")
|
6506
|
+
}
|
6507
|
+
|
6508
|
+
# not recommend changing charset convert options after passing them to the decoder.
|
6509
|
+
# here, the options are reluctantly changed for testing.
|
6510
|
+
@charset_convert_options[:undef] = :replace
|
6511
|
+
|
6512
|
+
assert_imap_command("SEARCH CHARSET utf-8 TEXT #{literal("\uFFFD")}") {|assert|
|
6513
|
+
assert.match(/^\+ /)
|
6514
|
+
assert.equal("* SEARCH 1\r\n") # matched!
|
6515
|
+
assert.equal("#{tag} OK SEARCH completed\r\n")
|
6516
|
+
}
|
6517
|
+
|
6518
|
+
assert_imap_command('CLOSE') {|assert|
|
6519
|
+
assert.equal("#{tag} OK CLOSE completed")
|
6520
|
+
}
|
6521
|
+
|
6522
|
+
if (command_test?) then
|
6523
|
+
assert_equal(true, @decoder.auth?)
|
6524
|
+
assert_equal(false, @decoder.selected?)
|
6525
|
+
end
|
6526
|
+
|
6527
|
+
assert_imap_command('LOGOUT') {|assert|
|
6528
|
+
assert.match(/^\* BYE /)
|
6529
|
+
assert.equal("#{tag} OK LOGOUT completed")
|
6530
|
+
}
|
6531
|
+
|
6532
|
+
if (command_test?) then
|
6533
|
+
assert_equal(false, @decoder.auth?)
|
6534
|
+
assert_equal(false, @decoder.selected?)
|
6535
|
+
end
|
6536
|
+
|
6537
|
+
assert_imap_closed
|
6538
|
+
}
|
6539
|
+
end
|
6540
|
+
|
6541
|
+
def test_charset_convert_options_stream
|
6542
|
+
use_imap_stream_decode_engine
|
6543
|
+
test_charset_convert_options
|
6544
|
+
end
|
6545
|
+
|
6546
|
+
def test_command_line_too_long_error_stream
|
6547
|
+
use_imap_stream_decode_engine # always run in stream
|
6548
|
+
imap_decode_engine_evaluate{
|
6549
|
+
assert_untagged_response{|assert|
|
6550
|
+
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
6551
|
+
}
|
6552
|
+
|
6553
|
+
assert_imap_command('APPEND INBOX ' + 'x' * LINE_LENGTH_LIMIT) {|assert|
|
6554
|
+
assert.equal('* BAD line too long')
|
6555
|
+
assert.equal('* BYE server autologout: connection terminated')
|
6556
|
+
}
|
6557
|
+
|
6558
|
+
assert_imap_closed
|
6559
|
+
}
|
6560
|
+
end
|
6561
|
+
|
6562
|
+
def test_authenticate_line_too_long_error_stream
|
6563
|
+
use_imap_stream_decode_engine # always run in stream
|
6564
|
+
imap_decode_engine_evaluate{
|
6565
|
+
assert_untagged_response{|assert|
|
6566
|
+
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
6567
|
+
}
|
6568
|
+
|
6569
|
+
assert_imap_command('AUTHENTICATE plain',
|
6570
|
+
client_input_text: 'x' * LINE_LENGTH_LIMIT + "\r\n") {|assert|
|
6571
|
+
assert.equal('+ ')
|
6572
|
+
assert.equal('* BAD line too long')
|
6573
|
+
assert.equal('* BYE server autologout: connection terminated')
|
6574
|
+
}
|
6575
|
+
|
6576
|
+
assert_imap_closed
|
6577
|
+
}
|
6578
|
+
end
|
6579
|
+
|
6580
|
+
def test_idle_line_too_long_error_stream
|
6581
|
+
use_imap_stream_decode_engine # always run in stream
|
6582
|
+
imap_decode_engine_evaluate{
|
6583
|
+
assert_untagged_response{|assert|
|
6584
|
+
assert.equal("* OK RIMS v#{RIMS::VERSION} IMAP4rev1 service ready.")
|
6585
|
+
}
|
6586
|
+
|
6587
|
+
assert_imap_command('LOGIN foo open_sesame') {|assert|
|
6588
|
+
assert.equal("#{tag} OK LOGIN completed")
|
6589
|
+
}
|
6590
|
+
|
6591
|
+
assert_imap_command('SELECT INBOX') {|assert|
|
6592
|
+
assert.skip_while{|line| line =~ /^\* / }
|
6593
|
+
assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
|
6594
|
+
}
|
6595
|
+
|
6596
|
+
assert_imap_command('IDLE', client_input_text: 'DONE' + ' ' * LINE_LENGTH_LIMIT + "\r\n") {|assert|
|
6597
|
+
assert.match(/^\+ /)
|
6598
|
+
assert.equal('* BAD line too long')
|
6599
|
+
assert.equal('* BYE server autologout: connection terminated')
|
6600
|
+
}
|
6601
|
+
|
6602
|
+
assert_imap_closed
|
6603
|
+
}
|
6604
|
+
end
|
6034
6605
|
end
|
6035
6606
|
|
6036
6607
|
class ProtocolMailDeliveryDecoderTest < Test::Unit::TestCase
|
@@ -6053,6 +6624,93 @@ module RIMS::Test
|
|
6053
6624
|
assert_equal(%w[ foo INBOX ], RIMS::Protocol::Decoder.decode_delivery_target_mailbox(encoded_mbox_name))
|
6054
6625
|
end
|
6055
6626
|
end
|
6627
|
+
|
6628
|
+
class ProtocolDecoderBulkResponseTest < Test::Unit::TestCase
|
6629
|
+
def setup
|
6630
|
+
limit_count = 10
|
6631
|
+
limit_size = 100
|
6632
|
+
@res = RIMS::Protocol::Decoder::BulkResponse.new(limit_count, limit_size)
|
6633
|
+
end
|
6634
|
+
|
6635
|
+
data('empty' => [ 0, 0, [] ],
|
6636
|
+
'1' => [ 1, 3, %w[ foo ] ],
|
6637
|
+
'2' => [ 2, 6, %w[ foo bar ] ],
|
6638
|
+
'3' => [ 3, 11, %w[ foo bar baaaz ] ])
|
6639
|
+
def test_add(data)
|
6640
|
+
expected_count, expected_size, response_list = data
|
6641
|
+
|
6642
|
+
assert_equal(0, @res.count)
|
6643
|
+
assert_equal(0, @res.size)
|
6644
|
+
|
6645
|
+
for response in response_list
|
6646
|
+
@res << response
|
6647
|
+
end
|
6648
|
+
|
6649
|
+
assert_equal(expected_count, @res.count)
|
6650
|
+
assert_equal(expected_size, @res.size)
|
6651
|
+
end
|
6652
|
+
|
6653
|
+
def test_emtpy?
|
6654
|
+
assert_true(@res.empty?)
|
6655
|
+
end
|
6656
|
+
|
6657
|
+
def test_not_empty?
|
6658
|
+
@res << 'foo'
|
6659
|
+
assert_false(@res.empty?)
|
6660
|
+
end
|
6661
|
+
|
6662
|
+
data('count: boundary' => %w[ 1 2 3 4 5 6 7 8 9 0 ],
|
6663
|
+
'count: over' => %w[ 1 2 3 4 5 6 7 8 9 0 a ],
|
6664
|
+
'size: boundary' => [ 'x' * 50, 'y' * 50 ],
|
6665
|
+
'size: over' => [ 'x' * 50, 'y' * 50, 'z' ],
|
6666
|
+
'count,size: boundary' => %w[ 1 2 3 4 5 6 7 8 9 0 ].map{|s| s * 10 },
|
6667
|
+
'count,size: over' => %w[ 1 2 3 4 5 6 7 8 9 0 ].map{|s| s * 10 } + %w[ a ])
|
6668
|
+
def test_full?(data)
|
6669
|
+
response_list = data
|
6670
|
+
for response in response_list
|
6671
|
+
@res << response
|
6672
|
+
end
|
6673
|
+
assert_true(@res.full?)
|
6674
|
+
end
|
6675
|
+
|
6676
|
+
data('empty' => [],
|
6677
|
+
'under' => %w[ foo bar baz ],
|
6678
|
+
'count: boundary' => %w[ 1 2 3 4 5 6 7 8 9 ],
|
6679
|
+
'size: boundary' => [ 'x' * 50, 'y' * 49 ])
|
6680
|
+
def test_not_full?(data)
|
6681
|
+
response_list = data
|
6682
|
+
for response in response_list
|
6683
|
+
@res << response
|
6684
|
+
end
|
6685
|
+
assert_false(@res.full?)
|
6686
|
+
end
|
6687
|
+
|
6688
|
+
def test_flush
|
6689
|
+
@res << 'foo'
|
6690
|
+
@res << 'bar'
|
6691
|
+
r1 = @res.flush
|
6692
|
+
assert_equal('foo' + 'bar', r1.join(''), 'responses may be joined.')
|
6693
|
+
assert_true(@res.empty?)
|
6694
|
+
assert_false(@res.full?)
|
6695
|
+
|
6696
|
+
@res << 'baz'
|
6697
|
+
r2 = @res.flush
|
6698
|
+
assert_equal('baz', r2.join(''), 'responses may be joined.')
|
6699
|
+
assert_true(@res.empty?)
|
6700
|
+
assert_false(@res.full?)
|
6701
|
+
|
6702
|
+
assert_not_equal(r1, r2)
|
6703
|
+
end
|
6704
|
+
|
6705
|
+
def test_flush_joined
|
6706
|
+
for c in ('a'..).first(10)
|
6707
|
+
@res << c
|
6708
|
+
end
|
6709
|
+
assert_equal([ ('a'..).first(10).join('') ], @res.flush)
|
6710
|
+
assert_true(@res.empty?)
|
6711
|
+
assert_false(@res.full?)
|
6712
|
+
end
|
6713
|
+
end
|
6056
6714
|
end
|
6057
6715
|
|
6058
6716
|
# Local Variables:
|