Module: Net::HTTPHeader
- Included in:
- HTTPGenericRequest, HTTPResponse
- Defined in:
- lib/net/http/header.rb
Overview
The HTTPHeader module provides access to HTTP headers.
The module is included in:
-
Net::HTTPGenericRequest (and therefore Net::HTTPRequest).
-
Net::HTTPResponse.
The headers are a hash-like collection of key/value pairs called fields.
Request and Response Fields
Headers may be included in:
-
A Net::HTTPRequest object: the object’s headers will be sent with the request. Any fields may be defined in the request; see Setters.
-
A Net::HTTPResponse object: the objects headers are usually those returned from the host. Fields may be retrieved from the object; see Getters and Iterators.
Exactly which fields should be sent or expected depends on the host; see:
About the Examples
:include: doc/net-http/examples.rdoc
Fields
A header field is a key/value pair.
Field Keys
A field key may be:
-
A string: Key
'Accept'
is treated as if it were'Accept'.downcase
; i.e.,'accept'
. -
A symbol: Key
:Accept
is treated as if it were:Accept.to_s.downcase
; i.e.,'accept'
.
Examples:
req = Net::HTTP::Get.new(uri)
req[:accept] # => "*/*"
req['Accept'] # => "*/*"
req['ACCEPT'] # => "*/*"
req['accept'] = 'text/html'
req[:accept] = 'text/html'
req['ACCEPT'] = 'text/html'
Field Values
A field value may be returned as an array of strings or as a string:
-
These methods return field values as arrays:
-
#get_fields: Returns the array value for the given key, or
nil
if it does not exist. -
#to_hash: Returns a hash of all header fields: each key is a field name; its value is the array value for the field.
-
-
These methods return field values as string; the string value for a field is equivalent to
self[key.downcase.to_s].join(', '))
:-
#[]: Returns the string value for the given key, or
nil
if it does not exist. -
#fetch: Like #[], but accepts a default value to be returned if the key does not exist.
-
The field value may be set:
-
#[]=: Sets the value for the given key; the given value may be a string, a symbol, an array, or a hash.
-
#add_field: Adds a given value to a value for the given key (not overwriting the existing value).
-
#delete: Deletes the field for the given key.
Example field values:
-
String:
req['Accept'] = 'text/html' # => "text/html" req['Accept'] # => "text/html" req.get_fields('Accept') # => ["text/html"]
-
Symbol:
req['Accept'] = :text # => :text req['Accept'] # => "text" req.get_fields('Accept') # => ["text"]
-
Simple array:
req[:foo] = %w[bar baz bat] req[:foo] # => "bar, baz, bat" req.get_fields(:foo) # => ["bar", "baz", "bat"]
-
Simple hash:
req[:foo] = {bar: 0, baz: 1, bat: 2} req[:foo] # => "bar, 0, baz, 1, bat, 2" req.get_fields(:foo) # => ["bar", "0", "baz", "1", "bat", "2"]
-
Nested:
req[:foo] = [%w[bar baz], {bat: 0, bam: 1}] req[:foo] # => "bar, baz, bat, 0, bam, 1" req.get_fields(:foo) # => ["bar", "baz", "bat", "0", "bam", "1"] req[:foo] = {bar: %w[baz bat], bam: {bah: 0, bad: 1}} req[:foo] # => "bar, baz, bat, bam, bah, 0, bad, 1" req.get_fields(:foo) # => ["bar", "baz", "bat", "bam", "bah", "0", "bad", "1"]
Convenience Methods
Various convenience methods retrieve values, set values, query values, set form values, or iterate over fields.
Setters
Method #[]= can set any field, but does little to validate the new value; some of the other setter methods provide some validation:
-
#[]=: Sets the string or array value for the given key.
-
#add_field: Creates or adds to the array value for the given key.
-
#basic_auth: Sets the string authorization header for
'Authorization'
. -
#content_length=: Sets the integer length for field
'Content-Length
. -
#content_type=: Sets the string value for field
'Content-Type'
. -
#proxy_basic_auth: Sets the string authorization header for
'Proxy-Authorization'
. -
#set_range: Sets the value for field
'Range'
.
Form Setters
-
#set_form: Sets an HTML form data set.
-
#set_form_data: Sets header fields and a body from HTML form data.
Getters
Method #[] can retrieve the value of any field that exists, but always as a string; some of the other getter methods return something different from the simple string value:
-
#[]: Returns the string field value for the given key.
-
#content_length: Returns the integer value of field
'Content-Length'
. -
#content_range: Returns the Range value of field
'Content-Range'
. -
#content_type: Returns the string value of field
'Content-Type'
. -
#fetch: Returns the string field value for the given key.
-
#get_fields: Returns the array field value for the given
key
. -
#main_type: Returns first part of the string value of field
'Content-Type'
. -
#sub_type: Returns second part of the string value of field
'Content-Type'
. -
#range: Returns an array of Range objects of field
'Range'
, ornil
. -
#range_length: Returns the integer length of the range given in field
'Content-Range'
. -
#type_params: Returns the string parameters for
'Content-Type'
.
Queries
-
#chunked?: Returns whether field
'Transfer-Encoding'
is set to'chunked'
. -
#connection_close?: Returns whether field
'Connection'
is set to'close'
. -
#connection_keep_alive?: Returns whether field
'Connection'
is set to'keep-alive'
. -
#key?: Returns whether a given key exists.
Iterators
-
#each_capitalized: Passes each field capitalized-name/value pair to the block.
-
#each_capitalized_name: Passes each capitalized field name to the block.
-
#each_header: Passes each field name/value pair to the block.
-
#each_name: Passes each field name to the block.
-
#each_value: Passes each string field value to the block.
Constant Summary collapse
- MAX_KEY_LENGTH =
1024
- MAX_FIELD_LENGTH =
65536
Instance Method Summary collapse
-
#[](key) ⇒ Object
Returns the string field value for the case-insensitive field
key
, ornil
if there is no such key; see Fields:. -
#[]=(key, val) ⇒ Object
Sets the value for the case-insensitive
key
toval
, overwriting the previous value if the field exists; see Fields:. -
#add_field(key, val) ⇒ Object
Adds value
val
to the value array for fieldkey
if the field exists; creates the field with the givenkey
andval
if it does not exist. -
#basic_auth(account, password) ⇒ Object
Sets header
'Authorization'
using the givenaccount
andpassword
strings:. -
#chunked? ⇒ Boolean
Returns
true
if field'Transfer-Encoding'
exists and has value'chunked'
,false
otherwise; see Transfer-Encoding response header:. -
#connection_close? ⇒ Boolean
Returns whether the HTTP session is to be closed.
-
#connection_keep_alive? ⇒ Boolean
Returns whether the HTTP session is to be kept alive.
-
#content_length ⇒ Object
Returns the value of field
'Content-Length'
as an integer, ornil
if there is no such field; see Content-Length request header:. -
#content_length=(len) ⇒ Object
Sets the value of field
'Content-Length'
to the given numeric; see Content-Length response header:. -
#content_range ⇒ Object
Returns a Range object representing the value of field
'Content-Range'
, ornil
if no such field exists; see Content-Range response header:. -
#content_type ⇒ Object
Returns the media type from the value of field
'Content-Type'
, ornil
if no such field exists; see Content-Type response header:. -
#delete(key) ⇒ Object
Removes the header for the given case-insensitive
key
(see Fields); returns the deleted value, ornil
if no such field exists:. -
#each_capitalized ⇒ Object
(also: #canonical_each)
Like #each_header, but the keys are returned in capitalized form.
-
#each_capitalized_name ⇒ Object
Calls the block with each capitalized field name:.
-
#each_header ⇒ Object
(also: #each)
Calls the block with each key/value pair:.
-
#each_name(&block) ⇒ Object
(also: #each_key)
Calls the block with each field key:.
-
#each_value ⇒ Object
Calls the block with each string field value:.
-
#fetch(key, *args, &block) ⇒ Object
call-seq: fetch(key, default_val = nil) {|key| … } -> object fetch(key, default_val = nil) -> value or default_val.
-
#get_fields(key) ⇒ Object
Returns the array field value for the given
key
, ornil
if there is no such field; see Fields:. -
#initialize_http_header(initheader) ⇒ Object
:nodoc:.
-
#key?(key) ⇒ Boolean
Returns
true
if the field for the case-insensitivekey
exists,false
otherwise:. -
#main_type ⇒ Object
Returns the leading (‘type’) part of the media type from the value of field
'Content-Type'
, ornil
if no such field exists; see Content-Type response header:. -
#proxy_basic_auth(account, password) ⇒ Object
Sets header
'Proxy-Authorization'
using the givenaccount
andpassword
strings:. -
#range ⇒ Object
Returns an array of Range objects that represent the value of field
'Range'
, ornil
if there is no such field; see Range request header:. -
#range_length ⇒ Object
Returns the integer representing length of the value of field
'Content-Range'
, ornil
if no such field exists; see Content-Range response header:. -
#set_content_type(type, params = {}) ⇒ Object
(also: #content_type=)
Sets the value of field
'Content-Type'
; returns the new value; see Content-Type request header:. -
#set_form(params, enctype = 'application/x-www-form-urlencoded', formopt = {}) ⇒ Object
Stores form data to be used in a
POST
orPUT
request. -
#set_form_data(params, sep = '&') ⇒ Object
(also: #form_data=)
Sets the request body to a URL-encoded string derived from argument
params
, and sets request header field'Content-Type'
to'application/x-www-form-urlencoded'
. -
#set_range(r, e = nil) ⇒ Object
(also: #range=)
call-seq: set_range(length) -> length set_range(offset, length) -> range set_range(begin..length) -> range.
-
#size ⇒ Object
(also: #length)
:nodoc: obsolete.
-
#sub_type ⇒ Object
Returns the trailing (‘subtype’) part of the media type from the value of field
'Content-Type'
, ornil
if no such field exists; see Content-Type response header:. -
#to_hash ⇒ Object
Returns a hash of the key/value pairs:.
-
#type_params ⇒ Object
Returns the trailing (‘parameters’) part of the value of field
'Content-Type'
, ornil
if no such field exists; see Content-Type response header:.
Instance Method Details
#[](key) ⇒ Object
Returns the string field value for the case-insensitive field key
, or nil
if there is no such key; see Fields:
res = Net::HTTP.get_response(hostname, '/todos/1')
res['Connection'] # => "keep-alive"
res['Nosuch'] # => nil
Note that some field values may be retrieved via convenience methods; see Getters.
224 225 226 227 |
# File 'lib/net/http/header.rb', line 224 def [](key) a = @header[key.downcase.to_s] or return nil a.join(', ') end |
#[]=(key, val) ⇒ Object
Sets the value for the case-insensitive key
to val
, overwriting the previous value if the field exists; see Fields:
req = Net::HTTP::Get.new(uri)
req['Accept'] # => "*/*"
req['Accept'] = 'text/html'
req['Accept'] # => "text/html"
Note that some field values may be set via convenience methods; see Setters.
240 241 242 243 244 245 246 |
# File 'lib/net/http/header.rb', line 240 def []=(key, val) unless val @header.delete key.downcase.to_s return val end set_field(key, val) end |
#add_field(key, val) ⇒ Object
Adds value val
to the value array for field key
if the field exists; creates the field with the given key
and val
if it does not exist. see Fields:
req = Net::HTTP::Get.new(uri)
req.add_field('Foo', 'bar')
req['Foo'] # => "bar"
req.add_field('Foo', 'baz')
req['Foo'] # => "bar, baz"
req.add_field('Foo', %w[baz bam])
req['Foo'] # => "bar, baz, baz, bam"
req.get_fields('Foo') # => ["bar", "baz", "baz", "bam"]
261 262 263 264 265 266 267 268 |
# File 'lib/net/http/header.rb', line 261 def add_field(key, val) stringified_downcased_key = key.downcase.to_s if @header.key?(stringified_downcased_key) append_field_value(@header[stringified_downcased_key], val) else set_field(key, val) end end |
#basic_auth(account, password) ⇒ Object
Sets header 'Authorization'
using the given account
and password
strings:
req.basic_auth('my_account', 'my_password')
req['Authorization']
# => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
945 946 947 |
# File 'lib/net/http/header.rb', line 945 def basic_auth(account, password) @header['authorization'] = [basic_encode(account, password)] end |
#chunked? ⇒ Boolean
Returns true
if field 'Transfer-Encoding'
exists and has value 'chunked'
, false
otherwise; see Transfer-Encoding response header:
res = Net::HTTP.get_response(hostname, '/todos/1')
res['Transfer-Encoding'] # => "chunked"
res.chunked? # => true
654 655 656 657 658 |
# File 'lib/net/http/header.rb', line 654 def chunked? return false unless @header['transfer-encoding'] field = self['Transfer-Encoding'] (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false end |
#connection_close? ⇒ Boolean
Returns whether the HTTP session is to be closed.
966 967 968 969 970 971 |
# File 'lib/net/http/header.rb', line 966 def connection_close? token = /(?:\A|,)\s*close\s*(?:\z|,)/i @header['connection']&.grep(token) {return true} @header['proxy-connection']&.grep(token) {return true} false end |
#connection_keep_alive? ⇒ Boolean
Returns whether the HTTP session is to be kept alive.
974 975 976 977 978 979 |
# File 'lib/net/http/header.rb', line 974 def connection_keep_alive? token = /(?:\A|,)\s*keep-alive\s*(?:\z|,)/i @header['connection']&.grep(token) {return true} @header['proxy-connection']&.grep(token) {return true} false end |
#content_length ⇒ Object
Returns the value of field 'Content-Length'
as an integer, or nil
if there is no such field; see Content-Length request header:
res = Net::HTTP.get_response(hostname, '/nosuch/1')
res.content_length # => 2
res = Net::HTTP.get_response(hostname, '/todos/1')
res.content_length # => nil
616 617 618 619 620 621 |
# File 'lib/net/http/header.rb', line 616 def content_length return nil unless key?('Content-Length') len = self['Content-Length'].slice(/\d+/) or raise Net::HTTPHeaderSyntaxError, 'wrong Content-Length format' len.to_i end |
#content_length=(len) ⇒ Object
Sets the value of field 'Content-Length'
to the given numeric; see Content-Length response header:
_uri = uri.dup
hostname = _uri.hostname # => "jsonplaceholder.typicode.com"
_uri.path = '/posts' # => "/posts"
req = Net::HTTP::Post.new(_uri) # => #<Net::HTTP::Post POST>
req.body = '{"title": "foo","body": "bar","userId": 1}'
req.content_length = req.body.size # => 42
req.content_type = 'application/json'
res = Net::HTTP.start(hostname) do |http|
http.request(req)
end # => #<Net::HTTPCreated 201 Created readbody=true>
637 638 639 640 641 642 643 |
# File 'lib/net/http/header.rb', line 637 def content_length=(len) unless len @header.delete 'content-length' return nil end @header['content-length'] = [len.to_i.to_s] end |
#content_range ⇒ Object
Returns a Range object representing the value of field 'Content-Range'
, or nil
if no such field exists; see Content-Range response header:
res = Net::HTTP.get_response(hostname, '/todos/1')
res['Content-Range'] # => nil
res['Content-Range'] = 'bytes 0-499/1000'
res['Content-Range'] # => "bytes 0-499/1000"
res.content_range # => 0..499
670 671 672 673 674 675 676 |
# File 'lib/net/http/header.rb', line 670 def content_range return nil unless @header['content-range'] m = %r<\A\s*(\w+)\s+(\d+)-(\d+)/(\d+|\*)>.match(self['Content-Range']) or raise Net::HTTPHeaderSyntaxError, 'wrong Content-Range format' return unless m[1] == 'bytes' m[2].to_i .. m[3].to_i end |
#content_type ⇒ Object
Returns the media type from the value of field 'Content-Type'
, or nil
if no such field exists; see Content-Type response header:
res = Net::HTTP.get_response(hostname, '/todos/1')
res['content-type'] # => "application/json; charset=utf-8"
res.content_type # => "application/json"
701 702 703 704 705 706 707 708 709 710 711 |
# File 'lib/net/http/header.rb', line 701 def content_type main = main_type() return nil unless main sub = sub_type() if sub "#{main}/#{sub}" else main end end |
#delete(key) ⇒ Object
453 454 455 |
# File 'lib/net/http/header.rb', line 453 def delete(key) @header.delete(key.downcase.to_s) end |
#each_capitalized ⇒ Object Also known as: canonical_each
Like #each_header, but the keys are returned in capitalized form.
Net::HTTPHeader#canonical_each is an alias for Net::HTTPHeader#each_capitalized.
484 485 486 487 488 489 |
# File 'lib/net/http/header.rb', line 484 def each_capitalized block_given? or return enum_for(__method__) { @header.size } @header.each do |k,v| yield capitalize(k), v.join(', ') end end |
#each_capitalized_name ⇒ Object
Calls the block with each capitalized field name:
res = Net::HTTP.get_response(hostname, '/todos/1')
res.each_capitalized_name do |key|
p key if key.start_with?('C')
end
Output:
"Content-Type"
"Connection"
"Cache-Control"
"Cf-Cache-Status"
"Cf-Ray"
The capitalization is system-dependent; see Case Mapping.
Returns an enumerator if no block is given.
417 418 419 420 421 422 |
# File 'lib/net/http/header.rb', line 417 def each_capitalized_name #:yield: +key+ block_given? or return enum_for(__method__) { @header.size } @header.each_key do |k| yield capitalize(k) end end |
#each_header ⇒ Object Also known as: each
Calls the block with each key/value pair:
res = Net::HTTP.get_response(hostname, '/todos/1')
res.each_header do |key, value|
p [key, value] if key.start_with?('c')
end
Output:
["content-type", "application/json; charset=utf-8"]
["connection", "keep-alive"]
["cache-control", "max-age=43200"]
["cf-cache-status", "HIT"]
["cf-ray", "771d17e9bc542cf5-ORD"]
Returns an enumerator if no block is given.
Net::HTTPHeader#each is an alias for Net::HTTPHeader#each_header.
364 365 366 367 368 369 |
# File 'lib/net/http/header.rb', line 364 def each_header #:yield: +key+, +value+ block_given? or return enum_for(__method__) { @header.size } @header.each do |k,va| yield k, va.join(', ') end end |
#each_name(&block) ⇒ Object Also known as: each_key
Calls the block with each field key:
res = Net::HTTP.get_response(hostname, '/todos/1')
res.each_key do |key|
p key if key.start_with?('c')
end
Output:
"content-type"
"connection"
"cache-control"
"cf-cache-status"
"cf-ray"
Returns an enumerator if no block is given.
Net::HTTPHeader#each_name is an alias for Net::HTTPHeader#each_key.
391 392 393 394 |
# File 'lib/net/http/header.rb', line 391 def each_name(&block) #:yield: +key+ block_given? or return enum_for(__method__) { @header.size } @header.each_key(&block) end |
#each_value ⇒ Object
Calls the block with each string field value:
res = Net::HTTP.get_response(hostname, '/todos/1')
res.each_value do |value|
p value if value.start_with?('c')
end
Output:
"chunked"
"cf-q-config;dur=6.0000002122251e-06"
"cloudflare"
Returns an enumerator if no block is given.
438 439 440 441 442 443 |
# File 'lib/net/http/header.rb', line 438 def each_value #:yield: +value+ block_given? or return enum_for(__method__) { @header.size } @header.each_value do |va| yield va.join(', ') end end |
#fetch(key, *args, &block) ⇒ Object
call-seq:
fetch(key, default_val = nil) {|key| ... } -> object
fetch(key, default_val = nil) -> value or default_val
With a block, returns the string value for key
if it exists; otherwise returns the value of the block; ignores the default_val
; see Fields:
res = Net::HTTP.get_response(hostname, '/todos/1')
# Field exists; block not called.
res.fetch('Connection') do |value|
fail 'Cannot happen'
end # => "keep-alive"
# Field does not exist; block called.
res.fetch('Nosuch') do |value|
value.downcase
end # => "nosuch"
With no block, returns the string value for key
if it exists; otherwise, returns default_val
if it was given; otherwise raises an exception:
res.fetch('Connection', 'Foo') # => "keep-alive"
res.fetch('Nosuch', 'Foo') # => "Foo"
res.fetch('Nosuch') # Raises KeyError.
341 342 343 344 |
# File 'lib/net/http/header.rb', line 341 def fetch(key, *args, &block) #:yield: +key+ a = @header.fetch(key.downcase.to_s, *args, &block) a.kind_of?(Array) ? a.join(', ') : a end |
#get_fields(key) ⇒ Object
Returns the array field value for the given key
, or nil
if there is no such field; see Fields:
res = Net::HTTP.get_response(hostname, '/todos/1')
res.get_fields('Connection') # => ["keep-alive"]
res.get_fields('Nosuch') # => nil
306 307 308 309 310 |
# File 'lib/net/http/header.rb', line 306 def get_fields(key) stringified_downcased_key = key.downcase.to_s return nil unless @header[stringified_downcased_key] @header[stringified_downcased_key].dup end |
#initialize_http_header(initheader) ⇒ Object
:nodoc:
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/net/http/header.rb', line 185 def initialize_http_header(initheader) #:nodoc: @header = {} return unless initheader initheader.each do |key, value| warn "net/http: duplicated HTTP header: #{key}", uplevel: 3 if key?(key) and $VERBOSE if value.nil? warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE else value = value.strip # raise error for invalid byte sequences if key.to_s.bytesize > MAX_KEY_LENGTH raise ArgumentError, "too long (#{key.bytesize} bytes) header: #{key[0, 30].inspect}..." end if value.to_s.bytesize > MAX_FIELD_LENGTH raise ArgumentError, "header #{key} has too long field value: #{value.bytesize}" end if value.count("\r\n") > 0 raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF" end @header[key.downcase.to_s] = [value] end end end |
#key?(key) ⇒ Boolean
463 464 465 |
# File 'lib/net/http/header.rb', line 463 def key?(key) @header.key?(key.downcase.to_s) end |
#main_type ⇒ Object
Returns the leading (‘type’) part of the media type from the value of field 'Content-Type'
, or nil
if no such field exists; see Content-Type response header:
res = Net::HTTP.get_response(hostname, '/todos/1')
res['content-type'] # => "application/json; charset=utf-8"
res.main_type # => "application"
723 724 725 726 |
# File 'lib/net/http/header.rb', line 723 def main_type return nil unless @header['content-type'] self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip end |
#proxy_basic_auth(account, password) ⇒ Object
Sets header 'Proxy-Authorization'
using the given account
and password
strings:
req.proxy_basic_auth('my_account', 'my_password')
req['Proxy-Authorization']
# => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
956 957 958 |
# File 'lib/net/http/header.rb', line 956 def proxy_basic_auth(account, password) @header['proxy-authorization'] = [basic_encode(account, password)] end |
#range ⇒ Object
Returns an array of Range objects that represent the value of field 'Range'
, or nil
if there is no such field; see Range request header:
req = Net::HTTP::Get.new(uri)
req['Range'] = 'bytes=0-99,200-299,400-499'
req.range # => [0..99, 200..299, 400..499]
req.delete('Range')
req.range # # => nil
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 |
# File 'lib/net/http/header.rb', line 509 def range return nil unless @header['range'] value = self['Range'] # byte-range-set = *( "," OWS ) ( byte-range-spec / suffix-byte-range-spec ) # *( OWS "," [ OWS ( byte-range-spec / suffix-byte-range-spec ) ] ) # corrected collected ABNF # http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#section-5.4.1 # http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#appendix-C # http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-19#section-3.2.5 unless /\Abytes=((?:,[ \t]*)*(?:\d+-\d*|-\d+)(?:[ \t]*,(?:[ \t]*\d+-\d*|-\d+)?)*)\z/ =~ value raise Net::HTTPHeaderSyntaxError, "invalid syntax for byte-ranges-specifier: '#{value}'" end byte_range_set = $1 result = byte_range_set.split(/,/).map {|spec| m = /(\d+)?\s*-\s*(\d+)?/i.match(spec) or raise Net::HTTPHeaderSyntaxError, "invalid byte-range-spec: '#{spec}'" d1 = m[1].to_i d2 = m[2].to_i if m[1] and m[2] if d1 > d2 raise Net::HTTPHeaderSyntaxError, "last-byte-pos MUST greater than or equal to first-byte-pos but '#{spec}'" end d1..d2 elsif m[1] d1..-1 elsif m[2] -d2..-1 else raise Net::HTTPHeaderSyntaxError, 'range is not specified' end } # if result.empty? # byte-range-set must include at least one byte-range-spec or suffix-byte-range-spec # but above regexp already denies it. if result.size == 1 && result[0].begin == 0 && result[0].end == -1 raise Net::HTTPHeaderSyntaxError, 'only one suffix-byte-range-spec with zero suffix-length' end result end |
#range_length ⇒ Object
Returns the integer representing length of the value of field 'Content-Range'
, or nil
if no such field exists; see Content-Range response header:
res = Net::HTTP.get_response(hostname, '/todos/1')
res['Content-Range'] # => nil
res['Content-Range'] = 'bytes 0-499/1000'
res.range_length # => 500
687 688 689 690 |
# File 'lib/net/http/header.rb', line 687 def range_length r = content_range() or return nil r.end - r.begin + 1 end |
#set_content_type(type, params = {}) ⇒ Object Also known as: content_type=
Sets the value of field 'Content-Type'
; returns the new value; see Content-Type request header:
req = Net::HTTP::Get.new(uri)
req.set_content_type('application/json') # => ["application/json"]
Net::HTTPHeader#content_type= is an alias for Net::HTTPHeader#set_content_type.
772 773 774 |
# File 'lib/net/http/header.rb', line 772 def set_content_type(type, params = {}) @header['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')] end |
#set_form(params, enctype = 'application/x-www-form-urlencoded', formopt = {}) ⇒ Object
Stores form data to be used in a POST
or PUT
request.
The form data given in params
consists of zero or more fields; each field is:
-
A scalar value.
-
A name/value pair.
-
An IO stream opened for reading.
Argument params
should be an Enumerable (method params.map
will be called), and is often an array or hash.
First, we set up a request:
_uri = uri.dup
_uri.path ='/posts'
req = Net::HTTP::Post.new(_uri)
Argument params
As an Array
When params
is an array, each of its elements is a subarray that defines a field; the subarray may contain:
-
One string:
req.set_form([['foo'], ['bar'], ['baz']])
-
Two strings:
req.set_form([%w[foo 0], %w[bar 1], %w[baz 2]])
-
When argument
enctype
(see below) is given as'multipart/form-data'
:-
A string name and an IO stream opened for reading:
require 'stringio' req.set_form([['file', StringIO.new('Ruby is cool.')]])
-
A string name, an IO stream opened for reading, and an options hash, which may contain these entries:
-
:filename
: The name of the file to use. -
:content_type
: The content type of the uploaded file.
Example:
req.set_form([['file', file, {filename: "other-filename.foo"}]]
-
-
The various forms may be mixed:
req.set_form(['foo', %w[bar 1], ['file', file]])
Argument params
As a Hash
When params
is a hash, each of its entries is a name/value pair that defines a field:
-
The name is a string.
-
The value may be:
-
nil
. -
Another string.
-
An IO stream opened for reading (only when argument
enctype
– see below – is given as'multipart/form-data'
).
-
Examples:
# Nil-valued fields.
req.set_form({'foo' => nil, 'bar' => nil, 'baz' => nil})
# String-valued fields.
req.set_form({'foo' => 0, 'bar' => 1, 'baz' => 2})
# IO-valued field.
require 'stringio'
req.set_form({'file' => StringIO.new('Ruby is cool.')})
# Mixture of fields.
req.set_form({'foo' => nil, 'bar' => 1, 'file' => file})
Optional argument enctype
specifies the value to be given to field 'Content-Type'
, and must be one of:
-
'application/x-www-form-urlencoded'
(the default). -
'multipart/form-data'
; see RFC 7578.
Optional argument formopt
is a hash of options (applicable only when argument enctype
is 'multipart/form-data'
) that may include the following entries:
-
:boundary
: The value is the boundary string for the multipart message. If not given, the boundary is a random string. See Boundary. -
:charset
: Value is the character set for the form submission. Field names and values of non-file fields should be encoded with this charset.
924 925 926 927 928 929 930 931 932 933 934 935 936 |
# File 'lib/net/http/header.rb', line 924 def set_form(params, enctype='application/x-www-form-urlencoded', formopt={}) @body_data = params @body = nil @body_stream = nil @form_option = formopt case enctype when /\Aapplication\/x-www-form-urlencoded\z/i, /\Amultipart\/form-data\z/i self.content_type = enctype else raise ArgumentError, "invalid enctype: #{enctype}" end end |
#set_form_data(params, sep = '&') ⇒ Object Also known as: form_data=
Sets the request body to a URL-encoded string derived from argument params
, and sets request header field 'Content-Type'
to 'application/x-www-form-urlencoded'
.
The resulting request is suitable for HTTP request POST
or PUT
.
Argument params
must be suitable for use as argument enum
to URI.encode_www_form.
With only argument params
given, sets the body to a URL-encoded string with the default separator '&'
:
req = Net::HTTP::Post.new('example.com')
req.set_form_data(q: 'ruby', lang: 'en')
req.body # => "q=ruby&lang=en"
req['Content-Type'] # => "application/x-www-form-urlencoded"
req.set_form_data([['q', 'ruby'], ['lang', 'en']])
req.body # => "q=ruby&lang=en"
req.set_form_data(q: ['ruby', 'perl'], lang: 'en')
req.body # => "q=ruby&q=perl&lang=en"
req.set_form_data([['q', 'ruby'], ['q', 'perl'], ['lang', 'en']])
req.body # => "q=ruby&q=perl&lang=en"
With string argument sep
also given, uses that string as the separator:
req.set_form_data({q: 'ruby', lang: 'en'}, '|')
req.body # => "q=ruby|lang=en"
Net::HTTPHeader#form_data= is an alias for Net::HTTPHeader#set_form_data.
812 813 814 815 816 817 |
# File 'lib/net/http/header.rb', line 812 def set_form_data(params, sep = '&') query = URI.encode_www_form(params) query.gsub!(/&/, sep) if sep != '&' self.body = query self.content_type = 'application/x-www-form-urlencoded' end |
#set_range(r, e = nil) ⇒ Object Also known as: range=
call-seq:
set_range(length) -> length
set_range(offset, length) -> range
set_range(begin..length) -> range
Sets the value for field 'Range'
; see Range request header:
With argument length
:
req = Net::HTTP::Get.new(uri)
req.set_range(100) # => 100
req['Range'] # => "bytes=0-99"
With arguments offset
and length
:
req.set_range(100, 100) # => 100...200
req['Range'] # => "bytes=100-199"
With argument range
:
req.set_range(100..199) # => 100..199
req['Range'] # => "bytes=100-199"
Net::HTTPHeader#range= is an alias for Net::HTTPHeader#set_range.
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
# File 'lib/net/http/header.rb', line 576 def set_range(r, e = nil) unless r @header.delete 'range' return r end r = (r...r+e) if e case r when Numeric n = r.to_i rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}") when Range first = r.first last = r.end last -= 1 if r.exclude_end? if last == -1 rangestr = (first > 0 ? "#{first}-" : "-#{-first}") else raise Net::HTTPHeaderSyntaxError, 'range.first is negative' if first < 0 raise Net::HTTPHeaderSyntaxError, 'range.last is negative' if last < 0 raise Net::HTTPHeaderSyntaxError, 'must be .first < .last' if first > last rangestr = "#{first}-#{last}" end else raise TypeError, 'Range/Integer is required' end @header['range'] = ["bytes=#{rangestr}"] r end |
#size ⇒ Object Also known as: length
:nodoc: obsolete
208 209 210 |
# File 'lib/net/http/header.rb', line 208 def size #:nodoc: obsolete @header.size end |
#sub_type ⇒ Object
Returns the trailing (‘subtype’) part of the media type from the value of field 'Content-Type'
, or nil
if no such field exists; see Content-Type response header:
res = Net::HTTP.get_response(hostname, '/todos/1')
res['content-type'] # => "application/json; charset=utf-8"
res.sub_type # => "json"
738 739 740 741 742 743 |
# File 'lib/net/http/header.rb', line 738 def sub_type return nil unless @header['content-type'] _, sub = *self['Content-Type'].split(';').first.to_s.split('/') return nil unless sub sub.strip end |
#to_hash ⇒ Object
477 478 479 |
# File 'lib/net/http/header.rb', line 477 def to_hash @header.dup end |
#type_params ⇒ Object
Returns the trailing (‘parameters’) part of the value of field 'Content-Type'
, or nil
if no such field exists; see Content-Type response header:
res = Net::HTTP.get_response(hostname, '/todos/1')
res['content-type'] # => "application/json; charset=utf-8"
res.type_params # => {"charset"=>"utf-8"}
753 754 755 756 757 758 759 760 761 762 |
# File 'lib/net/http/header.rb', line 753 def type_params result = {} list = self['Content-Type'].to_s.split(';') list.shift list.each do |param| k, v = *param.split('=', 2) result[k.strip] = v.strip end result end |