mms2r 1.0.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.
Files changed (55) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +54 -0
  3. data/README.txt +81 -0
  4. data/Rakefile +30 -0
  5. data/conf/mms2r_cingularmedia_transform.yml +6 -0
  6. data/conf/mms2r_sprintmedia_ignore.yml +10 -0
  7. data/conf/mms2r_tmobilemedia_ignore.yml +17 -0
  8. data/conf/mms2r_verizonmedia_ignore.yml +3 -0
  9. data/lib/mms2r.rb +3 -0
  10. data/lib/mms2r/cingular_media.rb +11 -0
  11. data/lib/mms2r/media.rb +345 -0
  12. data/lib/mms2r/mmode_media.rb +13 -0
  13. data/lib/mms2r/sprint_media.rb +50 -0
  14. data/lib/mms2r/tmobile_media.rb +11 -0
  15. data/lib/mms2r/verizon_media.rb +11 -0
  16. data/lib/mms2r/version.rb +12 -0
  17. data/lib/vendor/text/format.rb +1466 -0
  18. data/lib/vendor/tmail.rb +3 -0
  19. data/lib/vendor/tmail/address.rb +242 -0
  20. data/lib/vendor/tmail/attachments.rb +39 -0
  21. data/lib/vendor/tmail/base64.rb +71 -0
  22. data/lib/vendor/tmail/config.rb +69 -0
  23. data/lib/vendor/tmail/encode.rb +467 -0
  24. data/lib/vendor/tmail/facade.rb +552 -0
  25. data/lib/vendor/tmail/header.rb +914 -0
  26. data/lib/vendor/tmail/info.rb +35 -0
  27. data/lib/vendor/tmail/loader.rb +1 -0
  28. data/lib/vendor/tmail/mail.rb +447 -0
  29. data/lib/vendor/tmail/mailbox.rb +433 -0
  30. data/lib/vendor/tmail/mbox.rb +1 -0
  31. data/lib/vendor/tmail/net.rb +280 -0
  32. data/lib/vendor/tmail/obsolete.rb +135 -0
  33. data/lib/vendor/tmail/parser.rb +1522 -0
  34. data/lib/vendor/tmail/port.rb +377 -0
  35. data/lib/vendor/tmail/quoting.rb +131 -0
  36. data/lib/vendor/tmail/scanner.rb +41 -0
  37. data/lib/vendor/tmail/scanner_r.rb +263 -0
  38. data/lib/vendor/tmail/stringio.rb +277 -0
  39. data/lib/vendor/tmail/tmail.rb +1 -0
  40. data/lib/vendor/tmail/utils.rb +238 -0
  41. data/test/files/dot.jpg +0 -0
  42. data/test/files/sprint-image-01.mail +195 -0
  43. data/test/files/sprint-text-01.mail +8 -0
  44. data/test/files/sprint-video-01.mail +195 -0
  45. data/test/files/sprint.mov +0 -0
  46. data/test/files/verizon-image-01.mail +815 -0
  47. data/test/files/verizon-text-01.mail +11 -0
  48. data/test/files/verizon-video-01.mail +336 -0
  49. data/test/test_mms2r_cingular.rb +52 -0
  50. data/test/test_mms2r_media.rb +311 -0
  51. data/test/test_mms2r_mmode.rb +52 -0
  52. data/test/test_mms2r_sprint.rb +154 -0
  53. data/test/test_mms2r_tmobile.rb +169 -0
  54. data/test/test_mms2r_verizon.rb +74 -0
  55. metadata +130 -0
@@ -0,0 +1,914 @@
1
+ #
2
+ # header.rb
3
+ #
4
+ #--
5
+ # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ #
26
+ # Note: Originally licensed under LGPL v2+. Using MIT license for Rails
27
+ # with permission of Minero Aoki.
28
+ #++
29
+
30
+ require 'tmail/encode'
31
+ require 'tmail/address'
32
+ require 'tmail/parser'
33
+ require 'tmail/config'
34
+ require 'tmail/utils'
35
+
36
+
37
+ module TMail
38
+
39
+ class HeaderField
40
+
41
+ include TextUtils
42
+
43
+ class << self
44
+
45
+ alias newobj new
46
+
47
+ def new( name, body, conf = DEFAULT_CONFIG )
48
+ klass = FNAME_TO_CLASS[name.downcase] || UnstructuredHeader
49
+ klass.newobj body, conf
50
+ end
51
+
52
+ def new_from_port( port, name, conf = DEFAULT_CONFIG )
53
+ re = Regep.new('\A(' + Regexp.quote(name) + '):', 'i')
54
+ str = nil
55
+ port.ropen {|f|
56
+ f.each do |line|
57
+ if m = re.match(line) then str = m.post_match.strip
58
+ elsif str and /\A[\t ]/ === line then str << ' ' << line.strip
59
+ elsif /\A-*\s*\z/ === line then break
60
+ elsif str then break
61
+ end
62
+ end
63
+ }
64
+ new(name, str, Config.to_config(conf))
65
+ end
66
+
67
+ def internal_new( name, conf )
68
+ FNAME_TO_CLASS[name].newobj('', conf, true)
69
+ end
70
+
71
+ end # class << self
72
+
73
+ def initialize( body, conf, intern = false )
74
+ @body = body
75
+ @config = conf
76
+
77
+ @illegal = false
78
+ @parsed = false
79
+ if intern
80
+ @parsed = true
81
+ parse_init
82
+ end
83
+ end
84
+
85
+ def inspect
86
+ "#<#{self.class} #{@body.inspect}>"
87
+ end
88
+
89
+ def illegal?
90
+ @illegal
91
+ end
92
+
93
+ def empty?
94
+ ensure_parsed
95
+ return true if @illegal
96
+ isempty?
97
+ end
98
+
99
+ private
100
+
101
+ def ensure_parsed
102
+ return if @parsed
103
+ @parsed = true
104
+ parse
105
+ end
106
+
107
+ # defabstract parse
108
+ # end
109
+
110
+ def clear_parse_status
111
+ @parsed = false
112
+ @illegal = false
113
+ end
114
+
115
+ public
116
+
117
+ def body
118
+ ensure_parsed
119
+ v = Decoder.new(s = '')
120
+ do_accept v
121
+ v.terminate
122
+ s
123
+ end
124
+
125
+ def body=( str )
126
+ @body = str
127
+ clear_parse_status
128
+ end
129
+
130
+ include StrategyInterface
131
+
132
+ def accept( strategy, dummy1 = nil, dummy2 = nil )
133
+ ensure_parsed
134
+ do_accept strategy
135
+ strategy.terminate
136
+ end
137
+
138
+ # abstract do_accept
139
+
140
+ end
141
+
142
+
143
+ class UnstructuredHeader < HeaderField
144
+
145
+ def body
146
+ ensure_parsed
147
+ @body
148
+ end
149
+
150
+ def body=( arg )
151
+ ensure_parsed
152
+ @body = arg
153
+ end
154
+
155
+ private
156
+
157
+ def parse_init
158
+ end
159
+
160
+ def parse
161
+ @body = Decoder.decode(@body.gsub(/\n|\r\n|\r/, ''))
162
+ end
163
+
164
+ def isempty?
165
+ not @body
166
+ end
167
+
168
+ def do_accept( strategy )
169
+ strategy.text @body
170
+ end
171
+
172
+ end
173
+
174
+
175
+ class StructuredHeader < HeaderField
176
+
177
+ def comments
178
+ ensure_parsed
179
+ @comments
180
+ end
181
+
182
+ private
183
+
184
+ def parse
185
+ save = nil
186
+
187
+ begin
188
+ parse_init
189
+ do_parse
190
+ rescue SyntaxError
191
+ if not save and mime_encoded? @body
192
+ save = @body
193
+ @body = Decoder.decode(save)
194
+ retry
195
+ elsif save
196
+ @body = save
197
+ end
198
+
199
+ @illegal = true
200
+ raise if @config.strict_parse?
201
+ end
202
+ end
203
+
204
+ def parse_init
205
+ @comments = []
206
+ init
207
+ end
208
+
209
+ def do_parse
210
+ obj = Parser.parse(self.class::PARSE_TYPE, @body, @comments)
211
+ set obj if obj
212
+ end
213
+
214
+ end
215
+
216
+
217
+ class DateTimeHeader < StructuredHeader
218
+
219
+ PARSE_TYPE = :DATETIME
220
+
221
+ def date
222
+ ensure_parsed
223
+ @date
224
+ end
225
+
226
+ def date=( arg )
227
+ ensure_parsed
228
+ @date = arg
229
+ end
230
+
231
+ private
232
+
233
+ def init
234
+ @date = nil
235
+ end
236
+
237
+ def set( t )
238
+ @date = t
239
+ end
240
+
241
+ def isempty?
242
+ not @date
243
+ end
244
+
245
+ def do_accept( strategy )
246
+ strategy.meta time2str(@date)
247
+ end
248
+
249
+ end
250
+
251
+
252
+ class AddressHeader < StructuredHeader
253
+
254
+ PARSE_TYPE = :MADDRESS
255
+
256
+ def addrs
257
+ ensure_parsed
258
+ @addrs
259
+ end
260
+
261
+ private
262
+
263
+ def init
264
+ @addrs = []
265
+ end
266
+
267
+ def set( a )
268
+ @addrs = a
269
+ end
270
+
271
+ def isempty?
272
+ @addrs.empty?
273
+ end
274
+
275
+ def do_accept( strategy )
276
+ first = true
277
+ @addrs.each do |a|
278
+ if first
279
+ first = false
280
+ else
281
+ strategy.meta ','
282
+ strategy.space
283
+ end
284
+ a.accept strategy
285
+ end
286
+
287
+ @comments.each do |c|
288
+ strategy.space
289
+ strategy.meta '('
290
+ strategy.text c
291
+ strategy.meta ')'
292
+ end
293
+ end
294
+
295
+ end
296
+
297
+
298
+ class ReturnPathHeader < AddressHeader
299
+
300
+ PARSE_TYPE = :RETPATH
301
+
302
+ def addr
303
+ addrs()[0]
304
+ end
305
+
306
+ def spec
307
+ a = addr() or return nil
308
+ a.spec
309
+ end
310
+
311
+ def routes
312
+ a = addr() or return nil
313
+ a.routes
314
+ end
315
+
316
+ private
317
+
318
+ def do_accept( strategy )
319
+ a = addr()
320
+
321
+ strategy.meta '<'
322
+ unless a.routes.empty?
323
+ strategy.meta a.routes.map {|i| '@' + i }.join(',')
324
+ strategy.meta ':'
325
+ end
326
+ spec = a.spec
327
+ strategy.meta spec if spec
328
+ strategy.meta '>'
329
+ end
330
+
331
+ end
332
+
333
+
334
+ class SingleAddressHeader < AddressHeader
335
+
336
+ def addr
337
+ addrs()[0]
338
+ end
339
+
340
+ private
341
+
342
+ def do_accept( strategy )
343
+ a = addr()
344
+ a.accept strategy
345
+ @comments.each do |c|
346
+ strategy.space
347
+ strategy.meta '('
348
+ strategy.text c
349
+ strategy.meta ')'
350
+ end
351
+ end
352
+
353
+ end
354
+
355
+
356
+ class MessageIdHeader < StructuredHeader
357
+
358
+ def id
359
+ ensure_parsed
360
+ @id
361
+ end
362
+
363
+ def id=( arg )
364
+ ensure_parsed
365
+ @id = arg
366
+ end
367
+
368
+ private
369
+
370
+ def init
371
+ @id = nil
372
+ end
373
+
374
+ def isempty?
375
+ not @id
376
+ end
377
+
378
+ def do_parse
379
+ @id = @body.slice(MESSAGE_ID) or
380
+ raise SyntaxError, "wrong Message-ID format: #{@body}"
381
+ end
382
+
383
+ def do_accept( strategy )
384
+ strategy.meta @id
385
+ end
386
+
387
+ end
388
+
389
+
390
+ class ReferencesHeader < StructuredHeader
391
+
392
+ def refs
393
+ ensure_parsed
394
+ @refs
395
+ end
396
+
397
+ def each_id
398
+ self.refs.each do |i|
399
+ yield i if MESSAGE_ID === i
400
+ end
401
+ end
402
+
403
+ def ids
404
+ ensure_parsed
405
+ @ids
406
+ end
407
+
408
+ def each_phrase
409
+ self.refs.each do |i|
410
+ yield i unless MESSAGE_ID === i
411
+ end
412
+ end
413
+
414
+ def phrases
415
+ ret = []
416
+ each_phrase {|i| ret.push i }
417
+ ret
418
+ end
419
+
420
+ private
421
+
422
+ def init
423
+ @refs = []
424
+ @ids = []
425
+ end
426
+
427
+ def isempty?
428
+ @ids.empty?
429
+ end
430
+
431
+ def do_parse
432
+ str = @body
433
+ while m = MESSAGE_ID.match(str)
434
+ pre = m.pre_match.strip
435
+ @refs.push pre unless pre.empty?
436
+ @refs.push s = m[0]
437
+ @ids.push s
438
+ str = m.post_match
439
+ end
440
+ str = str.strip
441
+ @refs.push str unless str.empty?
442
+ end
443
+
444
+ def do_accept( strategy )
445
+ first = true
446
+ @ids.each do |i|
447
+ if first
448
+ first = false
449
+ else
450
+ strategy.space
451
+ end
452
+ strategy.meta i
453
+ end
454
+ end
455
+
456
+ end
457
+
458
+
459
+ class ReceivedHeader < StructuredHeader
460
+
461
+ PARSE_TYPE = :RECEIVED
462
+
463
+ def from
464
+ ensure_parsed
465
+ @from
466
+ end
467
+
468
+ def from=( arg )
469
+ ensure_parsed
470
+ @from = arg
471
+ end
472
+
473
+ def by
474
+ ensure_parsed
475
+ @by
476
+ end
477
+
478
+ def by=( arg )
479
+ ensure_parsed
480
+ @by = arg
481
+ end
482
+
483
+ def via
484
+ ensure_parsed
485
+ @via
486
+ end
487
+
488
+ def via=( arg )
489
+ ensure_parsed
490
+ @via = arg
491
+ end
492
+
493
+ def with
494
+ ensure_parsed
495
+ @with
496
+ end
497
+
498
+ def id
499
+ ensure_parsed
500
+ @id
501
+ end
502
+
503
+ def id=( arg )
504
+ ensure_parsed
505
+ @id = arg
506
+ end
507
+
508
+ def _for
509
+ ensure_parsed
510
+ @_for
511
+ end
512
+
513
+ def _for=( arg )
514
+ ensure_parsed
515
+ @_for = arg
516
+ end
517
+
518
+ def date
519
+ ensure_parsed
520
+ @date
521
+ end
522
+
523
+ def date=( arg )
524
+ ensure_parsed
525
+ @date = arg
526
+ end
527
+
528
+ private
529
+
530
+ def init
531
+ @from = @by = @via = @with = @id = @_for = nil
532
+ @with = []
533
+ @date = nil
534
+ end
535
+
536
+ def set( args )
537
+ @from, @by, @via, @with, @id, @_for, @date = *args
538
+ end
539
+
540
+ def isempty?
541
+ @with.empty? and not (@from or @by or @via or @id or @_for or @date)
542
+ end
543
+
544
+ def do_accept( strategy )
545
+ list = []
546
+ list.push 'from ' + @from if @from
547
+ list.push 'by ' + @by if @by
548
+ list.push 'via ' + @via if @via
549
+ @with.each do |i|
550
+ list.push 'with ' + i
551
+ end
552
+ list.push 'id ' + @id if @id
553
+ list.push 'for <' + @_for + '>' if @_for
554
+
555
+ first = true
556
+ list.each do |i|
557
+ strategy.space unless first
558
+ strategy.meta i
559
+ first = false
560
+ end
561
+ if @date
562
+ strategy.meta ';'
563
+ strategy.space
564
+ strategy.meta time2str(@date)
565
+ end
566
+ end
567
+
568
+ end
569
+
570
+
571
+ class KeywordsHeader < StructuredHeader
572
+
573
+ PARSE_TYPE = :KEYWORDS
574
+
575
+ def keys
576
+ ensure_parsed
577
+ @keys
578
+ end
579
+
580
+ private
581
+
582
+ def init
583
+ @keys = []
584
+ end
585
+
586
+ def set( a )
587
+ @keys = a
588
+ end
589
+
590
+ def isempty?
591
+ @keys.empty?
592
+ end
593
+
594
+ def do_accept( strategy )
595
+ first = true
596
+ @keys.each do |i|
597
+ if first
598
+ first = false
599
+ else
600
+ strategy.meta ','
601
+ end
602
+ strategy.meta i
603
+ end
604
+ end
605
+
606
+ end
607
+
608
+
609
+ class EncryptedHeader < StructuredHeader
610
+
611
+ PARSE_TYPE = :ENCRYPTED
612
+
613
+ def encrypter
614
+ ensure_parsed
615
+ @encrypter
616
+ end
617
+
618
+ def encrypter=( arg )
619
+ ensure_parsed
620
+ @encrypter = arg
621
+ end
622
+
623
+ def keyword
624
+ ensure_parsed
625
+ @keyword
626
+ end
627
+
628
+ def keyword=( arg )
629
+ ensure_parsed
630
+ @keyword = arg
631
+ end
632
+
633
+ private
634
+
635
+ def init
636
+ @encrypter = nil
637
+ @keyword = nil
638
+ end
639
+
640
+ def set( args )
641
+ @encrypter, @keyword = args
642
+ end
643
+
644
+ def isempty?
645
+ not (@encrypter or @keyword)
646
+ end
647
+
648
+ def do_accept( strategy )
649
+ if @key
650
+ strategy.meta @encrypter + ','
651
+ strategy.space
652
+ strategy.meta @keyword
653
+ else
654
+ strategy.meta @encrypter
655
+ end
656
+ end
657
+
658
+ end
659
+
660
+
661
+ class MimeVersionHeader < StructuredHeader
662
+
663
+ PARSE_TYPE = :MIMEVERSION
664
+
665
+ def major
666
+ ensure_parsed
667
+ @major
668
+ end
669
+
670
+ def major=( arg )
671
+ ensure_parsed
672
+ @major = arg
673
+ end
674
+
675
+ def minor
676
+ ensure_parsed
677
+ @minor
678
+ end
679
+
680
+ def minor=( arg )
681
+ ensure_parsed
682
+ @minor = arg
683
+ end
684
+
685
+ def version
686
+ sprintf('%d.%d', major, minor)
687
+ end
688
+
689
+ private
690
+
691
+ def init
692
+ @major = nil
693
+ @minor = nil
694
+ end
695
+
696
+ def set( args )
697
+ @major, @minor = *args
698
+ end
699
+
700
+ def isempty?
701
+ not (@major or @minor)
702
+ end
703
+
704
+ def do_accept( strategy )
705
+ strategy.meta sprintf('%d.%d', @major, @minor)
706
+ end
707
+
708
+ end
709
+
710
+
711
+ class ContentTypeHeader < StructuredHeader
712
+
713
+ PARSE_TYPE = :CTYPE
714
+
715
+ def main_type
716
+ ensure_parsed
717
+ @main
718
+ end
719
+
720
+ def main_type=( arg )
721
+ ensure_parsed
722
+ @main = arg.downcase
723
+ end
724
+
725
+ def sub_type
726
+ ensure_parsed
727
+ @sub
728
+ end
729
+
730
+ def sub_type=( arg )
731
+ ensure_parsed
732
+ @sub = arg.downcase
733
+ end
734
+
735
+ def content_type
736
+ ensure_parsed
737
+ @sub ? sprintf('%s/%s', @main, @sub) : @main
738
+ end
739
+
740
+ def params
741
+ ensure_parsed
742
+ @params
743
+ end
744
+
745
+ def []( key )
746
+ ensure_parsed
747
+ @params and @params[key]
748
+ end
749
+
750
+ def []=( key, val )
751
+ ensure_parsed
752
+ (@params ||= {})[key] = val
753
+ end
754
+
755
+ private
756
+
757
+ def init
758
+ @main = @sub = @params = nil
759
+ end
760
+
761
+ def set( args )
762
+ @main, @sub, @params = *args
763
+ end
764
+
765
+ def isempty?
766
+ not (@main or @sub)
767
+ end
768
+
769
+ def do_accept( strategy )
770
+ if @sub
771
+ strategy.meta sprintf('%s/%s', @main, @sub)
772
+ else
773
+ strategy.meta @main
774
+ end
775
+ @params.each do |k,v|
776
+ if v
777
+ strategy.meta ';'
778
+ strategy.space
779
+ strategy.kv_pair k, v
780
+ end
781
+ end
782
+ end
783
+
784
+ end
785
+
786
+
787
+ class ContentTransferEncodingHeader < StructuredHeader
788
+
789
+ PARSE_TYPE = :CENCODING
790
+
791
+ def encoding
792
+ ensure_parsed
793
+ @encoding
794
+ end
795
+
796
+ def encoding=( arg )
797
+ ensure_parsed
798
+ @encoding = arg
799
+ end
800
+
801
+ private
802
+
803
+ def init
804
+ @encoding = nil
805
+ end
806
+
807
+ def set( s )
808
+ @encoding = s
809
+ end
810
+
811
+ def isempty?
812
+ not @encoding
813
+ end
814
+
815
+ def do_accept( strategy )
816
+ strategy.meta @encoding.capitalize
817
+ end
818
+
819
+ end
820
+
821
+
822
+ class ContentDispositionHeader < StructuredHeader
823
+
824
+ PARSE_TYPE = :CDISPOSITION
825
+
826
+ def disposition
827
+ ensure_parsed
828
+ @disposition
829
+ end
830
+
831
+ def disposition=( str )
832
+ ensure_parsed
833
+ @disposition = str.downcase
834
+ end
835
+
836
+ def params
837
+ ensure_parsed
838
+ @params
839
+ end
840
+
841
+ def []( key )
842
+ ensure_parsed
843
+ @params and @params[key]
844
+ end
845
+
846
+ def []=( key, val )
847
+ ensure_parsed
848
+ (@params ||= {})[key] = val
849
+ end
850
+
851
+ private
852
+
853
+ def init
854
+ @disposition = @params = nil
855
+ end
856
+
857
+ def set( args )
858
+ @disposition, @params = *args
859
+ end
860
+
861
+ def isempty?
862
+ not @disposition and (not @params or @params.empty?)
863
+ end
864
+
865
+ def do_accept( strategy )
866
+ strategy.meta @disposition
867
+ @params.each do |k,v|
868
+ strategy.meta ';'
869
+ strategy.space
870
+ strategy.kv_pair k, v
871
+ end
872
+ end
873
+
874
+ end
875
+
876
+
877
+ class HeaderField # redefine
878
+
879
+ FNAME_TO_CLASS = {
880
+ 'date' => DateTimeHeader,
881
+ 'resent-date' => DateTimeHeader,
882
+ 'to' => AddressHeader,
883
+ 'cc' => AddressHeader,
884
+ 'bcc' => AddressHeader,
885
+ 'from' => AddressHeader,
886
+ 'reply-to' => AddressHeader,
887
+ 'resent-to' => AddressHeader,
888
+ 'resent-cc' => AddressHeader,
889
+ 'resent-bcc' => AddressHeader,
890
+ 'resent-from' => AddressHeader,
891
+ 'resent-reply-to' => AddressHeader,
892
+ 'sender' => SingleAddressHeader,
893
+ 'resent-sender' => SingleAddressHeader,
894
+ 'return-path' => ReturnPathHeader,
895
+ 'message-id' => MessageIdHeader,
896
+ 'resent-message-id' => MessageIdHeader,
897
+ 'in-reply-to' => ReferencesHeader,
898
+ 'received' => ReceivedHeader,
899
+ 'references' => ReferencesHeader,
900
+ 'keywords' => KeywordsHeader,
901
+ 'encrypted' => EncryptedHeader,
902
+ 'mime-version' => MimeVersionHeader,
903
+ 'content-type' => ContentTypeHeader,
904
+ 'content-transfer-encoding' => ContentTransferEncodingHeader,
905
+ 'content-disposition' => ContentDispositionHeader,
906
+ 'content-id' => MessageIdHeader,
907
+ 'subject' => UnstructuredHeader,
908
+ 'comments' => UnstructuredHeader,
909
+ 'content-description' => UnstructuredHeader
910
+ }
911
+
912
+ end
913
+
914
+ end # module TMail