class Mail::ContentTypeField - mail-2.5.4 Documentation

# class Mail::ContentTypeField

### Constants

CAPITALIZED_FIELD
FIELD_NAME

### Public Class Methods

generate_boundary() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 81
    def ContentTypeField.generate_boundary
      "--==_mimepart_#{Mail.random_tag}"
    end

new(value = nil, charset = 'utf-8') click to toggle source
Calls superclass method

    # File lib/mail/fields/content_type_field.rb, line 9
    def initialize(value = nil, charset = 'utf-8')
      self.charset = charset
      if value.class == Array
        @main_type = value[0]
        @sub_type = value[1]
        @parameters = ParameterHash.new.merge!(value.last)
      else
        @main_type = nil
        @sub_type = nil
        @parameters = nil
        value = strip_field(FIELD_NAME, value)
      end
      ensure_filename_quoted(value)
      super(CAPITALIZED_FIELD, value, charset)
      self.parse
      self
    end

with_boundary(type) click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 77
    def ContentTypeField.with_boundary(type)
      new("#{type}; boundary=#{generate_boundary}")
    end

### Public Instance Methods

attempt_to_clean() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 43
    def attempt_to_clean
      # Sanitize the value, handle special cases
      @element ||= Mail::ContentTypeElement.new(sanatize(value))
    rescue
      # All else fails, just get the MIME media type
      @element ||= Mail::ContentTypeElement.new(get_mime_type(value))
    end

content_type()
Alias for: string
decoded() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 119
    def decoded
      if parameters.length > 0
        p = "; #{parameters.decoded}"
      else
        p = ""
      end
      "#{content_type}" + p
    end

default() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 63
    def default
      decoded
    end

element() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 35
    def element
      begin
        @element ||= Mail::ContentTypeElement.new(value)
      rescue
        attempt_to_clean
      end
    end

encoded() click to toggle source

TODO: Fix this up

    # File lib/mail/fields/content_type_field.rb, line 110
    def encoded
      if parameters.length > 0
        p = ";\r\n\s#{parameters.encoded}"
      else
        p = ""
      end
      "#{CAPITALIZED_FIELD}: #{content_type}#{p}\r\n"
    end

filename() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 97
    def filename
      case
      when parameters['filename']
        @filename = parameters['filename']
      when parameters['name']
        @filename = parameters['name']
      else
        @filename = nil
      end
      @filename
    end

main_type() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 51
    def main_type
      @main_type ||= element.main_type
    end

parameters() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 69
    def parameters
      unless @parameters
        @parameters = ParameterHash.new
        element.parameters.each { |p| @parameters.merge!(p) }
      end
      @parameters
    end

parse(val = value) click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 27
    def parse(val = value)
      unless val.blank?
        self.value = val
        @element = nil
        element
      end
    end

string() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 59
    def string
      "#{main_type}/#{sub_type}"
    end

Also aliased as: content_type
stringify(params) click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 93
    def stringify(params)
      params.map { |k,v| "#{k}=#{Encodings.param_encode(v)}" }.join("; ")
    end

sub_type() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 55
    def sub_type
      @sub_type ||= element.sub_type
    end

value() click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 85
    def value
      if @value.class == Array
        "#{@main_type}/#{@sub_type}; #{stringify(parameters)}"
      else
        @value
      end
    end

### Private Instance Methods

get_mime_type( val ) click to toggle source

    # File lib/mail/fields/content_type_field.rb, line 191
    def get_mime_type( val )
      case
      when val =~ /^([\w\-]+)\/([\w\-]+);.+$/i
        "#{$1}/#{$2}"
      else
        'text/plain'
      end
    end

method_missing(name, *args, &block) click to toggle source
Calls superclass method

    # File lib/mail/fields/content_type_field.rb, line 130
    def method_missing(name, *args, &block)
      if name.to_s =~ /(\w+)=/
        self.parameters[$1] = args.first
        @value = "#{content_type}; #{stringify(parameters)}"
      else
        super
      end
    end

sanatize( val ) click to toggle source

Various special cases from random emails found that I am not going to change the parser for

    # File lib/mail/fields/content_type_field.rb, line 141
    def sanatize( val )

      # TODO: check if there are cases where whitespace is not a separator
      val = val.
        gsub(/\s*=\s*/,'='). # remove whitespaces around equal sign
        tr(' ',';').
        squeeze(';').
        gsub(';', '; '). #use '; ' as a separator (or EOL)
        gsub(/;\s*$/,'') #remove trailing to keep examples below

      if val =~ /(boundary=(\S*))/i
        val = "#{$`.downcase}boundary=#{$2}#{$'.downcase}"
      else
        val.downcase!
      end

      case
      when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;;+(.*)$/i
        # Handles 'text/plain;; format="flowed"' (double semi colon)
        "#{$1}/#{$2}; #{$3}"
      when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
        # Microsoft helper:
        # Handles 'type/subtype;ISO-8559-1'
        "#{$1}/#{$2}; charset=#{quote_atom($3)}"
      when val.chomp =~ /^text;?$/i
        # Handles 'text;' and 'text'
        "text/plain;"
      when val.chomp =~ /^(\w+);\s(.*)$/i
        # Handles 'text; <parameters>'
        "text/plain; #{$2}"
      when val =~ /([\w\-]+\/[\w\-]+);\scharset="charset="(\w+)""/i
        # Handles text/html; charset="charset="GB2312""
        "#{$1}; charset=#{quote_atom($2)}"
      when val =~ /([\w\-]+\/[\w\-]+);\s+(.*)/i
        type = $1
        # Handles misquoted param values
        # e.g: application/octet-stream; name=archiveshelp1[1].htm
        # and: audio/x-midi;\r\n\sname=Part .exe
        params = $2.to_s.split(/\s+/)
        params = params.map { |i| i.to_s.chomp.strip }
        params = params.map { |i| i.split(/\s*\=\s*/) }
        params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
        "#{type}; #{params}"
      when val =~ /^\s*$/
        'text/plain'
      else
        ''
      end
    end