mms2r 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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