rims-rfc822 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0825e7fac6f422946c68301c42abcce200e31d32a96ed83d6b1879a5a2b7c6cf'
4
- data.tar.gz: '091affd6b8394475774ea160b56eb870f01785f72c1b737ea41fe4a5c6698d82'
3
+ metadata.gz: 6d5fb16811b51a21112bde75cf3afb370097c69205b0351847382a19debeaac9
4
+ data.tar.gz: c7a0b7ee568f34e324f2fe3cef2db7908346a09ab7c9131fc6ae96bdd39c06e0
5
5
  SHA512:
6
- metadata.gz: 210d959c67edec519382dfcb24e7aa1069a93e8da0b001badff3c8e643b2aaf83c5a0f84e54f0354fe1740e86b4a2467f5c5f503420fd6e2b2e89b15c0585dc7
7
- data.tar.gz: ad09d49a4f5caab505893a90e5c309d3d2878178aa73dcec2784fbbf38ad24ac5028710c3f62ece160bc7ccbbbdbf1969fe70c38ae13d1a322f0a99cad5e1cd3
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.each do |name, value|
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 << $& if $&
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.sub!(/\A./, '') and dst_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.sub!(/\A./, '') && dst_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.sub!(/\A./, '')
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'(?<name>\S+?) \s* = \s* (?: (?<quoted_string>".*?") | (?<token>\S+?) ) \s* (?:;|\Z)'x) do
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
- [ 'application'.dup.force_encoding(type_txt.encoding).freeze,
143
- 'octet-stream'.dup.force_encoding(type_txt.encoding).freeze,
144
- params
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>\S.*?) \s* : (?<group_list>.*?) ;
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( nil, nil, unquote_phrase(display_name), nil).freeze
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]+) \s* @ \s* (?<domain>[^<>@",\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>\S.*?)
252
+ (?<display_name> \S.*? )
227
253
  \s*
228
254
  <
229
255
  \s*
230
256
  (?:
231
- (?<route>@[^<>@",]* (?:, \s* @[^<>@",]*)*)
257
+ (?<route>
258
+ @[^<>@",]*
259
+ (?:
260
+ , \s*
261
+ @[^<>@",]*
262
+ )*
263
+ )
232
264
  \s*
233
265
  :
234
266
  )?
235
267
  \s*
236
- (?<local_part>[^<>@",\s]+) \s* @ \s* (?<domain>[^<>@",\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!(decode_charset_encoding, charset_convert_options)
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
- def each
513
+ # API methods
514
+
515
+ def [](name)
482
516
  setup_header
483
- return enum_for(:each) unless block_given?
484
- for name, value in @field_list
485
- yield(name, value)
517
+ if (value_list = @field_table[name.downcase]) then
518
+ value_list[0]
486
519
  end
487
- self
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 [](name)
553
+ def keys
501
554
  setup_header
502
- if (value_list = @field_table[name.downcase]) then
503
- value_list[0]
504
- end
555
+ @field_table.keys
505
556
  end
506
557
 
507
- def fetch_upcase(name)
558
+ def each_key
508
559
  setup_header
509
- if (value_list = @field_table[name.downcase]) then
510
- if (value = value_list[0]) then
511
- value.upcase
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 field_value_list(name)
567
+ def each_pair
517
568
  setup_header
518
- @field_table[name.downcase]
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 (header.key? 'Content-Disposition') then
639
- @content_disposition ||= Parse.parse_content_disposition(header['Content-Disposition'])
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
- if (type = content_disposition) then
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 (header.key? 'Content-Language') then
675
- if (@content_language.nil?) then
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
- if (tag_list = content_language) then
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 (multipart?) then
707
- if (@parts.nil?) then
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
- @message ||= Message.new(body.raw_source)
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 (header.key? 'Date') then
733
- if (@date.nil?) then
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.gsub('-', '_')
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) }
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RIMS
4
4
  module RFC822
5
- VERSION = '0.2.1'
5
+ VERSION = '0.2.2'
6
6
  end
7
7
  end
8
8
 
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.1
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-14 00:00:00.000000000 Z
11
+ date: 2019-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler