class MIME::Media::Parser

Parser for MIME::Media

Constants

APP_HTTP

APP_HTTP_RGX = %r{^application/http}.freeze

HMD_RGX
MPS
MP_RGX1
MP_RGX2

Attributes

lines[RW]
target[RW]

Public Class Methods

new() click to toggle source
# File lib/safrano/multipart.rb, line 23
def initialize
  @state = :h
  @lines = []
  @target_hd = {}
  @target_ct = nil
  @sep = CRLF
end

Public Instance Methods

addline(line) click to toggle source
# File lib/safrano/multipart.rb, line 31
def addline(line)
  @lines << line
end
hook_multipart(content_type, boundary) click to toggle source
# File lib/safrano/multipart.rb, line 105
def hook_multipart(content_type, boundary)
  @target_hd[CTT_TYPE_LC] = content_type
  @target_ct = @target_hd[CTT_TYPE_LC]
  @target = multipart_content(boundary)
  @target.hd = @target_hd
  @target.ct = @target_ct
  @state = :bmp
end
multipart_content(boundary) click to toggle source
# File lib/safrano/multipart.rb, line 101
def multipart_content(boundary)
  MIME::Content::Multipart::Base.new(boundary)
end
new_content() click to toggle source
# File lib/safrano/multipart.rb, line 118
def new_content
  @target =
    if @target_ct.start_with?(MPS) &&
       (md = (MP_RGX1.match(@target_ct[10..-1]) || MP_RGX2.match(@target_ct[10..-1])))
      multipart_content(md[2].strip)
    elsif @target_ct.start_with?(APP_HTTP)
      MIME::Content::Application::Http.new
    else
      MIME::Content::Text::Plain.new
    end
  @target.hd.merge! @target_hd
  @target.ct = @target_ct
  @target.level = @level
  @state = @target.is_a?(MIME::Content::Multipart::Base) ? :bmp : :b
end
parse(level: 0) click to toggle source
# File lib/safrano/multipart.rb, line 87
def parse(level: 0)
  @level = level
  return unless @lines

  @lines.each do |line|
    parse_line(line)
  end
  # Warning: recursive here
  @target.parser.parse(level: level)
  @target.parser = nil
  @lines = nil
  @target
end
parse_first_part(line) click to toggle source
# File lib/safrano/multipart.rb, line 35
def parse_first_part(line)
  if @target.parser.next_part(line)
    @state = :next_part
  # this is for when there is only one part
  # (first part is the last one)
  elsif @target.parser.last_part(line)
    @state = :end
  else
    @target.parser.addline(line)
  end
end
parse_head(line) click to toggle source
# File lib/safrano/multipart.rb, line 57
def parse_head(line)
  if (hmd = HMD_RGX.match(line))
    @target_hd[hmd[1].downcase] = hmd[2].strip

  elsif CRLF == line
    @target_ct = @target_hd[CTT_TYPE_LC] || TEXT_PLAIN
    @state = new_content

  end
end
parse_line(line) click to toggle source
# File lib/safrano/multipart.rb, line 68
def parse_line(line)
  case @state
  when :h
    parse_head(line)

  when :b
    @target.parser.addline(line)

  when :bmp
    @state = :first_part if @target.parser.first_part(line)

  when :first_part
    parse_first_part(line)

  when :next_part
    parse_next_part(line)
  end
end
parse_lines(inp, level: 0) click to toggle source
# File lib/safrano/multipart.rb, line 134
def parse_lines(inp, level: 0)
  @lines = inp
  parse(level: level)
end
parse_next_part(line) click to toggle source
# File lib/safrano/multipart.rb, line 47
def parse_next_part(line)
  if @target.parser.next_part(line)

  elsif @target.parser.last_part(line)
    @state = :end
  else
    @target.parser.addline(line)
  end
end
parse_str(inpstr, level: 0) click to toggle source
# File lib/safrano/multipart.rb, line 139
def parse_str(inpstr, level: 0)
  # we need to keep the line separators --> use io.readlines
  if inpstr.respond_to?(:readlines)
    @lines = inpstr.readlines(@sep)
  else
    # rack input wrapper only has gets but not readlines
    sepsave = $INPUT_RECORD_SEPARATOR
    $INPUT_RECORD_SEPARATOR = @sep
    while (line = inpstr.gets)
      @lines << line
    end
    $INPUT_RECORD_SEPARATOR = sepsave

  end
  # tmp hack for test-tools that convert CRLF in payload to LF :-(
  if @lines.size == 1
    @sep = LF
    @lines = @lines.first.split(LF).map { |xline| "#{xline}#{CRLF}" }
  end
  parse(level: level)
end
parse_string(inpstr, level: 0) click to toggle source
# File lib/safrano/multipart.rb, line 161
def parse_string(inpstr, level: 0)
  @lines = inpstr.split(@sep)
  if @lines.size == 1
    @sep = LF
    @lines = @lines.first.split(LF)
  end
  # split is not keeping the separator, we re-add it
  @lines = @lines.map { |line| "#{line}#{CRLF}" }
  parse(level: level)
end