Class: HTTP::Protocol::Headers

Inherits:
Object
  • Object
show all
Defined in:
lib/http/protocol/headers.rb

Defined Under Namespace

Classes: Merged, Multiple, Split

Constant Summary collapse

MERGE_POLICY =
{
	# Headers which may only be specified once.
	'content-type' => false,
	'content-disposition' => false,
	'content-length' => false,
	'user-agent' => false,
	'referer' => false,
	'host' => false,
	'authorization' => false,
	'proxy-authorization' => false,
	'if-modified-since' => false,
	'if-unmodified-since' => false,
	'from' => false,
	'location' => false,
	'max-forwards' => false,
	
	'connection' => Split,
	
	# Headers specifically for proxies:
	'via' => Split,
	'x-forwarded-for' => Split,
	
	# Headers which may be specified multiple times, but which can't be concatenated.
	'set-cookie' => Multiple,
	'www-authenticate' => Multiple,
	'proxy-authenticate' => Multiple
}.tap{|hash| hash.default = Split}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fields = []) ⇒ Headers

Returns a new instance of Headers.



67
68
69
70
# File 'lib/http/protocol/headers.rb', line 67

def initialize(fields = [])
	@fields = fields
	@indexed = to_h
end

Instance Attribute Details

#fieldsObject (readonly)

Returns the value of attribute fields.



72
73
74
# File 'lib/http/protocol/headers.rb', line 72

def fields
  @fields
end

Class Method Details

.[](hash) ⇒ Object



63
64
65
# File 'lib/http/protocol/headers.rb', line 63

def self.[] hash
	self.new(hash.to_a)
end

Instance Method Details

#==(other) ⇒ Object



191
192
193
194
195
196
197
# File 'lib/http/protocol/headers.rb', line 191

def == other
	if other.is_a? Hash
		to_h == other
	else
		@fields == other.fields
	end
end

#[](key) ⇒ Object



177
178
179
180
181
# File 'lib/http/protocol/headers.rb', line 177

def [] key
	@indexed ||= to_h
	
	@indexed[key]
end

#[]=(key, value) ⇒ Object



125
126
127
128
129
130
131
132
# File 'lib/http/protocol/headers.rb', line 125

def []= key, value
	@fields << [key, value]
	
	if @indexed
		# It would be good to do some kind of validation here.
		merge(@indexed, key.downcase, value)
	end
end

#add(key, value) ⇒ Object



121
122
123
# File 'lib/http/protocol/headers.rb', line 121

def add(key, value)
	self[key] = value
end

#delete(key) ⇒ Object

Delete all headers with the given key, and return the value of the last one, if any.



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/http/protocol/headers.rb', line 95

def delete(key)
	values, @fields = @fields.partition do |field|
		field.first.downcase == key
	end
	
	if @indexed
		@indexed.delete(key)
	end
	
	if field = values.last
		return field.last
	end
end

#each(&block) ⇒ Object



86
87
88
# File 'lib/http/protocol/headers.rb', line 86

def each(&block)
	@fields.each(&block)
end

#empty?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/http/protocol/headers.rb', line 82

def empty?
	@fields.empty?
end

#freezeObject



74
75
76
77
78
79
80
# File 'lib/http/protocol/headers.rb', line 74

def freeze
	return if frozen?
	
	@indexed = to_h
	
	super
end

#include?(key) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/http/protocol/headers.rb', line 90

def include? key
	self[key] != nil
end

#merge(hash, key, value) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/http/protocol/headers.rb', line 162

def merge(hash, key, value)
	if policy = MERGE_POLICY[key]
		if current_value = hash[key]
			current_value << value
		else
			hash[key] = policy.new(value)
		end
	else
		raise ArgumentError, "Header #{key} can only be set once!" if hash.include?(key)
		
		# We can't merge these, we only expose the last one set.
		hash[key] = value
	end
end

#slice!(keys) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/http/protocol/headers.rb', line 109

def slice!(keys)
	values, @fields = @fields.partition do |field|
		keys.include?(field.first.downcase)
	end
	
	if @indexed
		keys.each do |key|
			@indexed.delete(key)
		end
	end
end

#to_hObject



183
184
185
186
187
188
189
# File 'lib/http/protocol/headers.rb', line 183

def to_h
	@fields.inject({}) do |hash, (key, value)|
		merge(hash, key.downcase, value)
		
		hash
	end
end