Class: Protocol::Multipart::Header::Parameterized

Inherits:
Object
  • Object
show all
Defined in:
lib/protocol/multipart/header/parameterized.rb

Overview

A parameterized MIME header value.

Direct Known Subclasses

ContentDisposition, ContentType

Constant Summary collapse

TOKEN =
"[!#$%&'*+\\-.^_`|~0-9A-Za-z]+"
VALUE_PATTERN =
/\A[ \t]*(#{TOKEN}(?:\/#{TOKEN})?)[ \t]*/.freeze
PARAMETER_PATTERN =
/\G;[ \t]*(#{TOKEN})[ \t]*=[ \t]*(?:"((?:\\[^\x00-\x1f\x7f]|[^"\\\x00-\x1f\x7f])*)"|(#{TOKEN}))[ \t]*/.freeze
NAME =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type, parameters = {}) ⇒ Parameterized

Initialize a parameterized header value.



68
69
70
71
# File 'lib/protocol/multipart/header/parameterized.rb', line 68

def initialize(type, parameters = {})
	@type = type
	@parameters = parameters
end

Instance Attribute Details

#parametersObject (readonly)

The named parameters.



77
78
79
# File 'lib/protocol/multipart/header/parameterized.rb', line 77

def parameters
  @parameters
end

#typeObject (readonly)

The primary header value.



74
75
76
# File 'lib/protocol/multipart/header/parameterized.rb', line 74

def type
  @type
end

Class Method Details

.coerce(value) ⇒ Object

Coerce an object to a parameterized header value.



57
58
59
60
61
62
63
# File 'lib/protocol/multipart/header/parameterized.rb', line 57

def self.coerce(value)
	if value.is_a?(self)
		return value
	end
	
	return parse(value.to_s)
end

.parse(string) ⇒ Object

Parse a parameterized header value.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/protocol/multipart/header/parameterized.rb', line 22

def self.parse(string)
	unless match = self::VALUE_PATTERN.match(string)
		raise ArgumentError, "Invalid header value: #{string.inspect}!"
	end
	
	type = match[1].downcase
	parameters = {}
	offset = match.end(0)
	
	while offset < string.length
		unless match = PARAMETER_PATTERN.match(string, offset)
			raise ArgumentError, "Invalid header parameter at offset #{offset}: #{string.inspect}!"
		end
		
		name = match[1].downcase
		
		if parameters.key?(name)
			raise ArgumentError, "Duplicate header parameter: #{name.inspect}!"
		end
		
		if quoted = match[2]
			parameters[name] = quoted.gsub(/\\(.)/, "\\1")
		else
			parameters[name] = match[3]
		end
		
		offset = match.end(0)
	end
	
	return new(type, parameters)
end

Instance Method Details

#<<(value) ⇒ Object

Reject a second value for this singular MIME field.

Raises:

  • (Protocol::HTTP::DuplicateHeaderError)


87
88
89
# File 'lib/protocol/multipart/header/parameterized.rb', line 87

def <<(value)
	raise Protocol::HTTP::DuplicateHeaderError.new(self.class::NAME, self, value)
end

#[](name) ⇒ Object

Fetch a named parameter.



82
83
84
# File 'lib/protocol/multipart/header/parameterized.rb', line 82

def [](name)
	@parameters[name.downcase]
end

#to_sObject

Convert the header to its wire representation.



93
94
95
96
97
98
99
100
101
102
# File 'lib/protocol/multipart/header/parameterized.rb', line 93

def to_s
	value = String.new(@type)
	
	@parameters.each do |name, parameter|
		escaped = parameter.gsub(/["\\]/, "\\\\\\0")
		value << "; #{name}=\"#{escaped}\""
	end
	
	return value
end