net-http 0.1.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/README.md +1 -1
- data/Rakefile +0 -7
- data/doc/net-http/examples.rdoc +31 -0
- data/doc/net-http/included_getters.rdoc +3 -0
- data/lib/net/http/backward.rb +27 -13
- data/lib/net/http/exceptions.rb +28 -27
- data/lib/net/http/generic_request.rb +96 -21
- data/lib/net/http/header.rb +628 -163
- data/lib/net/http/proxy_delta.rb +1 -1
- data/lib/net/http/request.rb +73 -6
- data/lib/net/http/requests.rb +327 -25
- data/lib/net/http/response.rb +339 -28
- data/lib/net/http/responses.rb +1090 -223
- data/lib/net/http/status.rb +7 -6
- data/lib/net/http.rb +1458 -668
- data/lib/net/https.rb +1 -1
- data/net-http.gemspec +9 -6
- metadata +5 -20
- data/.github/workflows/test.yml +0 -24
- data/.gitignore +0 -8
- data/Gemfile.lock +0 -23
data/lib/net/http/header.rb
CHANGED
@@ -1,16 +1,188 @@
|
|
1
|
-
# frozen_string_literal:
|
2
|
-
# The HTTPHeader module defines methods for reading and writing
|
3
|
-
# HTTP headers.
|
1
|
+
# frozen_string_literal: true
|
4
2
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
3
|
+
# The \HTTPHeader module provides access to \HTTP headers.
|
4
|
+
#
|
5
|
+
# The module is included in:
|
6
|
+
#
|
7
|
+
# - Net::HTTPGenericRequest (and therefore Net::HTTPRequest).
|
8
|
+
# - Net::HTTPResponse.
|
9
|
+
#
|
10
|
+
# The headers are a hash-like collection of key/value pairs called _fields_.
|
11
|
+
#
|
12
|
+
# == Request and Response Fields
|
13
|
+
#
|
14
|
+
# Headers may be included in:
|
15
|
+
#
|
16
|
+
# - A Net::HTTPRequest object:
|
17
|
+
# the object's headers will be sent with the request.
|
18
|
+
# Any fields may be defined in the request;
|
19
|
+
# see {Setters}[rdoc-ref:Net::HTTPHeader@Setters].
|
20
|
+
# - A Net::HTTPResponse object:
|
21
|
+
# the objects headers are usually those returned from the host.
|
22
|
+
# Fields may be retrieved from the object;
|
23
|
+
# see {Getters}[rdoc-ref:Net::HTTPHeader@Getters]
|
24
|
+
# and {Iterators}[rdoc-ref:Net::HTTPHeader@Iterators].
|
25
|
+
#
|
26
|
+
# Exactly which fields should be sent or expected depends on the host;
|
27
|
+
# see:
|
28
|
+
#
|
29
|
+
# - {Request fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields].
|
30
|
+
# - {Response fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields].
|
31
|
+
#
|
32
|
+
# == About the Examples
|
33
|
+
#
|
34
|
+
# :include: doc/net-http/examples.rdoc
|
35
|
+
#
|
36
|
+
# == Fields
|
37
|
+
#
|
38
|
+
# A header field is a key/value pair.
|
39
|
+
#
|
40
|
+
# === Field Keys
|
41
|
+
#
|
42
|
+
# A field key may be:
|
43
|
+
#
|
44
|
+
# - A string: Key <tt>'Accept'</tt> is treated as if it were
|
45
|
+
# <tt>'Accept'.downcase</tt>; i.e., <tt>'accept'</tt>.
|
46
|
+
# - A symbol: Key <tt>:Accept</tt> is treated as if it were
|
47
|
+
# <tt>:Accept.to_s.downcase</tt>; i.e., <tt>'accept'</tt>.
|
48
|
+
#
|
49
|
+
# Examples:
|
50
|
+
#
|
51
|
+
# req = Net::HTTP::Get.new(uri)
|
52
|
+
# req[:accept] # => "*/*"
|
53
|
+
# req['Accept'] # => "*/*"
|
54
|
+
# req['ACCEPT'] # => "*/*"
|
55
|
+
#
|
56
|
+
# req['accept'] = 'text/html'
|
57
|
+
# req[:accept] = 'text/html'
|
58
|
+
# req['ACCEPT'] = 'text/html'
|
59
|
+
#
|
60
|
+
# === Field Values
|
61
|
+
#
|
62
|
+
# A field value may be returned as an array of strings or as a string:
|
63
|
+
#
|
64
|
+
# - These methods return field values as arrays:
|
65
|
+
#
|
66
|
+
# - #get_fields: Returns the array value for the given key,
|
67
|
+
# or +nil+ if it does not exist.
|
68
|
+
# - #to_hash: Returns a hash of all header fields:
|
69
|
+
# each key is a field name; its value is the array value for the field.
|
70
|
+
#
|
71
|
+
# - These methods return field values as string;
|
72
|
+
# the string value for a field is equivalent to
|
73
|
+
# <tt>self[key.downcase.to_s].join(', '))</tt>:
|
74
|
+
#
|
75
|
+
# - #[]: Returns the string value for the given key,
|
76
|
+
# or +nil+ if it does not exist.
|
77
|
+
# - #fetch: Like #[], but accepts a default value
|
78
|
+
# to be returned if the key does not exist.
|
79
|
+
#
|
80
|
+
# The field value may be set:
|
81
|
+
#
|
82
|
+
# - #[]=: Sets the value for the given key;
|
83
|
+
# the given value may be a string, a symbol, an array, or a hash.
|
84
|
+
# - #add_field: Adds a given value to a value for the given key
|
85
|
+
# (not overwriting the existing value).
|
86
|
+
# - #delete: Deletes the field for the given key.
|
87
|
+
#
|
88
|
+
# Example field values:
|
89
|
+
#
|
90
|
+
# - \String:
|
91
|
+
#
|
92
|
+
# req['Accept'] = 'text/html' # => "text/html"
|
93
|
+
# req['Accept'] # => "text/html"
|
94
|
+
# req.get_fields('Accept') # => ["text/html"]
|
95
|
+
#
|
96
|
+
# - \Symbol:
|
97
|
+
#
|
98
|
+
# req['Accept'] = :text # => :text
|
99
|
+
# req['Accept'] # => "text"
|
100
|
+
# req.get_fields('Accept') # => ["text"]
|
101
|
+
#
|
102
|
+
# - Simple array:
|
103
|
+
#
|
104
|
+
# req[:foo] = %w[bar baz bat]
|
105
|
+
# req[:foo] # => "bar, baz, bat"
|
106
|
+
# req.get_fields(:foo) # => ["bar", "baz", "bat"]
|
107
|
+
#
|
108
|
+
# - Simple hash:
|
109
|
+
#
|
110
|
+
# req[:foo] = {bar: 0, baz: 1, bat: 2}
|
111
|
+
# req[:foo] # => "bar, 0, baz, 1, bat, 2"
|
112
|
+
# req.get_fields(:foo) # => ["bar", "0", "baz", "1", "bat", "2"]
|
113
|
+
#
|
114
|
+
# - Nested:
|
115
|
+
#
|
116
|
+
# req[:foo] = [%w[bar baz], {bat: 0, bam: 1}]
|
117
|
+
# req[:foo] # => "bar, baz, bat, 0, bam, 1"
|
118
|
+
# req.get_fields(:foo) # => ["bar", "baz", "bat", "0", "bam", "1"]
|
119
|
+
#
|
120
|
+
# req[:foo] = {bar: %w[baz bat], bam: {bah: 0, bad: 1}}
|
121
|
+
# req[:foo] # => "bar, baz, bat, bam, bah, 0, bad, 1"
|
122
|
+
# req.get_fields(:foo) # => ["bar", "baz", "bat", "bam", "bah", "0", "bad", "1"]
|
123
|
+
#
|
124
|
+
# == Convenience Methods
|
125
|
+
#
|
126
|
+
# Various convenience methods retrieve values, set values, query values,
|
127
|
+
# set form values, or iterate over fields.
|
128
|
+
#
|
129
|
+
# === Setters
|
130
|
+
#
|
131
|
+
# \Method #[]= can set any field, but does little to validate the new value;
|
132
|
+
# some of the other setter methods provide some validation:
|
133
|
+
#
|
134
|
+
# - #[]=: Sets the string or array value for the given key.
|
135
|
+
# - #add_field: Creates or adds to the array value for the given key.
|
136
|
+
# - #basic_auth: Sets the string authorization header for <tt>'Authorization'</tt>.
|
137
|
+
# - #content_length=: Sets the integer length for field <tt>'Content-Length</tt>.
|
138
|
+
# - #content_type=: Sets the string value for field <tt>'Content-Type'</tt>.
|
139
|
+
# - #proxy_basic_auth: Sets the string authorization header for <tt>'Proxy-Authorization'</tt>.
|
140
|
+
# - #set_range: Sets the value for field <tt>'Range'</tt>.
|
141
|
+
#
|
142
|
+
# === Form Setters
|
143
|
+
#
|
144
|
+
# - #set_form: Sets an HTML form data set.
|
145
|
+
# - #set_form_data: Sets header fields and a body from HTML form data.
|
146
|
+
#
|
147
|
+
# === Getters
|
148
|
+
#
|
149
|
+
# \Method #[] can retrieve the value of any field that exists,
|
150
|
+
# but always as a string;
|
151
|
+
# some of the other getter methods return something different
|
152
|
+
# from the simple string value:
|
153
|
+
#
|
154
|
+
# - #[]: Returns the string field value for the given key.
|
155
|
+
# - #content_length: Returns the integer value of field <tt>'Content-Length'</tt>.
|
156
|
+
# - #content_range: Returns the Range value of field <tt>'Content-Range'</tt>.
|
157
|
+
# - #content_type: Returns the string value of field <tt>'Content-Type'</tt>.
|
158
|
+
# - #fetch: Returns the string field value for the given key.
|
159
|
+
# - #get_fields: Returns the array field value for the given +key+.
|
160
|
+
# - #main_type: Returns first part of the string value of field <tt>'Content-Type'</tt>.
|
161
|
+
# - #sub_type: Returns second part of the string value of field <tt>'Content-Type'</tt>.
|
162
|
+
# - #range: Returns an array of Range objects of field <tt>'Range'</tt>, or +nil+.
|
163
|
+
# - #range_length: Returns the integer length of the range given in field <tt>'Content-Range'</tt>.
|
164
|
+
# - #type_params: Returns the string parameters for <tt>'Content-Type'</tt>.
|
165
|
+
#
|
166
|
+
# === Queries
|
167
|
+
#
|
168
|
+
# - #chunked?: Returns whether field <tt>'Transfer-Encoding'</tt> is set to <tt>'chunked'</tt>.
|
169
|
+
# - #connection_close?: Returns whether field <tt>'Connection'</tt> is set to <tt>'close'</tt>.
|
170
|
+
# - #connection_keep_alive?: Returns whether field <tt>'Connection'</tt> is set to <tt>'keep-alive'</tt>.
|
171
|
+
# - #key?: Returns whether a given key exists.
|
172
|
+
#
|
173
|
+
# === Iterators
|
174
|
+
#
|
175
|
+
# - #each_capitalized: Passes each field capitalized-name/value pair to the block.
|
176
|
+
# - #each_capitalized_name: Passes each capitalized field name to the block.
|
177
|
+
# - #each_header: Passes each field name/value pair to the block.
|
178
|
+
# - #each_name: Passes each field name to the block.
|
179
|
+
# - #each_value: Passes each string field value to the block.
|
10
180
|
#
|
11
181
|
module Net::HTTPHeader
|
182
|
+
MAX_KEY_LENGTH = 1024
|
183
|
+
MAX_FIELD_LENGTH = 65536
|
12
184
|
|
13
|
-
def initialize_http_header(initheader)
|
185
|
+
def initialize_http_header(initheader) #:nodoc:
|
14
186
|
@header = {}
|
15
187
|
return unless initheader
|
16
188
|
initheader.each do |key, value|
|
@@ -19,6 +191,12 @@ module Net::HTTPHeader
|
|
19
191
|
warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE
|
20
192
|
else
|
21
193
|
value = value.strip # raise error for invalid byte sequences
|
194
|
+
if key.to_s.bytesize > MAX_KEY_LENGTH
|
195
|
+
raise ArgumentError, "too long (#{key.bytesize} bytes) header: #{key[0, 30].inspect}..."
|
196
|
+
end
|
197
|
+
if value.to_s.bytesize > MAX_FIELD_LENGTH
|
198
|
+
raise ArgumentError, "header #{key} has too long field value: #{value.bytesize}"
|
199
|
+
end
|
22
200
|
if value.count("\r\n") > 0
|
23
201
|
raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF"
|
24
202
|
end
|
@@ -33,14 +211,32 @@ module Net::HTTPHeader
|
|
33
211
|
|
34
212
|
alias length size #:nodoc: obsolete
|
35
213
|
|
36
|
-
# Returns the
|
37
|
-
#
|
214
|
+
# Returns the string field value for the case-insensitive field +key+,
|
215
|
+
# or +nil+ if there is no such key;
|
216
|
+
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
|
217
|
+
#
|
218
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
219
|
+
# res['Connection'] # => "keep-alive"
|
220
|
+
# res['Nosuch'] # => nil
|
221
|
+
#
|
222
|
+
# Note that some field values may be retrieved via convenience methods;
|
223
|
+
# see {Getters}[rdoc-ref:Net::HTTPHeader@Getters].
|
38
224
|
def [](key)
|
39
225
|
a = @header[key.downcase.to_s] or return nil
|
40
226
|
a.join(', ')
|
41
227
|
end
|
42
228
|
|
43
|
-
# Sets the
|
229
|
+
# Sets the value for the case-insensitive +key+ to +val+,
|
230
|
+
# overwriting the previous value if the field exists;
|
231
|
+
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
|
232
|
+
#
|
233
|
+
# req = Net::HTTP::Get.new(uri)
|
234
|
+
# req['Accept'] # => "*/*"
|
235
|
+
# req['Accept'] = 'text/html'
|
236
|
+
# req['Accept'] # => "text/html"
|
237
|
+
#
|
238
|
+
# Note that some field values may be set via convenience methods;
|
239
|
+
# see {Setters}[rdoc-ref:Net::HTTPHeader@Setters].
|
44
240
|
def []=(key, val)
|
45
241
|
unless val
|
46
242
|
@header.delete key.downcase.to_s
|
@@ -49,20 +245,18 @@ module Net::HTTPHeader
|
|
49
245
|
set_field(key, val)
|
50
246
|
end
|
51
247
|
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
# See also #[]=, #[] and #get_fields.
|
248
|
+
# Adds value +val+ to the value array for field +key+ if the field exists;
|
249
|
+
# creates the field with the given +key+ and +val+ if it does not exist.
|
250
|
+
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
|
56
251
|
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
# p request.get_fields('X-My-Header') #=> ["a", "b", "c"]
|
252
|
+
# req = Net::HTTP::Get.new(uri)
|
253
|
+
# req.add_field('Foo', 'bar')
|
254
|
+
# req['Foo'] # => "bar"
|
255
|
+
# req.add_field('Foo', 'baz')
|
256
|
+
# req['Foo'] # => "bar, baz"
|
257
|
+
# req.add_field('Foo', %w[baz bam])
|
258
|
+
# req['Foo'] # => "bar, baz, baz, bam"
|
259
|
+
# req.get_fields('Foo') # => ["bar", "baz", "baz", "bam"]
|
66
260
|
#
|
67
261
|
def add_field(key, val)
|
68
262
|
stringified_downcased_key = key.downcase.to_s
|
@@ -101,16 +295,13 @@ module Net::HTTPHeader
|
|
101
295
|
end
|
102
296
|
end
|
103
297
|
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
# header fields without any processing. See also #[].
|
298
|
+
# Returns the array field value for the given +key+,
|
299
|
+
# or +nil+ if there is no such field;
|
300
|
+
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
|
108
301
|
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
#
|
112
|
-
# p response['Set-Cookie']
|
113
|
-
# #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"
|
302
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
303
|
+
# res.get_fields('Connection') # => ["keep-alive"]
|
304
|
+
# res.get_fields('Nosuch') # => nil
|
114
305
|
#
|
115
306
|
def get_fields(key)
|
116
307
|
stringified_downcased_key = key.downcase.to_s
|
@@ -118,24 +309,58 @@ module Net::HTTPHeader
|
|
118
309
|
@header[stringified_downcased_key].dup
|
119
310
|
end
|
120
311
|
|
121
|
-
#
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
312
|
+
# call-seq:
|
313
|
+
# fetch(key, default_val = nil) {|key| ... } -> object
|
314
|
+
# fetch(key, default_val = nil) -> value or default_val
|
315
|
+
#
|
316
|
+
# With a block, returns the string value for +key+ if it exists;
|
317
|
+
# otherwise returns the value of the block;
|
318
|
+
# ignores the +default_val+;
|
319
|
+
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
|
320
|
+
#
|
321
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
322
|
+
#
|
323
|
+
# # Field exists; block not called.
|
324
|
+
# res.fetch('Connection') do |value|
|
325
|
+
# fail 'Cannot happen'
|
326
|
+
# end # => "keep-alive"
|
327
|
+
#
|
328
|
+
# # Field does not exist; block called.
|
329
|
+
# res.fetch('Nosuch') do |value|
|
330
|
+
# value.downcase
|
331
|
+
# end # => "nosuch"
|
332
|
+
#
|
333
|
+
# With no block, returns the string value for +key+ if it exists;
|
334
|
+
# otherwise, returns +default_val+ if it was given;
|
335
|
+
# otherwise raises an exception:
|
336
|
+
#
|
337
|
+
# res.fetch('Connection', 'Foo') # => "keep-alive"
|
338
|
+
# res.fetch('Nosuch', 'Foo') # => "Foo"
|
339
|
+
# res.fetch('Nosuch') # Raises KeyError.
|
340
|
+
#
|
125
341
|
def fetch(key, *args, &block) #:yield: +key+
|
126
342
|
a = @header.fetch(key.downcase.to_s, *args, &block)
|
127
343
|
a.kind_of?(Array) ? a.join(', ') : a
|
128
344
|
end
|
129
345
|
|
130
|
-
#
|
131
|
-
# and value to the code block supplied.
|
346
|
+
# Calls the block with each key/value pair:
|
132
347
|
#
|
133
|
-
#
|
348
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
349
|
+
# res.each_header do |key, value|
|
350
|
+
# p [key, value] if key.start_with?('c')
|
351
|
+
# end
|
134
352
|
#
|
135
|
-
#
|
353
|
+
# Output:
|
136
354
|
#
|
137
|
-
#
|
355
|
+
# ["content-type", "application/json; charset=utf-8"]
|
356
|
+
# ["connection", "keep-alive"]
|
357
|
+
# ["cache-control", "max-age=43200"]
|
358
|
+
# ["cf-cache-status", "HIT"]
|
359
|
+
# ["cf-ray", "771d17e9bc542cf5-ORD"]
|
138
360
|
#
|
361
|
+
# Returns an enumerator if no block is given.
|
362
|
+
#
|
363
|
+
# Net::HTTPHeader#each is an alias for Net::HTTPHeader#each_header.
|
139
364
|
def each_header #:yield: +key+, +value+
|
140
365
|
block_given? or return enum_for(__method__) { @header.size }
|
141
366
|
@header.each do |k,va|
|
@@ -145,10 +370,24 @@ module Net::HTTPHeader
|
|
145
370
|
|
146
371
|
alias each each_header
|
147
372
|
|
148
|
-
#
|
149
|
-
#
|
373
|
+
# Calls the block with each field key:
|
374
|
+
#
|
375
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
376
|
+
# res.each_key do |key|
|
377
|
+
# p key if key.start_with?('c')
|
378
|
+
# end
|
379
|
+
#
|
380
|
+
# Output:
|
381
|
+
#
|
382
|
+
# "content-type"
|
383
|
+
# "connection"
|
384
|
+
# "cache-control"
|
385
|
+
# "cf-cache-status"
|
386
|
+
# "cf-ray"
|
150
387
|
#
|
151
388
|
# Returns an enumerator if no block is given.
|
389
|
+
#
|
390
|
+
# Net::HTTPHeader#each_name is an alias for Net::HTTPHeader#each_key.
|
152
391
|
def each_name(&block) #:yield: +key+
|
153
392
|
block_given? or return enum_for(__method__) { @header.size }
|
154
393
|
@header.each_key(&block)
|
@@ -156,12 +395,23 @@ module Net::HTTPHeader
|
|
156
395
|
|
157
396
|
alias each_key each_name
|
158
397
|
|
159
|
-
#
|
160
|
-
#
|
398
|
+
# Calls the block with each capitalized field name:
|
399
|
+
#
|
400
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
401
|
+
# res.each_capitalized_name do |key|
|
402
|
+
# p key if key.start_with?('C')
|
403
|
+
# end
|
404
|
+
#
|
405
|
+
# Output:
|
161
406
|
#
|
162
|
-
#
|
163
|
-
#
|
164
|
-
#
|
407
|
+
# "Content-Type"
|
408
|
+
# "Connection"
|
409
|
+
# "Cache-Control"
|
410
|
+
# "Cf-Cache-Status"
|
411
|
+
# "Cf-Ray"
|
412
|
+
#
|
413
|
+
# The capitalization is system-dependent;
|
414
|
+
# see {Case Mapping}[https://docs.ruby-lang.org/en/master/case_mapping_rdoc.html].
|
165
415
|
#
|
166
416
|
# Returns an enumerator if no block is given.
|
167
417
|
def each_capitalized_name #:yield: +key+
|
@@ -171,8 +421,18 @@ module Net::HTTPHeader
|
|
171
421
|
end
|
172
422
|
end
|
173
423
|
|
174
|
-
#
|
175
|
-
#
|
424
|
+
# Calls the block with each string field value:
|
425
|
+
#
|
426
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
427
|
+
# res.each_value do |value|
|
428
|
+
# p value if value.start_with?('c')
|
429
|
+
# end
|
430
|
+
#
|
431
|
+
# Output:
|
432
|
+
#
|
433
|
+
# "chunked"
|
434
|
+
# "cf-q-config;dur=6.0000002122251e-06"
|
435
|
+
# "cloudflare"
|
176
436
|
#
|
177
437
|
# Returns an enumerator if no block is given.
|
178
438
|
def each_value #:yield: +value+
|
@@ -182,32 +442,45 @@ module Net::HTTPHeader
|
|
182
442
|
end
|
183
443
|
end
|
184
444
|
|
185
|
-
# Removes
|
445
|
+
# Removes the header for the given case-insensitive +key+
|
446
|
+
# (see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]);
|
447
|
+
# returns the deleted value, or +nil+ if no such field exists:
|
448
|
+
#
|
449
|
+
# req = Net::HTTP::Get.new(uri)
|
450
|
+
# req.delete('Accept') # => ["*/*"]
|
451
|
+
# req.delete('Nosuch') # => nil
|
452
|
+
#
|
186
453
|
def delete(key)
|
187
454
|
@header.delete(key.downcase.to_s)
|
188
455
|
end
|
189
456
|
|
190
|
-
# true if +key+
|
457
|
+
# Returns +true+ if the field for the case-insensitive +key+ exists, +false+ otherwise:
|
458
|
+
#
|
459
|
+
# req = Net::HTTP::Get.new(uri)
|
460
|
+
# req.key?('Accept') # => true
|
461
|
+
# req.key?('Nosuch') # => false
|
462
|
+
#
|
191
463
|
def key?(key)
|
192
464
|
@header.key?(key.downcase.to_s)
|
193
465
|
end
|
194
466
|
|
195
|
-
# Returns a
|
196
|
-
#
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
467
|
+
# Returns a hash of the key/value pairs:
|
468
|
+
#
|
469
|
+
# req = Net::HTTP::Get.new(uri)
|
470
|
+
# req.to_hash
|
471
|
+
# # =>
|
472
|
+
# {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"],
|
473
|
+
# "accept"=>["*/*"],
|
474
|
+
# "user-agent"=>["Ruby"],
|
475
|
+
# "host"=>["jsonplaceholder.typicode.com"]}
|
476
|
+
#
|
200
477
|
def to_hash
|
201
478
|
@header.dup
|
202
479
|
end
|
203
480
|
|
204
|
-
#
|
481
|
+
# Like #each_header, but the keys are returned in capitalized form.
|
205
482
|
#
|
206
|
-
#
|
207
|
-
# capitalization may not match that used by the remote HTTP
|
208
|
-
# server in its response.
|
209
|
-
#
|
210
|
-
# Returns an enumerator if no block is given.
|
483
|
+
# Net::HTTPHeader#canonical_each is an alias for Net::HTTPHeader#each_capitalized.
|
211
484
|
def each_capitalized
|
212
485
|
block_given? or return enum_for(__method__) { @header.size }
|
213
486
|
@header.each do |k,v|
|
@@ -222,8 +495,17 @@ module Net::HTTPHeader
|
|
222
495
|
end
|
223
496
|
private :capitalize
|
224
497
|
|
225
|
-
# Returns an
|
226
|
-
#
|
498
|
+
# Returns an array of Range objects that represent
|
499
|
+
# the value of field <tt>'Range'</tt>,
|
500
|
+
# or +nil+ if there is no such field;
|
501
|
+
# see {Range request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#range-request-header]:
|
502
|
+
#
|
503
|
+
# req = Net::HTTP::Get.new(uri)
|
504
|
+
# req['Range'] = 'bytes=0-99,200-299,400-499'
|
505
|
+
# req.range # => [0..99, 200..299, 400..499]
|
506
|
+
# req.delete('Range')
|
507
|
+
# req.range # # => nil
|
508
|
+
#
|
227
509
|
def range
|
228
510
|
return nil unless @header['range']
|
229
511
|
|
@@ -266,14 +548,31 @@ module Net::HTTPHeader
|
|
266
548
|
result
|
267
549
|
end
|
268
550
|
|
269
|
-
#
|
270
|
-
#
|
271
|
-
#
|
272
|
-
#
|
551
|
+
# call-seq:
|
552
|
+
# set_range(length) -> length
|
553
|
+
# set_range(offset, length) -> range
|
554
|
+
# set_range(begin..length) -> range
|
555
|
+
#
|
556
|
+
# Sets the value for field <tt>'Range'</tt>;
|
557
|
+
# see {Range request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#range-request-header]:
|
558
|
+
#
|
559
|
+
# With argument +length+:
|
560
|
+
#
|
561
|
+
# req = Net::HTTP::Get.new(uri)
|
562
|
+
# req.set_range(100) # => 100
|
563
|
+
# req['Range'] # => "bytes=0-99"
|
273
564
|
#
|
274
|
-
#
|
275
|
-
# req.set_range 0, 1023
|
565
|
+
# With arguments +offset+ and +length+:
|
276
566
|
#
|
567
|
+
# req.set_range(100, 100) # => 100...200
|
568
|
+
# req['Range'] # => "bytes=100-199"
|
569
|
+
#
|
570
|
+
# With argument +range+:
|
571
|
+
#
|
572
|
+
# req.set_range(100..199) # => 100..199
|
573
|
+
# req['Range'] # => "bytes=100-199"
|
574
|
+
#
|
575
|
+
# Net::HTTPHeader#range= is an alias for Net::HTTPHeader#set_range.
|
277
576
|
def set_range(r, e = nil)
|
278
577
|
unless r
|
279
578
|
@header.delete 'range'
|
@@ -305,8 +604,15 @@ module Net::HTTPHeader
|
|
305
604
|
|
306
605
|
alias range= set_range
|
307
606
|
|
308
|
-
# Returns
|
309
|
-
#
|
607
|
+
# Returns the value of field <tt>'Content-Length'</tt> as an integer,
|
608
|
+
# or +nil+ if there is no such field;
|
609
|
+
# see {Content-Length request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-length-request-header]:
|
610
|
+
#
|
611
|
+
# res = Net::HTTP.get_response(hostname, '/nosuch/1')
|
612
|
+
# res.content_length # => 2
|
613
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
614
|
+
# res.content_length # => nil
|
615
|
+
#
|
310
616
|
def content_length
|
311
617
|
return nil unless key?('Content-Length')
|
312
618
|
len = self['Content-Length'].slice(/\d+/) or
|
@@ -314,6 +620,20 @@ module Net::HTTPHeader
|
|
314
620
|
len.to_i
|
315
621
|
end
|
316
622
|
|
623
|
+
# Sets the value of field <tt>'Content-Length'</tt> to the given numeric;
|
624
|
+
# see {Content-Length response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-length-response-header]:
|
625
|
+
#
|
626
|
+
# _uri = uri.dup
|
627
|
+
# hostname = _uri.hostname # => "jsonplaceholder.typicode.com"
|
628
|
+
# _uri.path = '/posts' # => "/posts"
|
629
|
+
# req = Net::HTTP::Post.new(_uri) # => #<Net::HTTP::Post POST>
|
630
|
+
# req.body = '{"title": "foo","body": "bar","userId": 1}'
|
631
|
+
# req.content_length = req.body.size # => 42
|
632
|
+
# req.content_type = 'application/json'
|
633
|
+
# res = Net::HTTP.start(hostname) do |http|
|
634
|
+
# http.request(req)
|
635
|
+
# end # => #<Net::HTTPCreated 201 Created readbody=true>
|
636
|
+
#
|
317
637
|
def content_length=(len)
|
318
638
|
unless len
|
319
639
|
@header.delete 'content-length'
|
@@ -322,53 +642,99 @@ module Net::HTTPHeader
|
|
322
642
|
@header['content-length'] = [len.to_i.to_s]
|
323
643
|
end
|
324
644
|
|
325
|
-
# Returns
|
326
|
-
#
|
327
|
-
#
|
328
|
-
#
|
645
|
+
# Returns +true+ if field <tt>'Transfer-Encoding'</tt>
|
646
|
+
# exists and has value <tt>'chunked'</tt>,
|
647
|
+
# +false+ otherwise;
|
648
|
+
# see {Transfer-Encoding response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#transfer-encoding-response-header]:
|
649
|
+
#
|
650
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
651
|
+
# res['Transfer-Encoding'] # => "chunked"
|
652
|
+
# res.chunked? # => true
|
653
|
+
#
|
329
654
|
def chunked?
|
330
655
|
return false unless @header['transfer-encoding']
|
331
656
|
field = self['Transfer-Encoding']
|
332
657
|
(/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
|
333
658
|
end
|
334
659
|
|
335
|
-
# Returns a Range object
|
336
|
-
#
|
337
|
-
#
|
338
|
-
#
|
660
|
+
# Returns a Range object representing the value of field
|
661
|
+
# <tt>'Content-Range'</tt>, or +nil+ if no such field exists;
|
662
|
+
# see {Content-Range response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-range-response-header]:
|
663
|
+
#
|
664
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
665
|
+
# res['Content-Range'] # => nil
|
666
|
+
# res['Content-Range'] = 'bytes 0-499/1000'
|
667
|
+
# res['Content-Range'] # => "bytes 0-499/1000"
|
668
|
+
# res.content_range # => 0..499
|
669
|
+
#
|
339
670
|
def content_range
|
340
671
|
return nil unless @header['content-range']
|
341
|
-
m = %r
|
672
|
+
m = %r<\A\s*(\w+)\s+(\d+)-(\d+)/(\d+|\*)>.match(self['Content-Range']) or
|
342
673
|
raise Net::HTTPHeaderSyntaxError, 'wrong Content-Range format'
|
343
|
-
m[1]
|
674
|
+
return unless m[1] == 'bytes'
|
675
|
+
m[2].to_i .. m[3].to_i
|
344
676
|
end
|
345
677
|
|
346
|
-
#
|
678
|
+
# Returns the integer representing length of the value of field
|
679
|
+
# <tt>'Content-Range'</tt>, or +nil+ if no such field exists;
|
680
|
+
# see {Content-Range response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-range-response-header]:
|
681
|
+
#
|
682
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
683
|
+
# res['Content-Range'] # => nil
|
684
|
+
# res['Content-Range'] = 'bytes 0-499/1000'
|
685
|
+
# res.range_length # => 500
|
686
|
+
#
|
347
687
|
def range_length
|
348
688
|
r = content_range() or return nil
|
349
689
|
r.end - r.begin + 1
|
350
690
|
end
|
351
691
|
|
352
|
-
# Returns
|
353
|
-
#
|
692
|
+
# Returns the {media type}[https://en.wikipedia.org/wiki/Media_type]
|
693
|
+
# from the value of field <tt>'Content-Type'</tt>,
|
694
|
+
# or +nil+ if no such field exists;
|
695
|
+
# see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
|
696
|
+
#
|
697
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
698
|
+
# res['content-type'] # => "application/json; charset=utf-8"
|
699
|
+
# res.content_type # => "application/json"
|
700
|
+
#
|
354
701
|
def content_type
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
702
|
+
main = main_type()
|
703
|
+
return nil unless main
|
704
|
+
|
705
|
+
sub = sub_type()
|
706
|
+
if sub
|
707
|
+
"#{main}/#{sub}"
|
708
|
+
else
|
709
|
+
main
|
359
710
|
end
|
360
711
|
end
|
361
712
|
|
362
|
-
# Returns
|
363
|
-
#
|
713
|
+
# Returns the leading ('type') part of the
|
714
|
+
# {media type}[https://en.wikipedia.org/wiki/Media_type]
|
715
|
+
# from the value of field <tt>'Content-Type'</tt>,
|
716
|
+
# or +nil+ if no such field exists;
|
717
|
+
# see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
|
718
|
+
#
|
719
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
720
|
+
# res['content-type'] # => "application/json; charset=utf-8"
|
721
|
+
# res.main_type # => "application"
|
722
|
+
#
|
364
723
|
def main_type
|
365
724
|
return nil unless @header['content-type']
|
366
725
|
self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
|
367
726
|
end
|
368
727
|
|
369
|
-
# Returns
|
370
|
-
#
|
371
|
-
#
|
728
|
+
# Returns the trailing ('subtype') part of the
|
729
|
+
# {media type}[https://en.wikipedia.org/wiki/Media_type]
|
730
|
+
# from the value of field <tt>'Content-Type'</tt>,
|
731
|
+
# or +nil+ if no such field exists;
|
732
|
+
# see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
|
733
|
+
#
|
734
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
735
|
+
# res['content-type'] # => "application/json; charset=utf-8"
|
736
|
+
# res.sub_type # => "json"
|
737
|
+
#
|
372
738
|
def sub_type
|
373
739
|
return nil unless @header['content-type']
|
374
740
|
_, sub = *self['Content-Type'].split(';').first.to_s.split('/')
|
@@ -376,9 +742,14 @@ module Net::HTTPHeader
|
|
376
742
|
sub.strip
|
377
743
|
end
|
378
744
|
|
379
|
-
#
|
380
|
-
#
|
381
|
-
#
|
745
|
+
# Returns the trailing ('parameters') part of the value of field <tt>'Content-Type'</tt>,
|
746
|
+
# or +nil+ if no such field exists;
|
747
|
+
# see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
|
748
|
+
#
|
749
|
+
# res = Net::HTTP.get_response(hostname, '/todos/1')
|
750
|
+
# res['content-type'] # => "application/json; charset=utf-8"
|
751
|
+
# res.type_params # => {"charset"=>"utf-8"}
|
752
|
+
#
|
382
753
|
def type_params
|
383
754
|
result = {}
|
384
755
|
list = self['Content-Type'].to_s.split(';')
|
@@ -390,29 +761,54 @@ module Net::HTTPHeader
|
|
390
761
|
result
|
391
762
|
end
|
392
763
|
|
393
|
-
# Sets the
|
394
|
-
#
|
395
|
-
#
|
396
|
-
#
|
764
|
+
# Sets the value of field <tt>'Content-Type'</tt>;
|
765
|
+
# returns the new value;
|
766
|
+
# see {Content-Type request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-request-header]:
|
767
|
+
#
|
768
|
+
# req = Net::HTTP::Get.new(uri)
|
769
|
+
# req.set_content_type('application/json') # => ["application/json"]
|
770
|
+
#
|
771
|
+
# Net::HTTPHeader#content_type= is an alias for Net::HTTPHeader#set_content_type.
|
397
772
|
def set_content_type(type, params = {})
|
398
773
|
@header['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')]
|
399
774
|
end
|
400
775
|
|
401
776
|
alias content_type= set_content_type
|
402
777
|
|
403
|
-
#
|
404
|
-
#
|
405
|
-
#
|
406
|
-
#
|
778
|
+
# Sets the request body to a URL-encoded string derived from argument +params+,
|
779
|
+
# and sets request header field <tt>'Content-Type'</tt>
|
780
|
+
# to <tt>'application/x-www-form-urlencoded'</tt>.
|
781
|
+
#
|
782
|
+
# The resulting request is suitable for HTTP request +POST+ or +PUT+.
|
783
|
+
#
|
784
|
+
# Argument +params+ must be suitable for use as argument +enum+ to
|
785
|
+
# {URI.encode_www_form}[https://docs.ruby-lang.org/en/master/URI.html#method-c-encode_www_form].
|
786
|
+
#
|
787
|
+
# With only argument +params+ given,
|
788
|
+
# sets the body to a URL-encoded string with the default separator <tt>'&'</tt>:
|
789
|
+
#
|
790
|
+
# req = Net::HTTP::Post.new('example.com')
|
791
|
+
#
|
792
|
+
# req.set_form_data(q: 'ruby', lang: 'en')
|
793
|
+
# req.body # => "q=ruby&lang=en"
|
794
|
+
# req['Content-Type'] # => "application/x-www-form-urlencoded"
|
407
795
|
#
|
408
|
-
#
|
409
|
-
#
|
796
|
+
# req.set_form_data([['q', 'ruby'], ['lang', 'en']])
|
797
|
+
# req.body # => "q=ruby&lang=en"
|
410
798
|
#
|
411
|
-
#
|
412
|
-
#
|
413
|
-
# http.form_data = {"q" => ["ruby", "perl"], "lang" => "en"}
|
414
|
-
# http.set_form_data({"q" => "ruby", "lang" => "en"}, ';')
|
799
|
+
# req.set_form_data(q: ['ruby', 'perl'], lang: 'en')
|
800
|
+
# req.body # => "q=ruby&q=perl&lang=en"
|
415
801
|
#
|
802
|
+
# req.set_form_data([['q', 'ruby'], ['q', 'perl'], ['lang', 'en']])
|
803
|
+
# req.body # => "q=ruby&q=perl&lang=en"
|
804
|
+
#
|
805
|
+
# With string argument +sep+ also given,
|
806
|
+
# uses that string as the separator:
|
807
|
+
#
|
808
|
+
# req.set_form_data({q: 'ruby', lang: 'en'}, '|')
|
809
|
+
# req.body # => "q=ruby|lang=en"
|
810
|
+
#
|
811
|
+
# Net::HTTPHeader#form_data= is an alias for Net::HTTPHeader#set_form_data.
|
416
812
|
def set_form_data(params, sep = '&')
|
417
813
|
query = URI.encode_www_form(params)
|
418
814
|
query.gsub!(/&/, sep) if sep != '&'
|
@@ -422,53 +818,108 @@ module Net::HTTPHeader
|
|
422
818
|
|
423
819
|
alias form_data= set_form_data
|
424
820
|
|
425
|
-
#
|
426
|
-
#
|
427
|
-
#
|
428
|
-
#
|
429
|
-
#
|
430
|
-
#
|
431
|
-
#
|
432
|
-
#
|
433
|
-
#
|
434
|
-
#
|
435
|
-
#
|
436
|
-
#
|
437
|
-
#
|
438
|
-
#
|
439
|
-
#
|
440
|
-
#
|
441
|
-
#
|
442
|
-
#
|
443
|
-
#
|
444
|
-
#
|
445
|
-
#
|
446
|
-
#
|
447
|
-
#
|
448
|
-
#
|
449
|
-
# the
|
450
|
-
#
|
451
|
-
#
|
452
|
-
#
|
453
|
-
#
|
454
|
-
#
|
455
|
-
#
|
456
|
-
#
|
457
|
-
#
|
458
|
-
#
|
459
|
-
#
|
460
|
-
#
|
461
|
-
#
|
462
|
-
#
|
463
|
-
#
|
464
|
-
#
|
465
|
-
#
|
466
|
-
#
|
467
|
-
#
|
468
|
-
#
|
469
|
-
#
|
470
|
-
#
|
471
|
-
#
|
821
|
+
# Stores form data to be used in a +POST+ or +PUT+ request.
|
822
|
+
#
|
823
|
+
# The form data given in +params+ consists of zero or more fields;
|
824
|
+
# each field is:
|
825
|
+
#
|
826
|
+
# - A scalar value.
|
827
|
+
# - A name/value pair.
|
828
|
+
# - An IO stream opened for reading.
|
829
|
+
#
|
830
|
+
# Argument +params+ should be an
|
831
|
+
# {Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html#module-Enumerable-label-Enumerable+in+Ruby+Classes]
|
832
|
+
# (method <tt>params.map</tt> will be called),
|
833
|
+
# and is often an array or hash.
|
834
|
+
#
|
835
|
+
# First, we set up a request:
|
836
|
+
#
|
837
|
+
# _uri = uri.dup
|
838
|
+
# _uri.path ='/posts'
|
839
|
+
# req = Net::HTTP::Post.new(_uri)
|
840
|
+
#
|
841
|
+
# <b>Argument +params+ As an Array</b>
|
842
|
+
#
|
843
|
+
# When +params+ is an array,
|
844
|
+
# each of its elements is a subarray that defines a field;
|
845
|
+
# the subarray may contain:
|
846
|
+
#
|
847
|
+
# - One string:
|
848
|
+
#
|
849
|
+
# req.set_form([['foo'], ['bar'], ['baz']])
|
850
|
+
#
|
851
|
+
# - Two strings:
|
852
|
+
#
|
853
|
+
# req.set_form([%w[foo 0], %w[bar 1], %w[baz 2]])
|
854
|
+
#
|
855
|
+
# - When argument +enctype+ (see below) is given as
|
856
|
+
# <tt>'multipart/form-data'</tt>:
|
857
|
+
#
|
858
|
+
# - A string name and an IO stream opened for reading:
|
859
|
+
#
|
860
|
+
# require 'stringio'
|
861
|
+
# req.set_form([['file', StringIO.new('Ruby is cool.')]])
|
862
|
+
#
|
863
|
+
# - A string name, an IO stream opened for reading,
|
864
|
+
# and an options hash, which may contain these entries:
|
865
|
+
#
|
866
|
+
# - +:filename+: The name of the file to use.
|
867
|
+
# - +:content_type+: The content type of the uploaded file.
|
868
|
+
#
|
869
|
+
# Example:
|
870
|
+
#
|
871
|
+
# req.set_form([['file', file, {filename: "other-filename.foo"}]]
|
872
|
+
#
|
873
|
+
# The various forms may be mixed:
|
874
|
+
#
|
875
|
+
# req.set_form(['foo', %w[bar 1], ['file', file]])
|
876
|
+
#
|
877
|
+
# <b>Argument +params+ As a Hash</b>
|
878
|
+
#
|
879
|
+
# When +params+ is a hash,
|
880
|
+
# each of its entries is a name/value pair that defines a field:
|
881
|
+
#
|
882
|
+
# - The name is a string.
|
883
|
+
# - The value may be:
|
884
|
+
#
|
885
|
+
# - +nil+.
|
886
|
+
# - Another string.
|
887
|
+
# - An IO stream opened for reading
|
888
|
+
# (only when argument +enctype+ -- see below -- is given as
|
889
|
+
# <tt>'multipart/form-data'</tt>).
|
890
|
+
#
|
891
|
+
# Examples:
|
892
|
+
#
|
893
|
+
# # Nil-valued fields.
|
894
|
+
# req.set_form({'foo' => nil, 'bar' => nil, 'baz' => nil})
|
895
|
+
#
|
896
|
+
# # String-valued fields.
|
897
|
+
# req.set_form({'foo' => 0, 'bar' => 1, 'baz' => 2})
|
898
|
+
#
|
899
|
+
# # IO-valued field.
|
900
|
+
# require 'stringio'
|
901
|
+
# req.set_form({'file' => StringIO.new('Ruby is cool.')})
|
902
|
+
#
|
903
|
+
# # Mixture of fields.
|
904
|
+
# req.set_form({'foo' => nil, 'bar' => 1, 'file' => file})
|
905
|
+
#
|
906
|
+
# Optional argument +enctype+ specifies the value to be given
|
907
|
+
# to field <tt>'Content-Type'</tt>, and must be one of:
|
908
|
+
#
|
909
|
+
# - <tt>'application/x-www-form-urlencoded'</tt> (the default).
|
910
|
+
# - <tt>'multipart/form-data'</tt>;
|
911
|
+
# see {RFC 7578}[https://www.rfc-editor.org/rfc/rfc7578].
|
912
|
+
#
|
913
|
+
# Optional argument +formopt+ is a hash of options
|
914
|
+
# (applicable only when argument +enctype+
|
915
|
+
# is <tt>'multipart/form-data'</tt>)
|
916
|
+
# that may include the following entries:
|
917
|
+
#
|
918
|
+
# - +:boundary+: The value is the boundary string for the multipart message.
|
919
|
+
# If not given, the boundary is a random string.
|
920
|
+
# See {Boundary}[https://www.rfc-editor.org/rfc/rfc7578#section-4.1].
|
921
|
+
# - +:charset+: Value is the character set for the form submission.
|
922
|
+
# Field names and values of non-file fields should be encoded with this charset.
|
472
923
|
#
|
473
924
|
def set_form(params, enctype='application/x-www-form-urlencoded', formopt={})
|
474
925
|
@body_data = params
|
@@ -484,12 +935,24 @@ module Net::HTTPHeader
|
|
484
935
|
end
|
485
936
|
end
|
486
937
|
|
487
|
-
#
|
938
|
+
# Sets header <tt>'Authorization'</tt> using the given
|
939
|
+
# +account+ and +password+ strings:
|
940
|
+
#
|
941
|
+
# req.basic_auth('my_account', 'my_password')
|
942
|
+
# req['Authorization']
|
943
|
+
# # => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
|
944
|
+
#
|
488
945
|
def basic_auth(account, password)
|
489
946
|
@header['authorization'] = [basic_encode(account, password)]
|
490
947
|
end
|
491
948
|
|
492
|
-
#
|
949
|
+
# Sets header <tt>'Proxy-Authorization'</tt> using the given
|
950
|
+
# +account+ and +password+ strings:
|
951
|
+
#
|
952
|
+
# req.proxy_basic_auth('my_account', 'my_password')
|
953
|
+
# req['Proxy-Authorization']
|
954
|
+
# # => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
|
955
|
+
#
|
493
956
|
def proxy_basic_auth(account, password)
|
494
957
|
@header['proxy-authorization'] = [basic_encode(account, password)]
|
495
958
|
end
|
@@ -499,6 +962,7 @@ module Net::HTTPHeader
|
|
499
962
|
end
|
500
963
|
private :basic_encode
|
501
964
|
|
965
|
+
# Returns whether the HTTP session is to be closed.
|
502
966
|
def connection_close?
|
503
967
|
token = /(?:\A|,)\s*close\s*(?:\z|,)/i
|
504
968
|
@header['connection']&.grep(token) {return true}
|
@@ -506,6 +970,7 @@ module Net::HTTPHeader
|
|
506
970
|
false
|
507
971
|
end
|
508
972
|
|
973
|
+
# Returns whether the HTTP session is to be kept alive.
|
509
974
|
def connection_keep_alive?
|
510
975
|
token = /(?:\A|,)\s*keep-alive\s*(?:\z|,)/i
|
511
976
|
@header['connection']&.grep(token) {return true}
|