rims-rfc822 0.2.1 → 0.2.2
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/README.md +6 -1
- data/lib/rims/rfc822.rb +115 -55
- data/lib/rims/rfc822/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d5fb16811b51a21112bde75cf3afb370097c69205b0351847382a19debeaac9
|
4
|
+
data.tar.gz: c7a0b7ee568f34e324f2fe3cef2db7908346a09ab7c9131fc6ae96bdd39c06e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f4e32a989c3f2d49a304133eba4109d6f058eca263bcf4c593ee81aafce43ef54aae91bd74f8e0cba9dd571c5c4892a0dcfe2b31b4d96cedd4adfe6574509ca
|
7
|
+
data.tar.gz: 67c9fccdca18ccb61c91f5c416e650a7525de89827654173fd9cc09f403190a5cd586d2eac7934be73080956499be2bdf373f8251a7b79504e513a641d263d50
|
data/README.md
CHANGED
@@ -37,8 +37,13 @@ p msg.body
|
|
37
37
|
p msg.header[name]
|
38
38
|
p msg.header.fetch_upcase(name)
|
39
39
|
p msg.header.field_value_list(name)
|
40
|
+
p msg.header.empty?
|
40
41
|
p msg.header.key? name
|
41
|
-
msg.header.
|
42
|
+
p msg.header.keys
|
43
|
+
msg.header.each_key do |name|
|
44
|
+
p name
|
45
|
+
end
|
46
|
+
msg.header.each_pair do |name, value|
|
42
47
|
p [ name, value ]
|
43
48
|
end
|
44
49
|
|
data/lib/rims/rfc822.rb
CHANGED
@@ -10,7 +10,7 @@ module RIMS
|
|
10
10
|
def split_message(msg_txt)
|
11
11
|
header_txt, body_txt = msg_txt.lstrip.split(/\r?\n\r?\n/, 2)
|
12
12
|
if ($&) then
|
13
|
-
header_txt << $&
|
13
|
+
header_txt << $&
|
14
14
|
else
|
15
15
|
body_txt = header_txt
|
16
16
|
header_txt = nil
|
@@ -57,7 +57,10 @@ module RIMS
|
|
57
57
|
when '('
|
58
58
|
state = :comment
|
59
59
|
when "\\"
|
60
|
-
src_txt.
|
60
|
+
unless (src_txt.empty?) then
|
61
|
+
dst_txt << src_txt[0]
|
62
|
+
src_txt[0] = ''
|
63
|
+
end
|
61
64
|
else
|
62
65
|
dst_txt << match_txt
|
63
66
|
end
|
@@ -66,7 +69,10 @@ module RIMS
|
|
66
69
|
when '"'
|
67
70
|
state = :raw
|
68
71
|
when "\\"
|
69
|
-
src_txt.
|
72
|
+
unless (src_txt.empty?) then
|
73
|
+
dst_txt << src_txt[0]
|
74
|
+
src_txt[0] = ''
|
75
|
+
end
|
70
76
|
else
|
71
77
|
dst_txt << match_txt
|
72
78
|
end
|
@@ -75,7 +81,7 @@ module RIMS
|
|
75
81
|
when ')'
|
76
82
|
state = :raw
|
77
83
|
when "\\"
|
78
|
-
src_txt
|
84
|
+
src_txt[0] = ''
|
79
85
|
else
|
80
86
|
# ignore comment text.
|
81
87
|
end
|
@@ -90,7 +96,16 @@ module RIMS
|
|
90
96
|
|
91
97
|
def parse_parameters(parameters_txt)
|
92
98
|
params = {}
|
93
|
-
parameters_txt.scan(%r
|
99
|
+
parameters_txt.scan(%r{
|
100
|
+
(?<name> \S+? )
|
101
|
+
\s* = \s*
|
102
|
+
(?:
|
103
|
+
(?<quoted_string> ".*?" ) |
|
104
|
+
(?<token> \S+? )
|
105
|
+
)
|
106
|
+
\s*
|
107
|
+
(?: ; | \Z )
|
108
|
+
}x) do
|
94
109
|
name = $~[:name]
|
95
110
|
if ($~[:quoted_string]) then
|
96
111
|
quoted_value = $~[:quoted_string]
|
@@ -139,9 +154,18 @@ module RIMS
|
|
139
154
|
end
|
140
155
|
end
|
141
156
|
|
142
|
-
|
143
|
-
|
144
|
-
|
157
|
+
# See RFC2045 / 5.2. Content-Type Defaults
|
158
|
+
# <https://tools.ietf.org/html/rfc2045#section-5.2>
|
159
|
+
#
|
160
|
+
# Default RFC 822 messages without a MIME Content-Type header are taken
|
161
|
+
# by this protocol to be plain text in the US-ASCII character set,
|
162
|
+
# which can be explicitly specified as:
|
163
|
+
#
|
164
|
+
# Content-type: text/plain; charset=us-ascii
|
165
|
+
#
|
166
|
+
[ 'text'.dup.force_encoding(type_txt.encoding).freeze,
|
167
|
+
'plain'.dup.force_encoding(type_txt.encoding).freeze,
|
168
|
+
params # default is no charset, it will be `ASCII-8BIT'.
|
145
169
|
].freeze
|
146
170
|
end
|
147
171
|
module_function :parse_content_type
|
@@ -201,20 +225,22 @@ module RIMS
|
|
201
225
|
if (src_txt.sub!(%r{
|
202
226
|
\A
|
203
227
|
\s*
|
204
|
-
(?<display_name
|
228
|
+
(?<display_name> \S.*? ) \s* : (?<group_list> .*? ) ;
|
205
229
|
\s*
|
206
230
|
,?
|
207
231
|
}x, ''))
|
208
232
|
then
|
209
233
|
display_name = $~[:display_name]
|
210
234
|
group_list = $~[:group_list]
|
211
|
-
addr_list << Address.new(
|
235
|
+
addr_list << Address.new(nil, nil, unquote_phrase(display_name), nil).freeze
|
212
236
|
addr_list.concat(parse_mail_address_list(group_list))
|
213
237
|
addr_list << Address.new(nil, nil, nil, nil).freeze
|
214
238
|
elsif (src_txt.sub!(%r{
|
215
239
|
\A
|
216
240
|
\s*
|
217
|
-
(?<local_part>[^<>@",\s]+
|
241
|
+
(?<local_part> [^<>@",\s]+ )
|
242
|
+
\s* @ \s*
|
243
|
+
(?<domain> [^<>@",\s]+ )
|
218
244
|
\s*
|
219
245
|
,?
|
220
246
|
}x, ''))
|
@@ -223,17 +249,25 @@ module RIMS
|
|
223
249
|
elsif (src_txt.sub!(%r{
|
224
250
|
\A
|
225
251
|
\s*
|
226
|
-
(?<display_name
|
252
|
+
(?<display_name> \S.*? )
|
227
253
|
\s*
|
228
254
|
<
|
229
255
|
\s*
|
230
256
|
(?:
|
231
|
-
(?<route
|
257
|
+
(?<route>
|
258
|
+
@[^<>@",]*
|
259
|
+
(?:
|
260
|
+
, \s*
|
261
|
+
@[^<>@",]*
|
262
|
+
)*
|
263
|
+
)
|
232
264
|
\s*
|
233
265
|
:
|
234
266
|
)?
|
235
267
|
\s*
|
236
|
-
(?<local_part>[^<>@",\s]+
|
268
|
+
(?<local_part> [^<>@",\s]+ )
|
269
|
+
\s* @ \s*
|
270
|
+
(?<domain> [^<>@",\s]+ )
|
237
271
|
\s*
|
238
272
|
>
|
239
273
|
\s*
|
@@ -402,7 +436,7 @@ module RIMS
|
|
402
436
|
# run the slow `String#encode' only when really needed
|
403
437
|
# because of a premise that the strings other than
|
404
438
|
# encoded words are ASCII only.
|
405
|
-
foreword.encode!(
|
439
|
+
foreword.encode!(dst.encoding, charset_convert_options)
|
406
440
|
end
|
407
441
|
dst << foreword
|
408
442
|
end
|
@@ -449,8 +483,6 @@ module RIMS
|
|
449
483
|
end
|
450
484
|
|
451
485
|
class Header
|
452
|
-
include Enumerable
|
453
|
-
|
454
486
|
def initialize(header_txt)
|
455
487
|
@raw_source = header_txt
|
456
488
|
@field_list = nil
|
@@ -464,7 +496,7 @@ module RIMS
|
|
464
496
|
@field_list = Parse.parse_header(@raw_source)
|
465
497
|
@field_table = {}
|
466
498
|
for name, value in @field_list
|
467
|
-
key = name.downcase
|
499
|
+
key = name.downcase.freeze
|
468
500
|
@field_table[key] = [] unless (@field_table.key? key)
|
469
501
|
@field_table[key] << value
|
470
502
|
end
|
@@ -478,13 +510,34 @@ module RIMS
|
|
478
510
|
end
|
479
511
|
private :setup_header
|
480
512
|
|
481
|
-
|
513
|
+
# API methods
|
514
|
+
|
515
|
+
def [](name)
|
482
516
|
setup_header
|
483
|
-
|
484
|
-
|
485
|
-
yield(name, value)
|
517
|
+
if (value_list = @field_table[name.downcase]) then
|
518
|
+
value_list[0]
|
486
519
|
end
|
487
|
-
|
520
|
+
end
|
521
|
+
|
522
|
+
def fetch_upcase(name)
|
523
|
+
setup_header
|
524
|
+
if (value_list = @field_table[name.downcase]) then
|
525
|
+
value_list[0].upcase
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
def field_value_list(name)
|
530
|
+
setup_header
|
531
|
+
@field_table[name.downcase]
|
532
|
+
end
|
533
|
+
|
534
|
+
# minimal methods like `Hash'
|
535
|
+
|
536
|
+
include Enumerable
|
537
|
+
|
538
|
+
def empty?
|
539
|
+
setup_header
|
540
|
+
@field_list.empty?
|
488
541
|
end
|
489
542
|
|
490
543
|
def key?(name)
|
@@ -497,26 +550,30 @@ module RIMS
|
|
497
550
|
alias include? key?
|
498
551
|
alias member? key?
|
499
552
|
|
500
|
-
def
|
553
|
+
def keys
|
501
554
|
setup_header
|
502
|
-
|
503
|
-
value_list[0]
|
504
|
-
end
|
555
|
+
@field_table.keys
|
505
556
|
end
|
506
557
|
|
507
|
-
def
|
558
|
+
def each_key
|
508
559
|
setup_header
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
end
|
560
|
+
return enum_for(:each_key) unless block_given?
|
561
|
+
@field_table.each_key do |key|
|
562
|
+
yield(key)
|
513
563
|
end
|
564
|
+
self
|
514
565
|
end
|
515
566
|
|
516
|
-
def
|
567
|
+
def each_pair
|
517
568
|
setup_header
|
518
|
-
|
569
|
+
return enum_for(:each_pair) unless block_given?
|
570
|
+
for name, value in @field_list
|
571
|
+
yield(name, value)
|
572
|
+
end
|
573
|
+
self
|
519
574
|
end
|
575
|
+
|
576
|
+
alias each each_pair
|
520
577
|
end
|
521
578
|
|
522
579
|
class Body
|
@@ -609,6 +666,7 @@ module RIMS
|
|
609
666
|
alias media_subtype_upcase media_sub_type_upcase
|
610
667
|
|
611
668
|
def content_type_upcase
|
669
|
+
# not return `nil'
|
612
670
|
content_type.upcase
|
613
671
|
end
|
614
672
|
|
@@ -635,8 +693,10 @@ module RIMS
|
|
635
693
|
end
|
636
694
|
|
637
695
|
def setup_content_disposition
|
638
|
-
if (
|
639
|
-
|
696
|
+
if (@content_disposition.nil?) then
|
697
|
+
if (header.key? 'Content-Disposition') then
|
698
|
+
@content_disposition = Parse.parse_content_disposition(header['Content-Disposition'])
|
699
|
+
end
|
640
700
|
end
|
641
701
|
|
642
702
|
nil
|
@@ -649,9 +709,7 @@ module RIMS
|
|
649
709
|
end
|
650
710
|
|
651
711
|
def content_disposition_upcase
|
652
|
-
|
653
|
-
type.upcase
|
654
|
-
end
|
712
|
+
content_disposition&.upcase
|
655
713
|
end
|
656
714
|
|
657
715
|
def content_disposition_parameter(name)
|
@@ -671,8 +729,8 @@ module RIMS
|
|
671
729
|
alias content_disposition_parameters content_disposition_parameter_list
|
672
730
|
|
673
731
|
def setup_content_language
|
674
|
-
if (
|
675
|
-
if (
|
732
|
+
if (@content_language.nil?) then
|
733
|
+
if (header.key? 'Content-Language') then
|
676
734
|
@content_language = header.field_value_list('Content-Language').map{|tags_txt| Parse.parse_content_language(tags_txt) }
|
677
735
|
@content_language.flatten!
|
678
736
|
@content_language.freeze
|
@@ -689,9 +747,7 @@ module RIMS
|
|
689
747
|
end
|
690
748
|
|
691
749
|
def content_language_upcase
|
692
|
-
|
693
|
-
tag_list.map{|tag| tag.upcase }
|
694
|
-
end
|
750
|
+
content_language&.map{|tag| tag.upcase }
|
695
751
|
end
|
696
752
|
|
697
753
|
def text?
|
@@ -703,8 +759,8 @@ module RIMS
|
|
703
759
|
end
|
704
760
|
|
705
761
|
def parts
|
706
|
-
if (
|
707
|
-
if (
|
762
|
+
if (@parts.nil?) then
|
763
|
+
if (multipart?) then
|
708
764
|
if (boundary = self.boundary) then
|
709
765
|
part_list = Parse.parse_multipart_body(boundary, body.raw_source)
|
710
766
|
@parts = part_list.map{|msg_txt| Message.new(msg_txt) }
|
@@ -713,9 +769,9 @@ module RIMS
|
|
713
769
|
end
|
714
770
|
@parts.freeze
|
715
771
|
end
|
716
|
-
|
717
|
-
@parts
|
718
772
|
end
|
773
|
+
|
774
|
+
@parts
|
719
775
|
end
|
720
776
|
|
721
777
|
def message?
|
@@ -723,14 +779,18 @@ module RIMS
|
|
723
779
|
end
|
724
780
|
|
725
781
|
def message
|
726
|
-
if (message?) then
|
727
|
-
|
782
|
+
if (@message.nil?) then
|
783
|
+
if (message?) then
|
784
|
+
@message = Message.new(body.raw_source)
|
785
|
+
end
|
728
786
|
end
|
787
|
+
|
788
|
+
@message
|
729
789
|
end
|
730
790
|
|
731
791
|
def date
|
732
|
-
if (
|
733
|
-
if (
|
792
|
+
if (@date.nil?) then
|
793
|
+
if (header.key? 'Date') then
|
734
794
|
begin
|
735
795
|
@date = Time.parse(header['Date'])
|
736
796
|
rescue ArgumentError
|
@@ -738,14 +798,14 @@ module RIMS
|
|
738
798
|
end
|
739
799
|
@date.freeze
|
740
800
|
end
|
741
|
-
|
742
|
-
@date
|
743
801
|
end
|
802
|
+
|
803
|
+
@date
|
744
804
|
end
|
745
805
|
|
746
806
|
def mail_address_header_field(field_name)
|
747
807
|
if (header.key? field_name) then
|
748
|
-
ivar_name = '@' + field_name.downcase.
|
808
|
+
ivar_name = '@' + field_name.downcase.tr('-', '_')
|
749
809
|
addr_list = instance_variable_get(ivar_name)
|
750
810
|
if (addr_list.nil?) then
|
751
811
|
addr_list = header.field_value_list(field_name).map{|addr_list_txt| Parse.parse_mail_address_list(addr_list_txt) }
|
data/lib/rims/rfc822/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rims-rfc822
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TOKI Yoshinori
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-07-
|
11
|
+
date: 2019-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|