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.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
#
|
3
3
|
# = net/http.rb
|
4
4
|
#
|
@@ -22,6 +22,7 @@
|
|
22
22
|
|
23
23
|
require 'net/protocol'
|
24
24
|
require 'uri'
|
25
|
+
require 'resolv'
|
25
26
|
autoload :OpenSSL, 'openssl'
|
26
27
|
|
27
28
|
module Net #:nodoc:
|
@@ -31,387 +32,717 @@ module Net #:nodoc:
|
|
31
32
|
class HTTPHeaderSyntaxError < StandardError; end
|
32
33
|
# :startdoc:
|
33
34
|
|
34
|
-
#
|
35
|
+
# \Class \Net::HTTP provides a rich library that implements the client
|
36
|
+
# in a client-server model that uses the \HTTP request-response protocol.
|
37
|
+
# For information about \HTTP, see:
|
38
|
+
#
|
39
|
+
# - {Hypertext Transfer Protocol}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol].
|
40
|
+
# - {Technical overview}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview].
|
41
|
+
#
|
42
|
+
# == About the Examples
|
43
|
+
#
|
44
|
+
# :include: doc/net-http/examples.rdoc
|
45
|
+
#
|
46
|
+
# == Strategies
|
47
|
+
#
|
48
|
+
# - If you will make only a few GET requests,
|
49
|
+
# consider using {OpenURI}[https://docs.ruby-lang.org/en/master/OpenURI.html].
|
50
|
+
# - If you will make only a few requests of all kinds,
|
51
|
+
# consider using the various singleton convenience methods in this class.
|
52
|
+
# Each of the following methods automatically starts and finishes
|
53
|
+
# a {session}[rdoc-ref:Net::HTTP@Sessions] that sends a single request:
|
54
|
+
#
|
55
|
+
# # Return string response body.
|
56
|
+
# Net::HTTP.get(hostname, path)
|
57
|
+
# Net::HTTP.get(uri)
|
58
|
+
#
|
59
|
+
# # Write string response body to $stdout.
|
60
|
+
# Net::HTTP.get_print(hostname, path)
|
61
|
+
# Net::HTTP.get_print(uri)
|
62
|
+
#
|
63
|
+
# # Return response as Net::HTTPResponse object.
|
64
|
+
# Net::HTTP.get_response(hostname, path)
|
65
|
+
# Net::HTTP.get_response(uri)
|
66
|
+
# data = '{"title": "foo", "body": "bar", "userId": 1}'
|
67
|
+
# Net::HTTP.post(uri, data)
|
68
|
+
# params = {title: 'foo', body: 'bar', userId: 1}
|
69
|
+
# Net::HTTP.post_form(uri, params)
|
70
|
+
#
|
71
|
+
# - If performance is important, consider using sessions, which lower request overhead.
|
72
|
+
# This {session}[rdoc-ref:Net::HTTP@Sessions] has multiple requests for
|
73
|
+
# {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]
|
74
|
+
# and {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
|
75
|
+
#
|
76
|
+
# Net::HTTP.start(hostname) do |http|
|
77
|
+
# # Session started automatically before block execution.
|
78
|
+
# http.get(path)
|
79
|
+
# http.head(path)
|
80
|
+
# body = 'Some text'
|
81
|
+
# http.post(path, body) # Can also have a block.
|
82
|
+
# http.put(path, body)
|
83
|
+
# http.delete(path)
|
84
|
+
# http.options(path)
|
85
|
+
# http.trace(path)
|
86
|
+
# http.patch(path, body) # Can also have a block.
|
87
|
+
# http.copy(path)
|
88
|
+
# http.lock(path, body)
|
89
|
+
# http.mkcol(path, body)
|
90
|
+
# http.move(path)
|
91
|
+
# http.propfind(path, body)
|
92
|
+
# http.proppatch(path, body)
|
93
|
+
# http.unlock(path, body)
|
94
|
+
# # Session finished automatically at block exit.
|
95
|
+
# end
|
35
96
|
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# [
|
97
|
+
# The methods cited above are convenience methods that, via their few arguments,
|
98
|
+
# allow minimal control over the requests.
|
99
|
+
# For greater control, consider using {request objects}[rdoc-ref:Net::HTTPRequest].
|
39
100
|
#
|
40
|
-
#
|
41
|
-
# URI::HTTP#port and URI::HTTP#request_uri are designed to work with
|
42
|
-
# Net::HTTP.
|
101
|
+
# == URIs
|
43
102
|
#
|
44
|
-
#
|
103
|
+
# On the internet, a URI
|
104
|
+
# ({Universal Resource Identifier}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier])
|
105
|
+
# is a string that identifies a particular resource.
|
106
|
+
# It consists of some or all of: scheme, hostname, path, query, and fragment;
|
107
|
+
# see {URI syntax}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax].
|
45
108
|
#
|
46
|
-
#
|
109
|
+
# A Ruby {URI::Generic}[https://docs.ruby-lang.org/en/master/URI/Generic.html] object
|
110
|
+
# represents an internet URI.
|
111
|
+
# It provides, among others, methods
|
112
|
+
# +scheme+, +hostname+, +path+, +query+, and +fragment+.
|
47
113
|
#
|
48
|
-
#
|
114
|
+
# === Schemes
|
49
115
|
#
|
50
|
-
#
|
116
|
+
# An internet \URI has
|
117
|
+
# a {scheme}[https://en.wikipedia.org/wiki/List_of_URI_schemes].
|
51
118
|
#
|
52
|
-
#
|
119
|
+
# The two schemes supported in \Net::HTTP are <tt>'https'</tt> and <tt>'http'</tt>:
|
53
120
|
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
# requests.
|
121
|
+
# uri.scheme # => "https"
|
122
|
+
# URI('http://example.com').scheme # => "http"
|
57
123
|
#
|
58
|
-
# ===
|
124
|
+
# === Hostnames
|
59
125
|
#
|
60
|
-
#
|
126
|
+
# A hostname identifies a server (host) to which requests may be sent:
|
61
127
|
#
|
62
|
-
#
|
128
|
+
# hostname = uri.hostname # => "jsonplaceholder.typicode.com"
|
129
|
+
# Net::HTTP.start(hostname) do |http|
|
130
|
+
# # Some HTTP stuff.
|
131
|
+
# end
|
63
132
|
#
|
64
|
-
#
|
65
|
-
# Net::HTTP.get(uri) # => String
|
133
|
+
# === Paths
|
66
134
|
#
|
67
|
-
#
|
135
|
+
# A host-specific path identifies a resource on the host:
|
68
136
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
137
|
+
# _uri = uri.dup
|
138
|
+
# _uri.path = '/todos/1'
|
139
|
+
# hostname = _uri.hostname
|
140
|
+
# path = _uri.path
|
141
|
+
# Net::HTTP.get(hostname, path)
|
72
142
|
#
|
73
|
-
#
|
74
|
-
# puts res.body if res.is_a?(Net::HTTPSuccess)
|
143
|
+
# === Queries
|
75
144
|
#
|
76
|
-
#
|
145
|
+
# A host-specific query adds name/value pairs to the URI:
|
77
146
|
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
147
|
+
# _uri = uri.dup
|
148
|
+
# params = {userId: 1, completed: false}
|
149
|
+
# _uri.query = URI.encode_www_form(params)
|
150
|
+
# _uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com?userId=1&completed=false>
|
151
|
+
# Net::HTTP.get(_uri)
|
81
152
|
#
|
82
|
-
# ===
|
153
|
+
# === Fragments
|
83
154
|
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
155
|
+
# A {URI fragment}[https://en.wikipedia.org/wiki/URI_fragment] has no effect
|
156
|
+
# in \Net::HTTP;
|
157
|
+
# the same data is returned, regardless of whether a fragment is included.
|
87
158
|
#
|
88
|
-
# ==
|
159
|
+
# == Request Headers
|
89
160
|
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
161
|
+
# Request headers may be used to pass additional information to the host,
|
162
|
+
# similar to arguments passed in a method call;
|
163
|
+
# each header is a name/value pair.
|
93
164
|
#
|
94
|
-
#
|
165
|
+
# Each of the \Net::HTTP methods that sends a request to the host
|
166
|
+
# has optional argument +headers+,
|
167
|
+
# where the headers are expressed as a hash of field-name/value pairs:
|
95
168
|
#
|
96
|
-
#
|
97
|
-
#
|
169
|
+
# headers = {Accept: 'application/json', Connection: 'Keep-Alive'}
|
170
|
+
# Net::HTTP.get(uri, headers)
|
98
171
|
#
|
99
|
-
#
|
100
|
-
#
|
172
|
+
# See lists of both standard request fields and common request fields at
|
173
|
+
# {Request Fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields].
|
174
|
+
# A host may also accept other custom fields.
|
101
175
|
#
|
102
|
-
#
|
103
|
-
# is kept open for the duration of the block. The connection will remain
|
104
|
-
# open for multiple requests in the block if the server indicates it
|
105
|
-
# supports persistent connections.
|
176
|
+
# == \HTTP Sessions
|
106
177
|
#
|
107
|
-
#
|
108
|
-
# automatically closing it you can use ::new and then call #start and
|
109
|
-
# #finish manually.
|
178
|
+
# A _session_ is a connection between a server (host) and a client that:
|
110
179
|
#
|
111
|
-
#
|
112
|
-
#
|
180
|
+
# - Is begun by instance method Net::HTTP#start.
|
181
|
+
# - May contain any number of requests.
|
182
|
+
# - Is ended by instance method Net::HTTP#finish.
|
113
183
|
#
|
114
|
-
#
|
115
|
-
# supply either a String for the request path or a URI from which Net::HTTP
|
116
|
-
# will extract the request path.
|
184
|
+
# See example sessions at {Strategies}[rdoc-ref:Net::HTTP@Strategies].
|
117
185
|
#
|
118
|
-
# ===
|
186
|
+
# === Session Using \Net::HTTP.start
|
119
187
|
#
|
120
|
-
#
|
121
|
-
#
|
188
|
+
# If you have many requests to make to a single host (and port),
|
189
|
+
# consider using singleton method Net::HTTP.start with a block;
|
190
|
+
# the method handles the session automatically by:
|
122
191
|
#
|
123
|
-
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
# res.to_hash['set-cookie'] # => Array
|
127
|
-
# puts "Headers: #{res.to_hash.inspect}"
|
192
|
+
# - Calling #start before block execution.
|
193
|
+
# - Executing the block.
|
194
|
+
# - Calling #finish after block execution.
|
128
195
|
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
# puts res.message # => 'OK'
|
132
|
-
# puts res.class.name # => 'HTTPOK'
|
196
|
+
# In the block, you can use these instance methods,
|
197
|
+
# each of which that sends a single request:
|
133
198
|
#
|
134
|
-
#
|
135
|
-
# puts res.body if res.response_body_permitted?
|
199
|
+
# - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
|
136
200
|
#
|
137
|
-
#
|
201
|
+
# - #get, #request_get: GET.
|
202
|
+
# - #head, #request_head: HEAD.
|
203
|
+
# - #post, #request_post: POST.
|
204
|
+
# - #delete: DELETE.
|
205
|
+
# - #options: OPTIONS.
|
206
|
+
# - #trace: TRACE.
|
207
|
+
# - #patch: PATCH.
|
138
208
|
#
|
139
|
-
#
|
209
|
+
# - {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
|
140
210
|
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
#
|
211
|
+
# - #copy: COPY.
|
212
|
+
# - #lock: LOCK.
|
213
|
+
# - #mkcol: MKCOL.
|
214
|
+
# - #move: MOVE.
|
215
|
+
# - #propfind: PROPFIND.
|
216
|
+
# - #proppatch: PROPPATCH.
|
217
|
+
# - #unlock: UNLOCK.
|
146
218
|
#
|
147
|
-
#
|
219
|
+
# === Session Using \Net::HTTP.start and \Net::HTTP.finish
|
148
220
|
#
|
149
|
-
#
|
150
|
-
# # You should choose a better exception.
|
151
|
-
# raise ArgumentError, 'too many HTTP redirects' if limit == 0
|
221
|
+
# You can manage a session manually using methods #start and #finish:
|
152
222
|
#
|
153
|
-
#
|
223
|
+
# http = Net::HTTP.new(hostname)
|
224
|
+
# http.start
|
225
|
+
# http.get('/todos/1')
|
226
|
+
# http.get('/todos/2')
|
227
|
+
# http.delete('/posts/1')
|
228
|
+
# http.finish # Needed to free resources.
|
154
229
|
#
|
155
|
-
#
|
156
|
-
# when Net::HTTPSuccess then
|
157
|
-
# response
|
158
|
-
# when Net::HTTPRedirection then
|
159
|
-
# location = response['location']
|
160
|
-
# warn "redirected to #{location}"
|
161
|
-
# fetch(location, limit - 1)
|
162
|
-
# else
|
163
|
-
# response.value
|
164
|
-
# end
|
165
|
-
# end
|
230
|
+
# === Single-Request Session
|
166
231
|
#
|
167
|
-
#
|
232
|
+
# Certain convenience methods automatically handle a session by:
|
168
233
|
#
|
169
|
-
#
|
234
|
+
# - Creating an \HTTP object
|
235
|
+
# - Starting a session.
|
236
|
+
# - Sending a single request.
|
237
|
+
# - Finishing the session.
|
238
|
+
# - Destroying the object.
|
170
239
|
#
|
171
|
-
#
|
172
|
-
# creates a URL encoded POST body:
|
240
|
+
# Such methods that send GET requests:
|
173
241
|
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
242
|
+
# - ::get: Returns the string response body.
|
243
|
+
# - ::get_print: Writes the string response body to $stdout.
|
244
|
+
# - ::get_response: Returns a Net::HTTPResponse object.
|
177
245
|
#
|
178
|
-
#
|
179
|
-
# http.request(req)
|
180
|
-
# end
|
246
|
+
# Such methods that send POST requests:
|
181
247
|
#
|
182
|
-
#
|
183
|
-
#
|
184
|
-
# # OK
|
185
|
-
# else
|
186
|
-
# res.value
|
187
|
-
# end
|
248
|
+
# - ::post: Posts data to the host.
|
249
|
+
# - ::post_form: Posts form data to the host.
|
188
250
|
#
|
189
|
-
#
|
251
|
+
# == \HTTP Requests and Responses
|
190
252
|
#
|
191
|
-
#
|
192
|
-
#
|
253
|
+
# Many of the methods above are convenience methods,
|
254
|
+
# each of which sends a request and returns a string
|
255
|
+
# without directly using \Net::HTTPRequest and \Net::HTTPResponse objects.
|
193
256
|
#
|
194
|
-
#
|
195
|
-
#
|
257
|
+
# You can, however, directly create a request object, send the request,
|
258
|
+
# and retrieve the response object; see:
|
196
259
|
#
|
197
|
-
#
|
260
|
+
# - Net::HTTPRequest.
|
261
|
+
# - Net::HTTPResponse.
|
198
262
|
#
|
199
|
-
#
|
200
|
-
# If-Modified-Since header. If the files has not been modified since the
|
201
|
-
# time in the header a Not Modified response will be returned. See RFC 2616
|
202
|
-
# section 9.3 for further details.
|
263
|
+
# == Following Redirection
|
203
264
|
#
|
204
|
-
#
|
205
|
-
#
|
265
|
+
# Each returned response is an instance of a subclass of Net::HTTPResponse.
|
266
|
+
# See the {response class hierarchy}[rdoc-ref:Net::HTTPResponse@Response+Subclasses].
|
206
267
|
#
|
207
|
-
#
|
208
|
-
#
|
268
|
+
# In particular, class Net::HTTPRedirection is the parent
|
269
|
+
# of all redirection classes.
|
270
|
+
# This allows you to craft a case statement to handle redirections properly:
|
209
271
|
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
272
|
+
# def fetch(uri, limit = 10)
|
273
|
+
# # You should choose a better exception.
|
274
|
+
# raise ArgumentError, 'Too many HTTP redirects' if limit == 0
|
275
|
+
#
|
276
|
+
# res = Net::HTTP.get_response(URI(uri))
|
277
|
+
# case res
|
278
|
+
# when Net::HTTPSuccess # Any success class.
|
279
|
+
# res
|
280
|
+
# when Net::HTTPRedirection # Any redirection class.
|
281
|
+
# location = res['Location']
|
282
|
+
# warn "Redirected to #{location}"
|
283
|
+
# fetch(location, limit - 1)
|
284
|
+
# else # Any other class.
|
285
|
+
# res.value
|
286
|
+
# end
|
287
|
+
# end
|
213
288
|
#
|
214
|
-
#
|
215
|
-
# io.write res.body
|
216
|
-
# end if res.is_a?(Net::HTTPSuccess)
|
289
|
+
# fetch(uri)
|
217
290
|
#
|
218
|
-
#
|
291
|
+
# == Basic Authentication
|
219
292
|
#
|
220
293
|
# Basic authentication is performed according to
|
221
|
-
# [
|
222
|
-
#
|
223
|
-
# uri = URI('http://example.com/index.html?key=value')
|
294
|
+
# {RFC2617}[http://www.ietf.org/rfc/rfc2617.txt]:
|
224
295
|
#
|
225
296
|
# req = Net::HTTP::Get.new(uri)
|
226
|
-
# req.basic_auth
|
227
|
-
#
|
228
|
-
# res = Net::HTTP.start(uri.hostname, uri.port) {|http|
|
297
|
+
# req.basic_auth('user', 'pass')
|
298
|
+
# res = Net::HTTP.start(hostname) do |http|
|
229
299
|
# http.request(req)
|
230
|
-
#
|
231
|
-
# puts res.body
|
300
|
+
# end
|
232
301
|
#
|
233
|
-
#
|
302
|
+
# == Streaming Response Bodies
|
234
303
|
#
|
235
|
-
# By default Net::HTTP reads an entire response into memory. If you are
|
304
|
+
# By default \Net::HTTP reads an entire response into memory. If you are
|
236
305
|
# handling large files or wish to implement a progress bar you can instead
|
237
306
|
# stream the body directly to an IO.
|
238
307
|
#
|
239
|
-
#
|
240
|
-
#
|
241
|
-
#
|
242
|
-
#
|
243
|
-
#
|
244
|
-
#
|
245
|
-
# open 'large_file', 'w' do |io|
|
246
|
-
# response.read_body do |chunk|
|
247
|
-
# io.write chunk
|
308
|
+
# Net::HTTP.start(hostname) do |http|
|
309
|
+
# req = Net::HTTP::Get.new(uri)
|
310
|
+
# http.request(req) do |res|
|
311
|
+
# open('t.tmp', 'w') do |f|
|
312
|
+
# res.read_body do |chunk|
|
313
|
+
# f.write chunk
|
248
314
|
# end
|
249
315
|
# end
|
250
316
|
# end
|
251
317
|
# end
|
252
318
|
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
# HTTPS is enabled for an HTTP connection by Net::HTTP#use_ssl=.
|
319
|
+
# == HTTPS
|
256
320
|
#
|
257
|
-
#
|
321
|
+
# HTTPS is enabled for an \HTTP connection by Net::HTTP#use_ssl=:
|
258
322
|
#
|
259
|
-
# Net::HTTP.start(
|
260
|
-
#
|
261
|
-
#
|
323
|
+
# Net::HTTP.start(hostname, :use_ssl => true) do |http|
|
324
|
+
# req = Net::HTTP::Get.new(uri)
|
325
|
+
# res = http.request(req)
|
262
326
|
# end
|
263
327
|
#
|
264
|
-
# Or if you simply want to make a GET request, you may pass in
|
265
|
-
# object that has an HTTPS URL. Net::HTTP automatically turns on TLS
|
266
|
-
# verification if the URI object has a 'https' URI scheme
|
328
|
+
# Or if you simply want to make a GET request, you may pass in a URI
|
329
|
+
# object that has an \HTTPS URL. \Net::HTTP automatically turns on TLS
|
330
|
+
# verification if the URI object has a 'https' URI scheme:
|
331
|
+
#
|
332
|
+
# uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com/>
|
333
|
+
# Net::HTTP.get(uri)
|
334
|
+
#
|
335
|
+
# == Proxy Server
|
336
|
+
#
|
337
|
+
# An \HTTP object can have
|
338
|
+
# a {proxy server}[https://en.wikipedia.org/wiki/Proxy_server].
|
339
|
+
#
|
340
|
+
# You can create an \HTTP object with a proxy server
|
341
|
+
# using method Net::HTTP.new or method Net::HTTP.start.
|
342
|
+
#
|
343
|
+
# The proxy may be defined either by argument +p_addr+
|
344
|
+
# or by environment variable <tt>'http_proxy'</tt>.
|
345
|
+
#
|
346
|
+
# === Proxy Using Argument +p_addr+ as a \String
|
347
|
+
#
|
348
|
+
# When argument +p_addr+ is a string hostname,
|
349
|
+
# the returned +http+ has the given host as its proxy:
|
350
|
+
#
|
351
|
+
# http = Net::HTTP.new(hostname, nil, 'proxy.example')
|
352
|
+
# http.proxy? # => true
|
353
|
+
# http.proxy_from_env? # => false
|
354
|
+
# http.proxy_address # => "proxy.example"
|
355
|
+
# # These use default values.
|
356
|
+
# http.proxy_port # => 80
|
357
|
+
# http.proxy_user # => nil
|
358
|
+
# http.proxy_pass # => nil
|
359
|
+
#
|
360
|
+
# The port, username, and password for the proxy may also be given:
|
267
361
|
#
|
268
|
-
#
|
269
|
-
# Net::HTTP.
|
362
|
+
# http = Net::HTTP.new(hostname, nil, 'proxy.example', 8000, 'pname', 'ppass')
|
363
|
+
# # => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
|
364
|
+
# http.proxy? # => true
|
365
|
+
# http.proxy_from_env? # => false
|
366
|
+
# http.proxy_address # => "proxy.example"
|
367
|
+
# http.proxy_port # => 8000
|
368
|
+
# http.proxy_user # => "pname"
|
369
|
+
# http.proxy_pass # => "ppass"
|
270
370
|
#
|
271
|
-
#
|
272
|
-
#
|
371
|
+
# === Proxy Using '<tt>ENV['http_proxy']</tt>'
|
372
|
+
#
|
373
|
+
# When environment variable <tt>'http_proxy'</tt>
|
374
|
+
# is set to a \URI string,
|
375
|
+
# the returned +http+ will have the server at that URI as its proxy;
|
376
|
+
# note that the \URI string must have a protocol
|
377
|
+
# such as <tt>'http'</tt> or <tt>'https'</tt>:
|
378
|
+
#
|
379
|
+
# ENV['http_proxy'] = 'http://example.com'
|
380
|
+
# http = Net::HTTP.new(hostname)
|
381
|
+
# http.proxy? # => true
|
382
|
+
# http.proxy_from_env? # => true
|
383
|
+
# http.proxy_address # => "example.com"
|
384
|
+
# # These use default values.
|
385
|
+
# http.proxy_port # => 80
|
386
|
+
# http.proxy_user # => nil
|
387
|
+
# http.proxy_pass # => nil
|
388
|
+
#
|
389
|
+
# The \URI string may include proxy username, password, and port number:
|
390
|
+
#
|
391
|
+
# ENV['http_proxy'] = 'http://pname:ppass@example.com:8000'
|
392
|
+
# http = Net::HTTP.new(hostname)
|
393
|
+
# http.proxy? # => true
|
394
|
+
# http.proxy_from_env? # => true
|
395
|
+
# http.proxy_address # => "example.com"
|
396
|
+
# http.proxy_port # => 8000
|
397
|
+
# http.proxy_user # => "pname"
|
398
|
+
# http.proxy_pass # => "ppass"
|
399
|
+
#
|
400
|
+
# === Filtering Proxies
|
401
|
+
#
|
402
|
+
# With method Net::HTTP.new (but not Net::HTTP.start),
|
403
|
+
# you can use argument +p_no_proxy+ to filter proxies:
|
404
|
+
#
|
405
|
+
# - Reject a certain address:
|
406
|
+
#
|
407
|
+
# http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example')
|
408
|
+
# http.proxy_address # => nil
|
409
|
+
#
|
410
|
+
# - Reject certain domains or subdomains:
|
411
|
+
#
|
412
|
+
# http = Net::HTTP.new('example.com', nil, 'my.proxy.example', 8000, 'pname', 'ppass', 'proxy.example')
|
413
|
+
# http.proxy_address # => nil
|
414
|
+
#
|
415
|
+
# - Reject certain addresses and port combinations:
|
416
|
+
#
|
417
|
+
# http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:1234')
|
418
|
+
# http.proxy_address # => "proxy.example"
|
419
|
+
#
|
420
|
+
# http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:8000')
|
421
|
+
# http.proxy_address # => nil
|
422
|
+
#
|
423
|
+
# - Reject a list of the types above delimited using a comma:
|
424
|
+
#
|
425
|
+
# http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000')
|
426
|
+
# http.proxy_address # => nil
|
427
|
+
#
|
428
|
+
# http = Net::HTTP.new('example.com', nil, 'my.proxy', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000')
|
429
|
+
# http.proxy_address # => nil
|
430
|
+
#
|
431
|
+
# == Compression and Decompression
|
432
|
+
#
|
433
|
+
# \Net::HTTP does not compress the body of a request before sending.
|
434
|
+
#
|
435
|
+
# By default, \Net::HTTP adds header <tt>'Accept-Encoding'</tt>
|
436
|
+
# to a new {request object}[rdoc-ref:Net::HTTPRequest]:
|
437
|
+
#
|
438
|
+
# Net::HTTP::Get.new(uri)['Accept-Encoding']
|
439
|
+
# # => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
|
440
|
+
#
|
441
|
+
# This requests the server to zip-encode the response body if there is one;
|
442
|
+
# the server is not required to do so.
|
443
|
+
#
|
444
|
+
# \Net::HTTP does not automatically decompress a response body
|
445
|
+
# if the response has header <tt>'Content-Range'</tt>.
|
446
|
+
#
|
447
|
+
# Otherwise decompression (or not) depends on the value of header
|
448
|
+
# {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-encoding-response-header]:
|
449
|
+
#
|
450
|
+
# - <tt>'deflate'</tt>, <tt>'gzip'</tt>, or <tt>'x-gzip'</tt>:
|
451
|
+
# decompresses the body and deletes the header.
|
452
|
+
# - <tt>'none'</tt> or <tt>'identity'</tt>:
|
453
|
+
# does not decompress the body, but deletes the header.
|
454
|
+
# - Any other value:
|
455
|
+
# leaves the body and header unchanged.
|
456
|
+
#
|
457
|
+
# == What's Here
|
458
|
+
#
|
459
|
+
# This is a categorized summary of methods and attributes.
|
460
|
+
#
|
461
|
+
# === \Net::HTTP Objects
|
462
|
+
#
|
463
|
+
# - {::new}[rdoc-ref:Net::HTTP.new]:
|
464
|
+
# Creates a new instance.
|
465
|
+
# - {#inspect}[rdoc-ref:Net::HTTP#inspect]:
|
466
|
+
# Returns a string representation of +self+.
|
467
|
+
#
|
468
|
+
# === Sessions
|
469
|
+
#
|
470
|
+
# - {::start}[rdoc-ref:Net::HTTP.start]:
|
471
|
+
# Begins a new session in a new \Net::HTTP object.
|
472
|
+
# - {#started?}[rdoc-ref:Net::HTTP#started?]
|
473
|
+
# (aliased as {#active?}[rdoc-ref:Net::HTTP#active?]):
|
474
|
+
# Returns whether in a session.
|
475
|
+
# - {#finish}[rdoc-ref:Net::HTTP#finish]:
|
476
|
+
# Ends an active session.
|
477
|
+
# - {#start}[rdoc-ref:Net::HTTP#start]:
|
478
|
+
# Begins a new session in an existing \Net::HTTP object (+self+).
|
479
|
+
#
|
480
|
+
# === Connections
|
481
|
+
#
|
482
|
+
# - {:continue_timeout}[rdoc-ref:Net::HTTP#continue_timeout]:
|
483
|
+
# Returns the continue timeout.
|
484
|
+
# - {#continue_timeout=}[rdoc-ref:Net::HTTP#continue_timeout=]:
|
485
|
+
# Sets the continue timeout seconds.
|
486
|
+
# - {:keep_alive_timeout}[rdoc-ref:Net::HTTP#keep_alive_timeout]:
|
487
|
+
# Returns the keep-alive timeout.
|
488
|
+
# - {:keep_alive_timeout=}[rdoc-ref:Net::HTTP#keep_alive_timeout=]:
|
489
|
+
# Sets the keep-alive timeout.
|
490
|
+
# - {:max_retries}[rdoc-ref:Net::HTTP#max_retries]:
|
491
|
+
# Returns the maximum retries.
|
492
|
+
# - {#max_retries=}[rdoc-ref:Net::HTTP#max_retries=]:
|
493
|
+
# Sets the maximum retries.
|
494
|
+
# - {:open_timeout}[rdoc-ref:Net::HTTP#open_timeout]:
|
495
|
+
# Returns the open timeout.
|
496
|
+
# - {:open_timeout=}[rdoc-ref:Net::HTTP#open_timeout=]:
|
497
|
+
# Sets the open timeout.
|
498
|
+
# - {:read_timeout}[rdoc-ref:Net::HTTP#read_timeout]:
|
499
|
+
# Returns the open timeout.
|
500
|
+
# - {:read_timeout=}[rdoc-ref:Net::HTTP#read_timeout=]:
|
501
|
+
# Sets the read timeout.
|
502
|
+
# - {:ssl_timeout}[rdoc-ref:Net::HTTP#ssl_timeout]:
|
503
|
+
# Returns the ssl timeout.
|
504
|
+
# - {:ssl_timeout=}[rdoc-ref:Net::HTTP#ssl_timeout=]:
|
505
|
+
# Sets the ssl timeout.
|
506
|
+
# - {:write_timeout}[rdoc-ref:Net::HTTP#write_timeout]:
|
507
|
+
# Returns the write timeout.
|
508
|
+
# - {write_timeout=}[rdoc-ref:Net::HTTP#write_timeout=]:
|
509
|
+
# Sets the write timeout.
|
510
|
+
#
|
511
|
+
# === Requests
|
512
|
+
#
|
513
|
+
# - {::get}[rdoc-ref:Net::HTTP.get]:
|
514
|
+
# Sends a GET request and returns the string response body.
|
515
|
+
# - {::get_print}[rdoc-ref:Net::HTTP.get_print]:
|
516
|
+
# Sends a GET request and write the string response body to $stdout.
|
517
|
+
# - {::get_response}[rdoc-ref:Net::HTTP.get_response]:
|
518
|
+
# Sends a GET request and returns a response object.
|
519
|
+
# - {::post_form}[rdoc-ref:Net::HTTP.post_form]:
|
520
|
+
# Sends a POST request with form data and returns a response object.
|
521
|
+
# - {::post}[rdoc-ref:Net::HTTP.post]:
|
522
|
+
# Sends a POST request with data and returns a response object.
|
523
|
+
# - {#copy}[rdoc-ref:Net::HTTP#copy]:
|
524
|
+
# Sends a COPY request and returns a response object.
|
525
|
+
# - {#delete}[rdoc-ref:Net::HTTP#delete]:
|
526
|
+
# Sends a DELETE request and returns a response object.
|
527
|
+
# - {#get}[rdoc-ref:Net::HTTP#get]:
|
528
|
+
# Sends a GET request and returns a response object.
|
529
|
+
# - {#head}[rdoc-ref:Net::HTTP#head]:
|
530
|
+
# Sends a HEAD request and returns a response object.
|
531
|
+
# - {#lock}[rdoc-ref:Net::HTTP#lock]:
|
532
|
+
# Sends a LOCK request and returns a response object.
|
533
|
+
# - {#mkcol}[rdoc-ref:Net::HTTP#mkcol]:
|
534
|
+
# Sends a MKCOL request and returns a response object.
|
535
|
+
# - {#move}[rdoc-ref:Net::HTTP#move]:
|
536
|
+
# Sends a MOVE request and returns a response object.
|
537
|
+
# - {#options}[rdoc-ref:Net::HTTP#options]:
|
538
|
+
# Sends a OPTIONS request and returns a response object.
|
539
|
+
# - {#patch}[rdoc-ref:Net::HTTP#patch]:
|
540
|
+
# Sends a PATCH request and returns a response object.
|
541
|
+
# - {#post}[rdoc-ref:Net::HTTP#post]:
|
542
|
+
# Sends a POST request and returns a response object.
|
543
|
+
# - {#propfind}[rdoc-ref:Net::HTTP#propfind]:
|
544
|
+
# Sends a PROPFIND request and returns a response object.
|
545
|
+
# - {#proppatch}[rdoc-ref:Net::HTTP#proppatch]:
|
546
|
+
# Sends a PROPPATCH request and returns a response object.
|
547
|
+
# - {#put}[rdoc-ref:Net::HTTP#put]:
|
548
|
+
# Sends a PUT request and returns a response object.
|
549
|
+
# - {#request}[rdoc-ref:Net::HTTP#request]:
|
550
|
+
# Sends a request and returns a response object.
|
551
|
+
# - {#request_get}[rdoc-ref:Net::HTTP#request_get]
|
552
|
+
# (aliased as {#get2}[rdoc-ref:Net::HTTP#get2]):
|
553
|
+
# Sends a GET request and forms a response object;
|
554
|
+
# if a block given, calls the block with the object,
|
555
|
+
# otherwise returns the object.
|
556
|
+
# - {#request_head}[rdoc-ref:Net::HTTP#request_head]
|
557
|
+
# (aliased as {#head2}[rdoc-ref:Net::HTTP#head2]):
|
558
|
+
# Sends a HEAD request and forms a response object;
|
559
|
+
# if a block given, calls the block with the object,
|
560
|
+
# otherwise returns the object.
|
561
|
+
# - {#request_post}[rdoc-ref:Net::HTTP#request_post]
|
562
|
+
# (aliased as {#post2}[rdoc-ref:Net::HTTP#post2]):
|
563
|
+
# Sends a POST request and forms a response object;
|
564
|
+
# if a block given, calls the block with the object,
|
565
|
+
# otherwise returns the object.
|
566
|
+
# - {#send_request}[rdoc-ref:Net::HTTP#send_request]:
|
567
|
+
# Sends a request and returns a response object.
|
568
|
+
# - {#trace}[rdoc-ref:Net::HTTP#trace]:
|
569
|
+
# Sends a TRACE request and returns a response object.
|
570
|
+
# - {#unlock}[rdoc-ref:Net::HTTP#unlock]:
|
571
|
+
# Sends an UNLOCK request and returns a response object.
|
572
|
+
#
|
573
|
+
# === Responses
|
574
|
+
#
|
575
|
+
# - {:close_on_empty_response}[rdoc-ref:Net::HTTP#close_on_empty_response]:
|
576
|
+
# Returns whether to close connection on empty response.
|
577
|
+
# - {:close_on_empty_response=}[rdoc-ref:Net::HTTP#close_on_empty_response=]:
|
578
|
+
# Sets whether to close connection on empty response.
|
579
|
+
# - {:ignore_eof}[rdoc-ref:Net::HTTP#ignore_eof]:
|
580
|
+
# Returns whether to ignore end-of-file when reading a response body
|
581
|
+
# with <tt>Content-Length</tt> headers.
|
582
|
+
# - {:ignore_eof=}[rdoc-ref:Net::HTTP#ignore_eof=]:
|
583
|
+
# Sets whether to ignore end-of-file when reading a response body
|
584
|
+
# with <tt>Content-Length</tt> headers.
|
585
|
+
# - {:response_body_encoding}[rdoc-ref:Net::HTTP#response_body_encoding]:
|
586
|
+
# Returns the encoding to use for the response body.
|
587
|
+
# - {#response_body_encoding=}[rdoc-ref:Net::HTTP#response_body_encoding=]:
|
588
|
+
# Sets the response body encoding.
|
273
589
|
#
|
274
590
|
# === Proxies
|
275
591
|
#
|
276
|
-
# Net::HTTP
|
277
|
-
#
|
278
|
-
#
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
282
|
-
#
|
283
|
-
#
|
284
|
-
#
|
285
|
-
# Net::HTTP
|
286
|
-
#
|
287
|
-
#
|
288
|
-
#
|
289
|
-
#
|
290
|
-
#
|
291
|
-
#
|
292
|
-
#
|
293
|
-
#
|
294
|
-
#
|
295
|
-
#
|
296
|
-
#
|
297
|
-
#
|
298
|
-
#
|
299
|
-
#
|
300
|
-
#
|
301
|
-
#
|
302
|
-
#
|
303
|
-
#
|
304
|
-
#
|
305
|
-
#
|
306
|
-
#
|
307
|
-
#
|
308
|
-
#
|
309
|
-
#
|
310
|
-
#
|
311
|
-
#
|
312
|
-
#
|
313
|
-
#
|
314
|
-
#
|
315
|
-
#
|
316
|
-
#
|
317
|
-
#
|
318
|
-
#
|
319
|
-
#
|
320
|
-
#
|
321
|
-
#
|
322
|
-
#
|
323
|
-
#
|
324
|
-
#
|
325
|
-
#
|
326
|
-
#
|
327
|
-
#
|
328
|
-
#
|
329
|
-
#
|
330
|
-
#
|
331
|
-
#
|
332
|
-
#
|
333
|
-
#
|
334
|
-
#
|
335
|
-
#
|
336
|
-
#
|
337
|
-
#
|
338
|
-
#
|
339
|
-
#
|
340
|
-
#
|
341
|
-
#
|
342
|
-
#
|
343
|
-
#
|
344
|
-
#
|
345
|
-
#
|
346
|
-
#
|
347
|
-
#
|
348
|
-
#
|
349
|
-
#
|
350
|
-
#
|
351
|
-
#
|
352
|
-
#
|
353
|
-
#
|
354
|
-
#
|
355
|
-
#
|
356
|
-
#
|
357
|
-
#
|
358
|
-
#
|
359
|
-
#
|
360
|
-
#
|
361
|
-
#
|
362
|
-
#
|
363
|
-
#
|
364
|
-
#
|
365
|
-
#
|
366
|
-
#
|
367
|
-
#
|
368
|
-
#
|
369
|
-
#
|
370
|
-
#
|
371
|
-
#
|
372
|
-
#
|
373
|
-
#
|
374
|
-
#
|
375
|
-
#
|
376
|
-
#
|
377
|
-
#
|
378
|
-
#
|
379
|
-
#
|
380
|
-
#
|
381
|
-
#
|
382
|
-
#
|
383
|
-
#
|
384
|
-
#
|
385
|
-
#
|
386
|
-
#
|
592
|
+
# - {:proxy_address}[rdoc-ref:Net::HTTP#proxy_address]:
|
593
|
+
# Returns the proxy address.
|
594
|
+
# - {:proxy_address=}[rdoc-ref:Net::HTTP#proxy_address=]:
|
595
|
+
# Sets the proxy address.
|
596
|
+
# - {::proxy_class?}[rdoc-ref:Net::HTTP.proxy_class?]:
|
597
|
+
# Returns whether +self+ is a proxy class.
|
598
|
+
# - {#proxy?}[rdoc-ref:Net::HTTP#proxy?]:
|
599
|
+
# Returns whether +self+ has a proxy.
|
600
|
+
# - {#proxy_address}[rdoc-ref:Net::HTTP#proxy_address]
|
601
|
+
# (aliased as {#proxyaddr}[rdoc-ref:Net::HTTP#proxyaddr]):
|
602
|
+
# Returns the proxy address.
|
603
|
+
# - {#proxy_from_env?}[rdoc-ref:Net::HTTP#proxy_from_env?]:
|
604
|
+
# Returns whether the proxy is taken from an environment variable.
|
605
|
+
# - {:proxy_from_env=}[rdoc-ref:Net::HTTP#proxy_from_env=]:
|
606
|
+
# Sets whether the proxy is to be taken from an environment variable.
|
607
|
+
# - {:proxy_pass}[rdoc-ref:Net::HTTP#proxy_pass]:
|
608
|
+
# Returns the proxy password.
|
609
|
+
# - {:proxy_pass=}[rdoc-ref:Net::HTTP#proxy_pass=]:
|
610
|
+
# Sets the proxy password.
|
611
|
+
# - {:proxy_port}[rdoc-ref:Net::HTTP#proxy_port]:
|
612
|
+
# Returns the proxy port.
|
613
|
+
# - {:proxy_port=}[rdoc-ref:Net::HTTP#proxy_port=]:
|
614
|
+
# Sets the proxy port.
|
615
|
+
# - {#proxy_user}[rdoc-ref:Net::HTTP#proxy_user]:
|
616
|
+
# Returns the proxy user name.
|
617
|
+
# - {:proxy_user=}[rdoc-ref:Net::HTTP#proxy_user=]:
|
618
|
+
# Sets the proxy user.
|
619
|
+
#
|
620
|
+
# === Security
|
621
|
+
#
|
622
|
+
# - {:ca_file}[rdoc-ref:Net::HTTP#ca_file]:
|
623
|
+
# Returns the path to a CA certification file.
|
624
|
+
# - {:ca_file=}[rdoc-ref:Net::HTTP#ca_file=]:
|
625
|
+
# Sets the path to a CA certification file.
|
626
|
+
# - {:ca_path}[rdoc-ref:Net::HTTP#ca_path]:
|
627
|
+
# Returns the path of to CA directory containing certification files.
|
628
|
+
# - {:ca_path=}[rdoc-ref:Net::HTTP#ca_path=]:
|
629
|
+
# Sets the path of to CA directory containing certification files.
|
630
|
+
# - {:cert}[rdoc-ref:Net::HTTP#cert]:
|
631
|
+
# Returns the OpenSSL::X509::Certificate object to be used for client certification.
|
632
|
+
# - {:cert=}[rdoc-ref:Net::HTTP#cert=]:
|
633
|
+
# Sets the OpenSSL::X509::Certificate object to be used for client certification.
|
634
|
+
# - {:cert_store}[rdoc-ref:Net::HTTP#cert_store]:
|
635
|
+
# Returns the X509::Store to be used for verifying peer certificate.
|
636
|
+
# - {:cert_store=}[rdoc-ref:Net::HTTP#cert_store=]:
|
637
|
+
# Sets the X509::Store to be used for verifying peer certificate.
|
638
|
+
# - {:ciphers}[rdoc-ref:Net::HTTP#ciphers]:
|
639
|
+
# Returns the available SSL ciphers.
|
640
|
+
# - {:ciphers=}[rdoc-ref:Net::HTTP#ciphers=]:
|
641
|
+
# Sets the available SSL ciphers.
|
642
|
+
# - {:extra_chain_cert}[rdoc-ref:Net::HTTP#extra_chain_cert]:
|
643
|
+
# Returns the extra X509 certificates to be added to the certificate chain.
|
644
|
+
# - {:extra_chain_cert=}[rdoc-ref:Net::HTTP#extra_chain_cert=]:
|
645
|
+
# Sets the extra X509 certificates to be added to the certificate chain.
|
646
|
+
# - {:key}[rdoc-ref:Net::HTTP#key]:
|
647
|
+
# Returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
|
648
|
+
# - {:key=}[rdoc-ref:Net::HTTP#key=]:
|
649
|
+
# Sets the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
|
650
|
+
# - {:max_version}[rdoc-ref:Net::HTTP#max_version]:
|
651
|
+
# Returns the maximum SSL version.
|
652
|
+
# - {:max_version=}[rdoc-ref:Net::HTTP#max_version=]:
|
653
|
+
# Sets the maximum SSL version.
|
654
|
+
# - {:min_version}[rdoc-ref:Net::HTTP#min_version]:
|
655
|
+
# Returns the minimum SSL version.
|
656
|
+
# - {:min_version=}[rdoc-ref:Net::HTTP#min_version=]:
|
657
|
+
# Sets the minimum SSL version.
|
658
|
+
# - {#peer_cert}[rdoc-ref:Net::HTTP#peer_cert]:
|
659
|
+
# Returns the X509 certificate chain for the session's socket peer.
|
660
|
+
# - {:ssl_version}[rdoc-ref:Net::HTTP#ssl_version]:
|
661
|
+
# Returns the SSL version.
|
662
|
+
# - {:ssl_version=}[rdoc-ref:Net::HTTP#ssl_version=]:
|
663
|
+
# Sets the SSL version.
|
664
|
+
# - {#use_ssl=}[rdoc-ref:Net::HTTP#use_ssl=]:
|
665
|
+
# Sets whether a new session is to use Transport Layer Security.
|
666
|
+
# - {#use_ssl?}[rdoc-ref:Net::HTTP#use_ssl?]:
|
667
|
+
# Returns whether +self+ uses SSL.
|
668
|
+
# - {:verify_callback}[rdoc-ref:Net::HTTP#verify_callback]:
|
669
|
+
# Returns the callback for the server certification verification.
|
670
|
+
# - {:verify_callback=}[rdoc-ref:Net::HTTP#verify_callback=]:
|
671
|
+
# Sets the callback for the server certification verification.
|
672
|
+
# - {:verify_depth}[rdoc-ref:Net::HTTP#verify_depth]:
|
673
|
+
# Returns the maximum depth for the certificate chain verification.
|
674
|
+
# - {:verify_depth=}[rdoc-ref:Net::HTTP#verify_depth=]:
|
675
|
+
# Sets the maximum depth for the certificate chain verification.
|
676
|
+
# - {:verify_hostname}[rdoc-ref:Net::HTTP#verify_hostname]:
|
677
|
+
# Returns the flags for server the certification verification at the beginning of the SSL/TLS session.
|
678
|
+
# - {:verify_hostname=}[rdoc-ref:Net::HTTP#verify_hostname=]:
|
679
|
+
# Sets he flags for server the certification verification at the beginning of the SSL/TLS session.
|
680
|
+
# - {:verify_mode}[rdoc-ref:Net::HTTP#verify_mode]:
|
681
|
+
# Returns the flags for server the certification verification at the beginning of the SSL/TLS session.
|
682
|
+
# - {:verify_mode=}[rdoc-ref:Net::HTTP#verify_mode=]:
|
683
|
+
# Sets the flags for server the certification verification at the beginning of the SSL/TLS session.
|
684
|
+
#
|
685
|
+
# === Addresses and Ports
|
686
|
+
#
|
687
|
+
# - {:address}[rdoc-ref:Net::HTTP#address]:
|
688
|
+
# Returns the string host name or host IP.
|
689
|
+
# - {::default_port}[rdoc-ref:Net::HTTP.default_port]:
|
690
|
+
# Returns integer 80, the default port to use for HTTP requests.
|
691
|
+
# - {::http_default_port}[rdoc-ref:Net::HTTP.http_default_port]:
|
692
|
+
# Returns integer 80, the default port to use for HTTP requests.
|
693
|
+
# - {::https_default_port}[rdoc-ref:Net::HTTP.https_default_port]:
|
694
|
+
# Returns integer 443, the default port to use for HTTPS requests.
|
695
|
+
# - {#ipaddr}[rdoc-ref:Net::HTTP#ipaddr]:
|
696
|
+
# Returns the IP address for the connection.
|
697
|
+
# - {#ipaddr=}[rdoc-ref:Net::HTTP#ipaddr=]:
|
698
|
+
# Sets the IP address for the connection.
|
699
|
+
# - {:local_host}[rdoc-ref:Net::HTTP#local_host]:
|
700
|
+
# Returns the string local host used to establish the connection.
|
701
|
+
# - {:local_host=}[rdoc-ref:Net::HTTP#local_host=]:
|
702
|
+
# Sets the string local host used to establish the connection.
|
703
|
+
# - {:local_port}[rdoc-ref:Net::HTTP#local_port]:
|
704
|
+
# Returns the integer local port used to establish the connection.
|
705
|
+
# - {:local_port=}[rdoc-ref:Net::HTTP#local_port=]:
|
706
|
+
# Sets the integer local port used to establish the connection.
|
707
|
+
# - {:port}[rdoc-ref:Net::HTTP#port]:
|
708
|
+
# Returns the integer port number.
|
709
|
+
#
|
710
|
+
# === \HTTP Version
|
711
|
+
#
|
712
|
+
# - {::version_1_2?}[rdoc-ref:Net::HTTP.version_1_2?]
|
713
|
+
# (aliased as {::is_version_1_2?}[rdoc-ref:Net::HTTP.is_version_1_2?]
|
714
|
+
# and {::version_1_2}[rdoc-ref:Net::HTTP.version_1_2]):
|
715
|
+
# Returns true; retained for compatibility.
|
716
|
+
#
|
717
|
+
# === Debugging
|
718
|
+
#
|
719
|
+
# - {#set_debug_output}[rdoc-ref:Net::HTTP#set_debug_output]:
|
720
|
+
# Sets the output stream for debugging.
|
387
721
|
#
|
388
722
|
class HTTP < Protocol
|
389
723
|
|
390
724
|
# :stopdoc:
|
391
|
-
VERSION = "0.
|
392
|
-
Revision = %q$Revision$.split[1]
|
725
|
+
VERSION = "0.4.1"
|
393
726
|
HTTPVersion = '1.1'
|
394
727
|
begin
|
395
728
|
require 'zlib'
|
396
|
-
require 'stringio' #for our purposes (unpacking gzip) lump these together
|
397
729
|
HAVE_ZLIB=true
|
398
730
|
rescue LoadError
|
399
731
|
HAVE_ZLIB=false
|
400
732
|
end
|
401
733
|
# :startdoc:
|
402
734
|
|
403
|
-
#
|
404
|
-
# Defaults to ON in Ruby 1.8 or later.
|
735
|
+
# Returns +true+; retained for compatibility.
|
405
736
|
def HTTP.version_1_2
|
406
737
|
true
|
407
738
|
end
|
408
739
|
|
409
|
-
# Returns true
|
410
|
-
# Defaults to true.
|
740
|
+
# Returns +true+; retained for compatibility.
|
411
741
|
def HTTP.version_1_2?
|
412
742
|
true
|
413
743
|
end
|
414
744
|
|
745
|
+
# Returns +false+; retained for compatibility.
|
415
746
|
def HTTP.version_1_1? #:nodoc:
|
416
747
|
false
|
417
748
|
end
|
@@ -421,25 +752,12 @@ module Net #:nodoc:
|
|
421
752
|
alias is_version_1_2? version_1_2? #:nodoc:
|
422
753
|
end
|
423
754
|
|
755
|
+
# :call-seq:
|
756
|
+
# Net::HTTP.get_print(hostname, path, port = 80) -> nil
|
757
|
+
# Net::HTTP:get_print(uri, headers = {}, port = uri.port) -> nil
|
424
758
|
#
|
425
|
-
#
|
426
|
-
#
|
427
|
-
|
428
|
-
#
|
429
|
-
# Gets the body text from the target and outputs it to $stdout. The
|
430
|
-
# target can either be specified as
|
431
|
-
# (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
|
432
|
-
#
|
433
|
-
# Net::HTTP.get_print URI('http://www.example.com/index.html')
|
434
|
-
#
|
435
|
-
# or:
|
436
|
-
#
|
437
|
-
# Net::HTTP.get_print 'www.example.com', '/index.html'
|
438
|
-
#
|
439
|
-
# you can also specify request headers:
|
440
|
-
#
|
441
|
-
# Net::HTTP.get_print URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' }
|
442
|
-
#
|
759
|
+
# Like Net::HTTP.get, but writes the returned body to $stdout;
|
760
|
+
# returns +nil+.
|
443
761
|
def HTTP.get_print(uri_or_host, path_or_headers = nil, port = nil)
|
444
762
|
get_response(uri_or_host, path_or_headers, port) {|res|
|
445
763
|
res.read_body do |chunk|
|
@@ -449,40 +767,48 @@ module Net #:nodoc:
|
|
449
767
|
nil
|
450
768
|
end
|
451
769
|
|
452
|
-
#
|
453
|
-
#
|
454
|
-
#
|
455
|
-
#
|
456
|
-
# print Net::HTTP.get(URI('http://www.example.com/index.html'))
|
770
|
+
# :call-seq:
|
771
|
+
# Net::HTTP.get(hostname, path, port = 80) -> body
|
772
|
+
# Net::HTTP:get(uri, headers = {}, port = uri.port) -> body
|
457
773
|
#
|
458
|
-
#
|
774
|
+
# Sends a GET request and returns the \HTTP response body as a string.
|
459
775
|
#
|
460
|
-
#
|
776
|
+
# With string arguments +hostname+ and +path+:
|
461
777
|
#
|
462
|
-
#
|
778
|
+
# hostname = 'jsonplaceholder.typicode.com'
|
779
|
+
# path = '/todos/1'
|
780
|
+
# puts Net::HTTP.get(hostname, path)
|
463
781
|
#
|
464
|
-
#
|
782
|
+
# Output:
|
465
783
|
#
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
#
|
471
|
-
#
|
472
|
-
# (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
|
784
|
+
# {
|
785
|
+
# "userId": 1,
|
786
|
+
# "id": 1,
|
787
|
+
# "title": "delectus aut autem",
|
788
|
+
# "completed": false
|
789
|
+
# }
|
473
790
|
#
|
474
|
-
#
|
475
|
-
# print res.body
|
791
|
+
# With URI object +uri+ and optional hash argument +headers+:
|
476
792
|
#
|
477
|
-
#
|
793
|
+
# uri = URI('https://jsonplaceholder.typicode.com/todos/1')
|
794
|
+
# headers = {'Content-type' => 'application/json; charset=UTF-8'}
|
795
|
+
# Net::HTTP.get(uri, headers)
|
478
796
|
#
|
479
|
-
#
|
480
|
-
# print res.body
|
797
|
+
# Related:
|
481
798
|
#
|
482
|
-
#
|
799
|
+
# - Net::HTTP::Get: request class for \HTTP method +GET+.
|
800
|
+
# - Net::HTTP#get: convenience method for \HTTP method +GET+.
|
483
801
|
#
|
484
|
-
|
802
|
+
def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
|
803
|
+
get_response(uri_or_host, path_or_headers, port).body
|
804
|
+
end
|
805
|
+
|
806
|
+
# :call-seq:
|
807
|
+
# Net::HTTP.get_response(hostname, path, port = 80) -> http_response
|
808
|
+
# Net::HTTP:get_response(uri, headers = {}, port = uri.port) -> http_response
|
485
809
|
#
|
810
|
+
# Like Net::HTTP.get, but returns a Net::HTTPResponse object
|
811
|
+
# instead of the body string.
|
486
812
|
def HTTP.get_response(uri_or_host, path_or_headers = nil, port = nil, &block)
|
487
813
|
if path_or_headers && !path_or_headers.is_a?(Hash)
|
488
814
|
host = uri_or_host
|
@@ -500,16 +826,31 @@ module Net #:nodoc:
|
|
500
826
|
end
|
501
827
|
end
|
502
828
|
|
503
|
-
# Posts data to
|
829
|
+
# Posts data to a host; returns a Net::HTTPResponse object.
|
504
830
|
#
|
505
|
-
#
|
831
|
+
# Argument +url+ must be a URL;
|
832
|
+
# argument +data+ must be a string:
|
833
|
+
#
|
834
|
+
# _uri = uri.dup
|
835
|
+
# _uri.path = '/posts'
|
836
|
+
# data = '{"title": "foo", "body": "bar", "userId": 1}'
|
837
|
+
# headers = {'content-type': 'application/json'}
|
838
|
+
# res = Net::HTTP.post(_uri, data, headers) # => #<Net::HTTPCreated 201 Created readbody=true>
|
839
|
+
# puts res.body
|
840
|
+
#
|
841
|
+
# Output:
|
506
842
|
#
|
507
|
-
#
|
508
|
-
#
|
843
|
+
# {
|
844
|
+
# "title": "foo",
|
845
|
+
# "body": "bar",
|
846
|
+
# "userId": 1,
|
847
|
+
# "id": 101
|
848
|
+
# }
|
509
849
|
#
|
510
|
-
#
|
511
|
-
#
|
512
|
-
#
|
850
|
+
# Related:
|
851
|
+
#
|
852
|
+
# - Net::HTTP::Post: request class for \HTTP method +POST+.
|
853
|
+
# - Net::HTTP#post: convenience method for \HTTP method +POST+.
|
513
854
|
#
|
514
855
|
def HTTP.post(url, data, header = nil)
|
515
856
|
start(url.hostname, url.port,
|
@@ -518,23 +859,25 @@ module Net #:nodoc:
|
|
518
859
|
}
|
519
860
|
end
|
520
861
|
|
521
|
-
# Posts
|
522
|
-
# The form data must be provided as a Hash mapping from String to String.
|
523
|
-
# Example:
|
862
|
+
# Posts data to a host; returns a Net::HTTPResponse object.
|
524
863
|
#
|
525
|
-
#
|
864
|
+
# Argument +url+ must be a URI;
|
865
|
+
# argument +data+ must be a hash:
|
526
866
|
#
|
527
|
-
#
|
528
|
-
#
|
529
|
-
#
|
530
|
-
#
|
531
|
-
#
|
867
|
+
# _uri = uri.dup
|
868
|
+
# _uri.path = '/posts'
|
869
|
+
# data = {title: 'foo', body: 'bar', userId: 1}
|
870
|
+
# res = Net::HTTP.post_form(_uri, data) # => #<Net::HTTPCreated 201 Created readbody=true>
|
871
|
+
# puts res.body
|
532
872
|
#
|
533
|
-
#
|
534
|
-
# require 'uri'
|
873
|
+
# Output:
|
535
874
|
#
|
536
|
-
#
|
537
|
-
#
|
875
|
+
# {
|
876
|
+
# "title": "foo",
|
877
|
+
# "body": "bar",
|
878
|
+
# "userId": "1",
|
879
|
+
# "id": 101
|
880
|
+
# }
|
538
881
|
#
|
539
882
|
def HTTP.post_form(url, params)
|
540
883
|
req = Post.new(url)
|
@@ -547,20 +890,29 @@ module Net #:nodoc:
|
|
547
890
|
end
|
548
891
|
|
549
892
|
#
|
550
|
-
# HTTP session management
|
893
|
+
# \HTTP session management
|
551
894
|
#
|
552
895
|
|
553
|
-
#
|
896
|
+
# Returns integer +80+, the default port to use for \HTTP requests:
|
897
|
+
#
|
898
|
+
# Net::HTTP.default_port # => 80
|
899
|
+
#
|
554
900
|
def HTTP.default_port
|
555
901
|
http_default_port()
|
556
902
|
end
|
557
903
|
|
558
|
-
#
|
904
|
+
# Returns integer +80+, the default port to use for \HTTP requests:
|
905
|
+
#
|
906
|
+
# Net::HTTP.http_default_port # => 80
|
907
|
+
#
|
559
908
|
def HTTP.http_default_port
|
560
909
|
80
|
561
910
|
end
|
562
911
|
|
563
|
-
#
|
912
|
+
# Returns integer +443+, the default port to use for HTTPS requests:
|
913
|
+
#
|
914
|
+
# Net::HTTP.https_default_port # => 443
|
915
|
+
#
|
564
916
|
def HTTP.https_default_port
|
565
917
|
443
|
566
918
|
end
|
@@ -570,35 +922,91 @@ module Net #:nodoc:
|
|
570
922
|
end
|
571
923
|
|
572
924
|
# :call-seq:
|
573
|
-
# HTTP.start(address, port, p_addr, p_port, p_user, p_pass,
|
574
|
-
# HTTP.start(address, port=nil, p_addr
|
575
|
-
#
|
576
|
-
# Creates a new Net::HTTP object,
|
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
|
-
#
|
925
|
+
# HTTP.start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) -> http
|
926
|
+
# HTTP.start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) {|http| ... } -> object
|
927
|
+
#
|
928
|
+
# Creates a new \Net::HTTP object, +http+, via \Net::HTTP.new:
|
929
|
+
#
|
930
|
+
# - For arguments +address+ and +port+, see Net::HTTP.new.
|
931
|
+
# - For proxy-defining arguments +p_addr+ through +p_pass+,
|
932
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
933
|
+
# - For argument +opts+, see below.
|
934
|
+
#
|
935
|
+
# With no block given:
|
936
|
+
#
|
937
|
+
# - Calls <tt>http.start</tt> with no block (see #start),
|
938
|
+
# which opens a TCP connection and \HTTP session.
|
939
|
+
# - Returns +http+.
|
940
|
+
# - The caller should call #finish to close the session:
|
941
|
+
#
|
942
|
+
# http = Net::HTTP.start(hostname)
|
943
|
+
# http.started? # => true
|
944
|
+
# http.finish
|
945
|
+
# http.started? # => false
|
946
|
+
#
|
947
|
+
# With a block given:
|
948
|
+
#
|
949
|
+
# - Calls <tt>http.start</tt> with the block (see #start), which:
|
950
|
+
#
|
951
|
+
# - Opens a TCP connection and \HTTP session.
|
952
|
+
# - Calls the block,
|
953
|
+
# which may make any number of requests to the host.
|
954
|
+
# - Closes the \HTTP session and TCP connection on block exit.
|
955
|
+
# - Returns the block's value +object+.
|
956
|
+
#
|
957
|
+
# - Returns +object+.
|
958
|
+
#
|
959
|
+
# Example:
|
960
|
+
#
|
961
|
+
# hostname = 'jsonplaceholder.typicode.com'
|
962
|
+
# Net::HTTP.start(hostname) do |http|
|
963
|
+
# puts http.get('/todos/1').body
|
964
|
+
# puts http.get('/todos/2').body
|
965
|
+
# end
|
966
|
+
#
|
967
|
+
# Output:
|
968
|
+
#
|
969
|
+
# {
|
970
|
+
# "userId": 1,
|
971
|
+
# "id": 1,
|
972
|
+
# "title": "delectus aut autem",
|
973
|
+
# "completed": false
|
974
|
+
# }
|
975
|
+
# {
|
976
|
+
# "userId": 1,
|
977
|
+
# "id": 2,
|
978
|
+
# "title": "quis ut nam facilis et officia qui",
|
979
|
+
# "completed": false
|
980
|
+
# }
|
981
|
+
#
|
982
|
+
# If the last argument given is a hash, it is the +opts+ hash,
|
983
|
+
# where each key is a method or accessor to be called,
|
984
|
+
# and its value is the value to be set.
|
985
|
+
#
|
986
|
+
# The keys may include:
|
987
|
+
#
|
988
|
+
# - #ca_file
|
989
|
+
# - #ca_path
|
990
|
+
# - #cert
|
991
|
+
# - #cert_store
|
992
|
+
# - #ciphers
|
993
|
+
# - #close_on_empty_response
|
994
|
+
# - +ipaddr+ (calls #ipaddr=)
|
995
|
+
# - #keep_alive_timeout
|
996
|
+
# - #key
|
997
|
+
# - #open_timeout
|
998
|
+
# - #read_timeout
|
999
|
+
# - #ssl_timeout
|
1000
|
+
# - #ssl_version
|
1001
|
+
# - +use_ssl+ (calls #use_ssl=)
|
1002
|
+
# - #verify_callback
|
1003
|
+
# - #verify_depth
|
1004
|
+
# - #verify_mode
|
1005
|
+
# - #write_timeout
|
1006
|
+
#
|
1007
|
+
# Note: If +port+ is +nil+ and <tt>opts[:use_ssl]</tt> is a truthy value,
|
1008
|
+
# the value passed to +new+ is Net::HTTP.https_default_port, not +port+.
|
1009
|
+
#
|
602
1010
|
def HTTP.start(address, *arg, &block) # :yield: +http+
|
603
1011
|
arg.pop if opt = Hash.try_convert(arg[-1])
|
604
1012
|
port, p_addr, p_port, p_user, p_pass = *arg
|
@@ -625,25 +1033,34 @@ module Net #:nodoc:
|
|
625
1033
|
alias newobj new # :nodoc:
|
626
1034
|
end
|
627
1035
|
|
628
|
-
#
|
629
|
-
# HTTP session.
|
1036
|
+
# Returns a new \Net::HTTP object +http+
|
1037
|
+
# (but does not open a TCP connection or \HTTP session).
|
630
1038
|
#
|
631
|
-
#
|
632
|
-
#
|
633
|
-
#
|
1039
|
+
# With only string argument +address+ given
|
1040
|
+
# (and <tt>ENV['http_proxy']</tt> undefined or +nil+),
|
1041
|
+
# the returned +http+:
|
634
1042
|
#
|
635
|
-
#
|
636
|
-
#
|
637
|
-
#
|
638
|
-
# supply it by hand. See URI::Generic#find_proxy for details of proxy
|
639
|
-
# detection from the environment. To disable proxy detection set +p_addr+
|
640
|
-
# to nil.
|
1043
|
+
# - Has the given address.
|
1044
|
+
# - Has the default port number, Net::HTTP.default_port (80).
|
1045
|
+
# - Has no proxy.
|
641
1046
|
#
|
642
|
-
#
|
643
|
-
#
|
644
|
-
#
|
645
|
-
#
|
646
|
-
#
|
1047
|
+
# Example:
|
1048
|
+
#
|
1049
|
+
# http = Net::HTTP.new(hostname)
|
1050
|
+
# # => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
|
1051
|
+
# http.address # => "jsonplaceholder.typicode.com"
|
1052
|
+
# http.port # => 80
|
1053
|
+
# http.proxy? # => false
|
1054
|
+
#
|
1055
|
+
# With integer argument +port+ also given,
|
1056
|
+
# the returned +http+ has the given port:
|
1057
|
+
#
|
1058
|
+
# http = Net::HTTP.new(hostname, 8000)
|
1059
|
+
# # => #<Net::HTTP jsonplaceholder.typicode.com:8000 open=false>
|
1060
|
+
# http.port # => 8000
|
1061
|
+
#
|
1062
|
+
# For proxy-defining arguments +p_addr+ through +p_no_proxy+,
|
1063
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
647
1064
|
#
|
648
1065
|
def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
|
649
1066
|
http = super address, port
|
@@ -657,7 +1074,7 @@ module Net #:nodoc:
|
|
657
1074
|
elsif p_addr == :ENV then
|
658
1075
|
http.proxy_from_env = true
|
659
1076
|
else
|
660
|
-
if p_addr && p_no_proxy && !URI::Generic.use_proxy?(
|
1077
|
+
if p_addr && p_no_proxy && !URI::Generic.use_proxy?(address, address, port, p_no_proxy)
|
661
1078
|
p_addr = nil
|
662
1079
|
p_port = nil
|
663
1080
|
end
|
@@ -670,10 +1087,10 @@ module Net #:nodoc:
|
|
670
1087
|
http
|
671
1088
|
end
|
672
1089
|
|
673
|
-
# Creates a new Net::HTTP object for the specified server address,
|
674
|
-
# without opening the TCP connection or initializing the HTTP session.
|
1090
|
+
# Creates a new \Net::HTTP object for the specified server address,
|
1091
|
+
# without opening the TCP connection or initializing the \HTTP session.
|
675
1092
|
# The +address+ should be a DNS hostname or IP address.
|
676
|
-
def initialize(address, port = nil)
|
1093
|
+
def initialize(address, port = nil) # :nodoc:
|
677
1094
|
@address = address
|
678
1095
|
@port = (port || HTTP.default_port)
|
679
1096
|
@ipaddr = nil
|
@@ -691,6 +1108,8 @@ module Net #:nodoc:
|
|
691
1108
|
@continue_timeout = nil
|
692
1109
|
@max_retries = 1
|
693
1110
|
@debug_output = nil
|
1111
|
+
@response_body_encoding = false
|
1112
|
+
@ignore_eof = true
|
694
1113
|
|
695
1114
|
@proxy_from_env = false
|
696
1115
|
@proxy_uri = nil
|
@@ -708,6 +1127,11 @@ module Net #:nodoc:
|
|
708
1127
|
end
|
709
1128
|
end
|
710
1129
|
|
1130
|
+
# Returns a string representation of +self+:
|
1131
|
+
#
|
1132
|
+
# Net::HTTP.new(hostname).inspect
|
1133
|
+
# # => "#<Net::HTTP jsonplaceholder.typicode.com:80 open=false>"
|
1134
|
+
#
|
711
1135
|
def inspect
|
712
1136
|
"#<#{self.class} #{@address}:#{@port} open=#{started?}>"
|
713
1137
|
end
|
@@ -715,71 +1139,184 @@ module Net #:nodoc:
|
|
715
1139
|
# *WARNING* This method opens a serious security hole.
|
716
1140
|
# Never use this method in production code.
|
717
1141
|
#
|
718
|
-
# Sets
|
1142
|
+
# Sets the output stream for debugging:
|
719
1143
|
#
|
720
1144
|
# http = Net::HTTP.new(hostname)
|
721
|
-
#
|
722
|
-
#
|
1145
|
+
# File.open('t.tmp', 'w') do |file|
|
1146
|
+
# http.set_debug_output(file)
|
1147
|
+
# http.start
|
1148
|
+
# http.get('/nosuch/1')
|
1149
|
+
# http.finish
|
1150
|
+
# end
|
1151
|
+
# puts File.read('t.tmp')
|
1152
|
+
#
|
1153
|
+
# Output:
|
1154
|
+
#
|
1155
|
+
# opening connection to jsonplaceholder.typicode.com:80...
|
1156
|
+
# opened
|
1157
|
+
# <- "GET /nosuch/1 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: jsonplaceholder.typicode.com\r\n\r\n"
|
1158
|
+
# -> "HTTP/1.1 404 Not Found\r\n"
|
1159
|
+
# -> "Date: Mon, 12 Dec 2022 21:14:11 GMT\r\n"
|
1160
|
+
# -> "Content-Type: application/json; charset=utf-8\r\n"
|
1161
|
+
# -> "Content-Length: 2\r\n"
|
1162
|
+
# -> "Connection: keep-alive\r\n"
|
1163
|
+
# -> "X-Powered-By: Express\r\n"
|
1164
|
+
# -> "X-Ratelimit-Limit: 1000\r\n"
|
1165
|
+
# -> "X-Ratelimit-Remaining: 999\r\n"
|
1166
|
+
# -> "X-Ratelimit-Reset: 1670879660\r\n"
|
1167
|
+
# -> "Vary: Origin, Accept-Encoding\r\n"
|
1168
|
+
# -> "Access-Control-Allow-Credentials: true\r\n"
|
1169
|
+
# -> "Cache-Control: max-age=43200\r\n"
|
1170
|
+
# -> "Pragma: no-cache\r\n"
|
1171
|
+
# -> "Expires: -1\r\n"
|
1172
|
+
# -> "X-Content-Type-Options: nosniff\r\n"
|
1173
|
+
# -> "Etag: W/\"2-vyGp6PvFo4RvsFtPoIWeCReyIC8\"\r\n"
|
1174
|
+
# -> "Via: 1.1 vegur\r\n"
|
1175
|
+
# -> "CF-Cache-Status: MISS\r\n"
|
1176
|
+
# -> "Server-Timing: cf-q-config;dur=1.3000000762986e-05\r\n"
|
1177
|
+
# -> "Report-To: {\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=yOr40jo%2BwS1KHzhTlVpl54beJ5Wx2FcG4gGV0XVrh3X9OlR5q4drUn2dkt5DGO4GDcE%2BVXT7CNgJvGs%2BZleIyMu8CLieFiDIvOviOY3EhHg94m0ZNZgrEdpKD0S85S507l1vsEwEHkoTm%2Ff19SiO\"}],\"group\":\"cf-nel\",\"max_age\":604800}\r\n"
|
1178
|
+
# -> "NEL: {\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}\r\n"
|
1179
|
+
# -> "Server: cloudflare\r\n"
|
1180
|
+
# -> "CF-RAY: 778977dc484ce591-DFW\r\n"
|
1181
|
+
# -> "alt-svc: h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\r\n"
|
1182
|
+
# -> "\r\n"
|
1183
|
+
# reading 2 bytes...
|
1184
|
+
# -> "{}"
|
1185
|
+
# read 2 bytes
|
1186
|
+
# Conn keep-alive
|
723
1187
|
#
|
724
1188
|
def set_debug_output(output)
|
725
1189
|
warn 'Net::HTTP#set_debug_output called after HTTP started', uplevel: 1 if started?
|
726
1190
|
@debug_output = output
|
727
1191
|
end
|
728
1192
|
|
729
|
-
#
|
1193
|
+
# Returns the string host name or host IP given as argument +address+ in ::new.
|
730
1194
|
attr_reader :address
|
731
1195
|
|
732
|
-
#
|
1196
|
+
# Returns the integer port number given as argument +port+ in ::new.
|
733
1197
|
attr_reader :port
|
734
1198
|
|
735
|
-
#
|
1199
|
+
# Sets or returns the string local host used to establish the connection;
|
1200
|
+
# initially +nil+.
|
736
1201
|
attr_accessor :local_host
|
737
1202
|
|
738
|
-
#
|
1203
|
+
# Sets or returns the integer local port used to establish the connection;
|
1204
|
+
# initially +nil+.
|
739
1205
|
attr_accessor :local_port
|
740
1206
|
|
1207
|
+
# Returns the encoding to use for the response body;
|
1208
|
+
# see #response_body_encoding=.
|
1209
|
+
attr_reader :response_body_encoding
|
1210
|
+
|
1211
|
+
# Sets the encoding to be used for the response body;
|
1212
|
+
# returns the encoding.
|
1213
|
+
#
|
1214
|
+
# The given +value+ may be:
|
1215
|
+
#
|
1216
|
+
# - An Encoding object.
|
1217
|
+
# - The name of an encoding.
|
1218
|
+
# - An alias for an encoding name.
|
1219
|
+
#
|
1220
|
+
# See {Encoding}[https://docs.ruby-lang.org/en/master/Encoding.html].
|
1221
|
+
#
|
1222
|
+
# Examples:
|
1223
|
+
#
|
1224
|
+
# http = Net::HTTP.new(hostname)
|
1225
|
+
# http.response_body_encoding = Encoding::US_ASCII # => #<Encoding:US-ASCII>
|
1226
|
+
# http.response_body_encoding = 'US-ASCII' # => "US-ASCII"
|
1227
|
+
# http.response_body_encoding = 'ASCII' # => "ASCII"
|
1228
|
+
#
|
1229
|
+
def response_body_encoding=(value)
|
1230
|
+
value = Encoding.find(value) if value.is_a?(String)
|
1231
|
+
@response_body_encoding = value
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
# Sets whether to determine the proxy from environment variable
|
1235
|
+
# '<tt>ENV['http_proxy']</tt>';
|
1236
|
+
# see {Proxy Using ENV['http_proxy']}[rdoc-ref:Net::HTTP@Proxy+Using+-27ENV-5B-27http_proxy-27-5D-27].
|
741
1237
|
attr_writer :proxy_from_env
|
1238
|
+
|
1239
|
+
# Sets the proxy address;
|
1240
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
742
1241
|
attr_writer :proxy_address
|
1242
|
+
|
1243
|
+
# Sets the proxy port;
|
1244
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
743
1245
|
attr_writer :proxy_port
|
1246
|
+
|
1247
|
+
# Sets the proxy user;
|
1248
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
744
1249
|
attr_writer :proxy_user
|
1250
|
+
|
1251
|
+
# Sets the proxy password;
|
1252
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
745
1253
|
attr_writer :proxy_pass
|
746
1254
|
|
747
|
-
#
|
1255
|
+
# Returns the IP address for the connection.
|
1256
|
+
#
|
1257
|
+
# If the session has not been started,
|
1258
|
+
# returns the value set by #ipaddr=,
|
1259
|
+
# or +nil+ if it has not been set:
|
1260
|
+
#
|
1261
|
+
# http = Net::HTTP.new(hostname)
|
1262
|
+
# http.ipaddr # => nil
|
1263
|
+
# http.ipaddr = '172.67.155.76'
|
1264
|
+
# http.ipaddr # => "172.67.155.76"
|
1265
|
+
#
|
1266
|
+
# If the session has been started,
|
1267
|
+
# returns the IP address from the socket:
|
1268
|
+
#
|
1269
|
+
# http = Net::HTTP.new(hostname)
|
1270
|
+
# http.start
|
1271
|
+
# http.ipaddr # => "172.67.155.76"
|
1272
|
+
# http.finish
|
1273
|
+
#
|
748
1274
|
def ipaddr
|
749
1275
|
started? ? @socket.io.peeraddr[3] : @ipaddr
|
750
1276
|
end
|
751
1277
|
|
752
|
-
#
|
1278
|
+
# Sets the IP address for the connection:
|
1279
|
+
#
|
1280
|
+
# http = Net::HTTP.new(hostname)
|
1281
|
+
# http.ipaddr # => nil
|
1282
|
+
# http.ipaddr = '172.67.155.76'
|
1283
|
+
# http.ipaddr # => "172.67.155.76"
|
1284
|
+
#
|
1285
|
+
# The IP address may not be set if the session has been started.
|
753
1286
|
def ipaddr=(addr)
|
754
1287
|
raise IOError, "ipaddr value changed, but session already started" if started?
|
755
1288
|
@ipaddr = addr
|
756
1289
|
end
|
757
1290
|
|
758
|
-
#
|
759
|
-
#
|
760
|
-
#
|
761
|
-
#
|
1291
|
+
# Sets or returns the numeric (\Integer or \Float) number of seconds
|
1292
|
+
# to wait for a connection to open;
|
1293
|
+
# initially 60.
|
1294
|
+
# If the connection is not made in the given interval,
|
1295
|
+
# an exception is raised.
|
762
1296
|
attr_accessor :open_timeout
|
763
1297
|
|
764
|
-
#
|
765
|
-
#
|
766
|
-
#
|
767
|
-
# it raises a Net::ReadTimeout exception. The default value is 60 seconds.
|
1298
|
+
# Returns the numeric (\Integer or \Float) number of seconds
|
1299
|
+
# to wait for one block to be read (via one read(2) call);
|
1300
|
+
# see #read_timeout=.
|
768
1301
|
attr_reader :read_timeout
|
769
1302
|
|
770
|
-
#
|
771
|
-
#
|
772
|
-
#
|
773
|
-
# it raises a Net::WriteTimeout exception. The default value is 60 seconds.
|
774
|
-
# Net::WriteTimeout is not raised on Windows.
|
1303
|
+
# Returns the numeric (\Integer or \Float) number of seconds
|
1304
|
+
# to wait for one block to be written (via one write(2) call);
|
1305
|
+
# see #write_timeout=.
|
775
1306
|
attr_reader :write_timeout
|
776
1307
|
|
777
|
-
#
|
778
|
-
# Net::ReadTimeout, IOError, EOFError, Errno::ECONNRESET,
|
1308
|
+
# Sets the maximum number of times to retry an idempotent request in case of
|
1309
|
+
# \Net::ReadTimeout, IOError, EOFError, Errno::ECONNRESET,
|
779
1310
|
# Errno::ECONNABORTED, Errno::EPIPE, OpenSSL::SSL::SSLError,
|
780
1311
|
# Timeout::Error.
|
781
|
-
#
|
782
|
-
#
|
1312
|
+
# The initial value is 1.
|
1313
|
+
#
|
1314
|
+
# Argument +retries+ must be a non-negative numeric value:
|
1315
|
+
#
|
1316
|
+
# http = Net::HTTP.new(hostname)
|
1317
|
+
# http.max_retries = 2 # => 2
|
1318
|
+
# http.max_retries # => 2
|
1319
|
+
#
|
783
1320
|
def max_retries=(retries)
|
784
1321
|
retries = retries.to_int
|
785
1322
|
if retries < 0
|
@@ -788,55 +1325,113 @@ module Net #:nodoc:
|
|
788
1325
|
@max_retries = retries
|
789
1326
|
end
|
790
1327
|
|
1328
|
+
# Returns the maximum number of times to retry an idempotent request;
|
1329
|
+
# see #max_retries=.
|
791
1330
|
attr_reader :max_retries
|
792
1331
|
|
793
|
-
#
|
1332
|
+
# Sets the read timeout, in seconds, for +self+ to integer +sec+;
|
1333
|
+
# the initial value is 60.
|
1334
|
+
#
|
1335
|
+
# Argument +sec+ must be a non-negative numeric value:
|
1336
|
+
#
|
1337
|
+
# http = Net::HTTP.new(hostname)
|
1338
|
+
# http.read_timeout # => 60
|
1339
|
+
# http.get('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
|
1340
|
+
# http.read_timeout = 0
|
1341
|
+
# http.get('/todos/1') # Raises Net::ReadTimeout.
|
1342
|
+
#
|
794
1343
|
def read_timeout=(sec)
|
795
1344
|
@socket.read_timeout = sec if @socket
|
796
1345
|
@read_timeout = sec
|
797
1346
|
end
|
798
1347
|
|
799
|
-
#
|
1348
|
+
# Sets the write timeout, in seconds, for +self+ to integer +sec+;
|
1349
|
+
# the initial value is 60.
|
1350
|
+
#
|
1351
|
+
# Argument +sec+ must be a non-negative numeric value:
|
1352
|
+
#
|
1353
|
+
# _uri = uri.dup
|
1354
|
+
# _uri.path = '/posts'
|
1355
|
+
# body = 'bar' * 200000
|
1356
|
+
# data = <<EOF
|
1357
|
+
# {"title": "foo", "body": "#{body}", "userId": "1"}
|
1358
|
+
# EOF
|
1359
|
+
# headers = {'content-type': 'application/json'}
|
1360
|
+
# http = Net::HTTP.new(hostname)
|
1361
|
+
# http.write_timeout # => 60
|
1362
|
+
# http.post(_uri.path, data, headers)
|
1363
|
+
# # => #<Net::HTTPCreated 201 Created readbody=true>
|
1364
|
+
# http.write_timeout = 0
|
1365
|
+
# http.post(_uri.path, data, headers) # Raises Net::WriteTimeout.
|
1366
|
+
#
|
800
1367
|
def write_timeout=(sec)
|
801
1368
|
@socket.write_timeout = sec if @socket
|
802
1369
|
@write_timeout = sec
|
803
1370
|
end
|
804
1371
|
|
805
|
-
#
|
806
|
-
#
|
807
|
-
# default value is +nil+.
|
1372
|
+
# Returns the continue timeout value;
|
1373
|
+
# see continue_timeout=.
|
808
1374
|
attr_reader :continue_timeout
|
809
1375
|
|
810
|
-
#
|
1376
|
+
# Sets the continue timeout value,
|
1377
|
+
# which is the number of seconds to wait for an expected 100 Continue response.
|
1378
|
+
# If the \HTTP object does not receive a response in this many seconds
|
1379
|
+
# it sends the request body.
|
811
1380
|
def continue_timeout=(sec)
|
812
1381
|
@socket.continue_timeout = sec if @socket
|
813
1382
|
@continue_timeout = sec
|
814
1383
|
end
|
815
1384
|
|
816
|
-
#
|
817
|
-
#
|
818
|
-
#
|
819
|
-
#
|
1385
|
+
# Sets or returns the numeric (\Integer or \Float) number of seconds
|
1386
|
+
# to keep the connection open after a request is sent;
|
1387
|
+
# initially 2.
|
1388
|
+
# If a new request is made during the given interval,
|
1389
|
+
# the still-open connection is used;
|
1390
|
+
# otherwise the connection will have been closed
|
1391
|
+
# and a new connection is opened.
|
820
1392
|
attr_accessor :keep_alive_timeout
|
821
1393
|
|
822
|
-
#
|
1394
|
+
# Sets or returns whether to ignore end-of-file when reading a response body
|
1395
|
+
# with <tt>Content-Length</tt> headers;
|
1396
|
+
# initially +true+.
|
1397
|
+
attr_accessor :ignore_eof
|
1398
|
+
|
1399
|
+
# Returns +true+ if the \HTTP session has been started:
|
1400
|
+
#
|
1401
|
+
# http = Net::HTTP.new(hostname)
|
1402
|
+
# http.started? # => false
|
1403
|
+
# http.start
|
1404
|
+
# http.started? # => true
|
1405
|
+
# http.finish # => nil
|
1406
|
+
# http.started? # => false
|
1407
|
+
#
|
1408
|
+
# Net::HTTP.start(hostname) do |http|
|
1409
|
+
# http.started?
|
1410
|
+
# end # => true
|
1411
|
+
# http.started? # => false
|
1412
|
+
#
|
823
1413
|
def started?
|
824
1414
|
@started
|
825
1415
|
end
|
826
1416
|
|
827
1417
|
alias active? started? #:nodoc: obsolete
|
828
1418
|
|
1419
|
+
# Sets or returns whether to close the connection when the response is empty;
|
1420
|
+
# initially +false+.
|
829
1421
|
attr_accessor :close_on_empty_response
|
830
1422
|
|
831
|
-
# Returns true if
|
1423
|
+
# Returns +true+ if +self+ uses SSL, +false+ otherwise.
|
1424
|
+
# See Net::HTTP#use_ssl=.
|
832
1425
|
def use_ssl?
|
833
1426
|
@use_ssl
|
834
1427
|
end
|
835
1428
|
|
836
|
-
#
|
837
|
-
#
|
838
|
-
#
|
839
|
-
#
|
1429
|
+
# Sets whether a new session is to use
|
1430
|
+
# {Transport Layer Security}[https://en.wikipedia.org/wiki/Transport_Layer_Security]:
|
1431
|
+
#
|
1432
|
+
# Raises IOError if attempting to change during a session.
|
1433
|
+
#
|
1434
|
+
# Raises OpenSSL::SSL::SSLError if the port is not an HTTPS port.
|
840
1435
|
def use_ssl=(flag)
|
841
1436
|
flag = flag ? true : false
|
842
1437
|
if started? and @use_ssl != flag
|
@@ -861,7 +1456,7 @@ module Net #:nodoc:
|
|
861
1456
|
:@verify_depth,
|
862
1457
|
:@verify_mode,
|
863
1458
|
:@verify_hostname,
|
864
|
-
]
|
1459
|
+
] # :nodoc:
|
865
1460
|
SSL_ATTRIBUTES = [
|
866
1461
|
:ca_file,
|
867
1462
|
:ca_path,
|
@@ -878,64 +1473,67 @@ module Net #:nodoc:
|
|
878
1473
|
:verify_depth,
|
879
1474
|
:verify_mode,
|
880
1475
|
:verify_hostname,
|
881
|
-
]
|
1476
|
+
] # :nodoc:
|
882
1477
|
|
883
|
-
# Sets path
|
884
|
-
#
|
885
|
-
# The file can contain several CA certificates.
|
1478
|
+
# Sets or returns the path to a CA certification file in PEM format.
|
886
1479
|
attr_accessor :ca_file
|
887
1480
|
|
888
|
-
# Sets path of
|
889
|
-
# PEM format.
|
1481
|
+
# Sets or returns the path of to CA directory
|
1482
|
+
# containing certification files in PEM format.
|
890
1483
|
attr_accessor :ca_path
|
891
1484
|
|
892
|
-
# Sets
|
893
|
-
#
|
1485
|
+
# Sets or returns the OpenSSL::X509::Certificate object
|
1486
|
+
# to be used for client certification.
|
894
1487
|
attr_accessor :cert
|
895
1488
|
|
896
|
-
# Sets the X509::Store to
|
1489
|
+
# Sets or returns the X509::Store to be used for verifying peer certificate.
|
897
1490
|
attr_accessor :cert_store
|
898
1491
|
|
899
|
-
# Sets the available ciphers.
|
1492
|
+
# Sets or returns the available SSL ciphers.
|
1493
|
+
# See {OpenSSL::SSL::SSLContext#ciphers=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ciphers-3D].
|
900
1494
|
attr_accessor :ciphers
|
901
1495
|
|
902
|
-
# Sets the extra X509 certificates to be added to the certificate chain.
|
903
|
-
# See OpenSSL::SSL::SSLContext#
|
1496
|
+
# Sets or returns the extra X509 certificates to be added to the certificate chain.
|
1497
|
+
# See {OpenSSL::SSL::SSLContext#add_certificate}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-add_certificate].
|
904
1498
|
attr_accessor :extra_chain_cert
|
905
1499
|
|
906
|
-
# Sets
|
907
|
-
# (This method is appeared in Michal Rokos's OpenSSL extension.)
|
1500
|
+
# Sets or returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
|
908
1501
|
attr_accessor :key
|
909
1502
|
|
910
|
-
# Sets the SSL timeout seconds.
|
1503
|
+
# Sets or returns the SSL timeout seconds.
|
911
1504
|
attr_accessor :ssl_timeout
|
912
1505
|
|
913
|
-
# Sets the SSL version.
|
1506
|
+
# Sets or returns the SSL version.
|
1507
|
+
# See {OpenSSL::SSL::SSLContext#ssl_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D].
|
914
1508
|
attr_accessor :ssl_version
|
915
1509
|
|
916
|
-
# Sets the minimum SSL version.
|
1510
|
+
# Sets or returns the minimum SSL version.
|
1511
|
+
# See {OpenSSL::SSL::SSLContext#min_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D].
|
917
1512
|
attr_accessor :min_version
|
918
1513
|
|
919
|
-
# Sets the maximum SSL version.
|
1514
|
+
# Sets or returns the maximum SSL version.
|
1515
|
+
# See {OpenSSL::SSL::SSLContext#max_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D].
|
920
1516
|
attr_accessor :max_version
|
921
1517
|
|
922
|
-
# Sets the
|
1518
|
+
# Sets or returns the callback for the server certification verification.
|
923
1519
|
attr_accessor :verify_callback
|
924
1520
|
|
925
|
-
# Sets the maximum depth for the certificate chain verification.
|
1521
|
+
# Sets or returns the maximum depth for the certificate chain verification.
|
926
1522
|
attr_accessor :verify_depth
|
927
1523
|
|
928
|
-
# Sets the flags for server the certification verification
|
929
|
-
# SSL/TLS session.
|
930
|
-
#
|
1524
|
+
# Sets or returns the flags for server the certification verification
|
1525
|
+
# at the beginning of the SSL/TLS session.
|
931
1526
|
# OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER are acceptable.
|
932
1527
|
attr_accessor :verify_mode
|
933
1528
|
|
934
|
-
# Sets to
|
935
|
-
#
|
1529
|
+
# Sets or returns whether to verify that the server certificate is valid
|
1530
|
+
# for the hostname.
|
1531
|
+
# See {OpenSSL::SSL::SSLContext#verify_hostname=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#attribute-i-verify_mode].
|
936
1532
|
attr_accessor :verify_hostname
|
937
1533
|
|
938
|
-
# Returns the
|
1534
|
+
# Returns the X509 certificate chain (an array of strings)
|
1535
|
+
# for the session's socket peer,
|
1536
|
+
# or +nil+ if none.
|
939
1537
|
def peer_cert
|
940
1538
|
if not use_ssl? or not @socket
|
941
1539
|
return nil
|
@@ -943,14 +1541,26 @@ module Net #:nodoc:
|
|
943
1541
|
@socket.io.peer_cert
|
944
1542
|
end
|
945
1543
|
|
946
|
-
#
|
1544
|
+
# Starts an \HTTP session.
|
947
1545
|
#
|
948
|
-
#
|
949
|
-
# object to the block, and closes the TCP connection and HTTP session
|
950
|
-
# after the block has been executed.
|
1546
|
+
# Without a block, returns +self+:
|
951
1547
|
#
|
952
|
-
#
|
953
|
-
#
|
1548
|
+
# http = Net::HTTP.new(hostname)
|
1549
|
+
# # => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
|
1550
|
+
# http.start
|
1551
|
+
# # => #<Net::HTTP jsonplaceholder.typicode.com:80 open=true>
|
1552
|
+
# http.started? # => true
|
1553
|
+
# http.finish
|
1554
|
+
#
|
1555
|
+
# With a block, calls the block with +self+,
|
1556
|
+
# finishes the session when the block exits,
|
1557
|
+
# and returns the block's value:
|
1558
|
+
#
|
1559
|
+
# http.start do |http|
|
1560
|
+
# http
|
1561
|
+
# end
|
1562
|
+
# # => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
|
1563
|
+
# http.started? # => false
|
954
1564
|
#
|
955
1565
|
def start # :yield: http
|
956
1566
|
raise IOError, 'HTTP session already opened' if @started
|
@@ -973,6 +1583,12 @@ module Net #:nodoc:
|
|
973
1583
|
private :do_start
|
974
1584
|
|
975
1585
|
def connect
|
1586
|
+
if use_ssl?
|
1587
|
+
# reference early to load OpenSSL before connecting,
|
1588
|
+
# as OpenSSL may take time to load.
|
1589
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
1590
|
+
end
|
1591
|
+
|
976
1592
|
if proxy? then
|
977
1593
|
conn_addr = proxy_address
|
978
1594
|
conn_port = proxy_port
|
@@ -981,7 +1597,7 @@ module Net #:nodoc:
|
|
981
1597
|
conn_port = port
|
982
1598
|
end
|
983
1599
|
|
984
|
-
|
1600
|
+
debug "opening connection to #{conn_addr}:#{conn_port}..."
|
985
1601
|
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
|
986
1602
|
begin
|
987
1603
|
TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
|
@@ -991,15 +1607,15 @@ module Net #:nodoc:
|
|
991
1607
|
end
|
992
1608
|
}
|
993
1609
|
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
994
|
-
|
1610
|
+
debug "opened"
|
995
1611
|
if use_ssl?
|
996
1612
|
if proxy?
|
997
1613
|
plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
|
998
1614
|
write_timeout: @write_timeout,
|
999
1615
|
continue_timeout: @continue_timeout,
|
1000
1616
|
debug_output: @debug_output)
|
1001
|
-
buf = "CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n"
|
1002
|
-
|
1617
|
+
buf = +"CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n" \
|
1618
|
+
"Host: #{@address}:#{@port}\r\n"
|
1003
1619
|
if proxy_user
|
1004
1620
|
credential = ["#{proxy_user}:#{proxy_pass}"].pack('m0')
|
1005
1621
|
buf << "Proxy-Authorization: Basic #{credential}\r\n"
|
@@ -1020,35 +1636,56 @@ module Net #:nodoc:
|
|
1020
1636
|
end
|
1021
1637
|
end
|
1022
1638
|
end
|
1023
|
-
@ssl_context = OpenSSL::SSL::SSLContext.new
|
1024
1639
|
@ssl_context.set_params(ssl_parameters)
|
1025
|
-
@ssl_context.session_cache_mode
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1640
|
+
unless @ssl_context.session_cache_mode.nil? # a dummy method on JRuby
|
1641
|
+
@ssl_context.session_cache_mode =
|
1642
|
+
OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
|
1643
|
+
OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
|
1644
|
+
end
|
1645
|
+
if @ssl_context.respond_to?(:session_new_cb) # not implemented under JRuby
|
1646
|
+
@ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
|
1647
|
+
end
|
1648
|
+
|
1649
|
+
# Still do the post_connection_check below even if connecting
|
1650
|
+
# to IP address
|
1651
|
+
verify_hostname = @ssl_context.verify_hostname
|
1652
|
+
|
1653
|
+
# Server Name Indication (SNI) RFC 3546/6066
|
1654
|
+
case @address
|
1655
|
+
when Resolv::IPv4::Regex, Resolv::IPv6::Regex
|
1656
|
+
# don't set SNI, as IP addresses in SNI is not valid
|
1657
|
+
# per RFC 6066, section 3.
|
1658
|
+
|
1659
|
+
# Avoid openssl warning
|
1660
|
+
@ssl_context.verify_hostname = false
|
1661
|
+
else
|
1662
|
+
ssl_host_address = @address
|
1663
|
+
end
|
1664
|
+
|
1665
|
+
debug "starting SSL for #{conn_addr}:#{conn_port}..."
|
1030
1666
|
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
|
1031
1667
|
s.sync_close = true
|
1032
|
-
|
1033
|
-
|
1668
|
+
s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address
|
1669
|
+
|
1034
1670
|
if @ssl_session and
|
1035
1671
|
Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
|
1036
1672
|
s.session = @ssl_session
|
1037
1673
|
end
|
1038
1674
|
ssl_socket_connect(s, @open_timeout)
|
1039
|
-
if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) &&
|
1675
|
+
if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
|
1040
1676
|
s.post_connection_check(@address)
|
1041
1677
|
end
|
1042
|
-
|
1678
|
+
debug "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
|
1043
1679
|
end
|
1044
1680
|
@socket = BufferedIO.new(s, read_timeout: @read_timeout,
|
1045
1681
|
write_timeout: @write_timeout,
|
1046
1682
|
continue_timeout: @continue_timeout,
|
1047
1683
|
debug_output: @debug_output)
|
1684
|
+
@last_communicated = nil
|
1048
1685
|
on_connect
|
1049
1686
|
rescue => exception
|
1050
1687
|
if s
|
1051
|
-
|
1688
|
+
debug "Conn close because of connect error #{exception}"
|
1052
1689
|
s.close
|
1053
1690
|
end
|
1054
1691
|
raise
|
@@ -1059,8 +1696,15 @@ module Net #:nodoc:
|
|
1059
1696
|
end
|
1060
1697
|
private :on_connect
|
1061
1698
|
|
1062
|
-
# Finishes the HTTP session
|
1063
|
-
#
|
1699
|
+
# Finishes the \HTTP session:
|
1700
|
+
#
|
1701
|
+
# http = Net::HTTP.new(hostname)
|
1702
|
+
# http.start
|
1703
|
+
# http.started? # => true
|
1704
|
+
# http.finish # => nil
|
1705
|
+
# http.started? # => false
|
1706
|
+
#
|
1707
|
+
# Raises IOError if not in a session.
|
1064
1708
|
def finish
|
1065
1709
|
raise IOError, 'HTTP session not yet started' unless started?
|
1066
1710
|
do_finish
|
@@ -1087,12 +1731,12 @@ module Net #:nodoc:
|
|
1087
1731
|
@proxy_user = nil
|
1088
1732
|
@proxy_pass = nil
|
1089
1733
|
|
1090
|
-
# Creates an HTTP proxy class which behaves like Net::HTTP, but
|
1734
|
+
# Creates an \HTTP proxy class which behaves like \Net::HTTP, but
|
1091
1735
|
# performs all access via the specified proxy.
|
1092
1736
|
#
|
1093
1737
|
# This class is obsolete. You may pass these same parameters directly to
|
1094
|
-
# Net::HTTP.new. See Net::HTTP.new for details of the arguments.
|
1095
|
-
def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil)
|
1738
|
+
# \Net::HTTP.new. See Net::HTTP.new for details of the arguments.
|
1739
|
+
def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil) #:nodoc:
|
1096
1740
|
return self unless p_addr
|
1097
1741
|
|
1098
1742
|
Class.new(self) {
|
@@ -1114,31 +1758,37 @@ module Net #:nodoc:
|
|
1114
1758
|
end
|
1115
1759
|
|
1116
1760
|
class << HTTP
|
1117
|
-
#
|
1761
|
+
# Returns true if self is a class which was created by HTTP::Proxy.
|
1118
1762
|
def proxy_class?
|
1119
1763
|
defined?(@is_proxy_class) ? @is_proxy_class : false
|
1120
1764
|
end
|
1121
1765
|
|
1122
|
-
#
|
1766
|
+
# Returns the address of the proxy host, or +nil+ if none;
|
1767
|
+
# see Net::HTTP@Proxy+Server.
|
1123
1768
|
attr_reader :proxy_address
|
1124
1769
|
|
1125
|
-
#
|
1770
|
+
# Returns the port number of the proxy host, or +nil+ if none;
|
1771
|
+
# see Net::HTTP@Proxy+Server.
|
1126
1772
|
attr_reader :proxy_port
|
1127
1773
|
|
1128
|
-
#
|
1774
|
+
# Returns the user name for accessing the proxy, or +nil+ if none;
|
1775
|
+
# see Net::HTTP@Proxy+Server.
|
1129
1776
|
attr_reader :proxy_user
|
1130
1777
|
|
1131
|
-
#
|
1132
|
-
#
|
1778
|
+
# Returns the password for accessing the proxy, or +nil+ if none;
|
1779
|
+
# see Net::HTTP@Proxy+Server.
|
1133
1780
|
attr_reader :proxy_pass
|
1134
1781
|
end
|
1135
1782
|
|
1136
|
-
#
|
1783
|
+
# Returns +true+ if a proxy server is defined, +false+ otherwise;
|
1784
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
1137
1785
|
def proxy?
|
1138
1786
|
!!(@proxy_from_env ? proxy_uri : @proxy_address)
|
1139
1787
|
end
|
1140
1788
|
|
1141
|
-
#
|
1789
|
+
# Returns +true+ if the proxy server is defined in the environment,
|
1790
|
+
# +false+ otherwise;
|
1791
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
1142
1792
|
def proxy_from_env?
|
1143
1793
|
@proxy_from_env
|
1144
1794
|
end
|
@@ -1147,12 +1797,13 @@ module Net #:nodoc:
|
|
1147
1797
|
def proxy_uri # :nodoc:
|
1148
1798
|
return if @proxy_uri == false
|
1149
1799
|
@proxy_uri ||= URI::HTTP.new(
|
1150
|
-
"http"
|
1800
|
+
"http", nil, address, port, nil, nil, nil, nil, nil
|
1151
1801
|
).find_proxy || false
|
1152
1802
|
@proxy_uri || nil
|
1153
1803
|
end
|
1154
1804
|
|
1155
|
-
#
|
1805
|
+
# Returns the address of the proxy server, if defined, +nil+ otherwise;
|
1806
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
1156
1807
|
def proxy_address
|
1157
1808
|
if @proxy_from_env then
|
1158
1809
|
proxy_uri&.hostname
|
@@ -1161,7 +1812,8 @@ module Net #:nodoc:
|
|
1161
1812
|
end
|
1162
1813
|
end
|
1163
1814
|
|
1164
|
-
#
|
1815
|
+
# Returns the port number of the proxy server, if defined, +nil+ otherwise;
|
1816
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
1165
1817
|
def proxy_port
|
1166
1818
|
if @proxy_from_env then
|
1167
1819
|
proxy_uri&.port
|
@@ -1170,26 +1822,23 @@ module Net #:nodoc:
|
|
1170
1822
|
end
|
1171
1823
|
end
|
1172
1824
|
|
1173
|
-
#
|
1174
|
-
|
1175
|
-
ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE = true
|
1176
|
-
else
|
1177
|
-
ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE = false
|
1178
|
-
end
|
1179
|
-
|
1180
|
-
# The username of the proxy server, if one is configured.
|
1825
|
+
# Returns the user name of the proxy server, if defined, +nil+ otherwise;
|
1826
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
1181
1827
|
def proxy_user
|
1182
|
-
if
|
1183
|
-
proxy_uri&.user
|
1828
|
+
if @proxy_from_env
|
1829
|
+
user = proxy_uri&.user
|
1830
|
+
unescape(user) if user
|
1184
1831
|
else
|
1185
1832
|
@proxy_user
|
1186
1833
|
end
|
1187
1834
|
end
|
1188
1835
|
|
1189
|
-
#
|
1836
|
+
# Returns the password of the proxy server, if defined, +nil+ otherwise;
|
1837
|
+
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
|
1190
1838
|
def proxy_pass
|
1191
|
-
if
|
1192
|
-
proxy_uri&.password
|
1839
|
+
if @proxy_from_env
|
1840
|
+
pass = proxy_uri&.password
|
1841
|
+
unescape(pass) if pass
|
1193
1842
|
else
|
1194
1843
|
@proxy_pass
|
1195
1844
|
end
|
@@ -1200,6 +1849,11 @@ module Net #:nodoc:
|
|
1200
1849
|
|
1201
1850
|
private
|
1202
1851
|
|
1852
|
+
def unescape(value)
|
1853
|
+
require 'cgi/util'
|
1854
|
+
CGI.unescape(value)
|
1855
|
+
end
|
1856
|
+
|
1203
1857
|
# without proxy, obsolete
|
1204
1858
|
|
1205
1859
|
def conn_address # :nodoc:
|
@@ -1228,45 +1882,38 @@ module Net #:nodoc:
|
|
1228
1882
|
|
1229
1883
|
public
|
1230
1884
|
|
1231
|
-
#
|
1232
|
-
#
|
1885
|
+
# :call-seq:
|
1886
|
+
# get(path, initheader = nil) {|res| ... }
|
1887
|
+
#
|
1888
|
+
# Sends a GET request to the server;
|
1889
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
1233
1890
|
#
|
1234
|
-
#
|
1235
|
-
#
|
1236
|
-
# If +initheader+ doesn't have the key 'accept-encoding', then
|
1237
|
-
# a value of "gzip;q=1.0,deflate;q=0.6,identity;q=0.3" is used,
|
1238
|
-
# so that gzip compression is used in preference to deflate
|
1239
|
-
# compression, which is used in preference to no compression.
|
1240
|
-
# Ruby doesn't have libraries to support the compress (Lempel-Ziv)
|
1241
|
-
# compression, so that is not supported. The intent of this is
|
1242
|
-
# to reduce bandwidth by default. If this routine sets up
|
1243
|
-
# compression, then it does the decompression also, removing
|
1244
|
-
# the header as well to prevent confusion. Otherwise
|
1245
|
-
# it leaves the body as it found it.
|
1891
|
+
# The request is based on the Net::HTTP::Get object
|
1892
|
+
# created from string +path+ and initial headers hash +initheader+.
|
1246
1893
|
#
|
1247
|
-
#
|
1894
|
+
# With a block given, calls the block with the response body:
|
1248
1895
|
#
|
1249
|
-
#
|
1250
|
-
#
|
1251
|
-
#
|
1252
|
-
#
|
1896
|
+
# http = Net::HTTP.new(hostname)
|
1897
|
+
# http.get('/todos/1') do |res|
|
1898
|
+
# p res
|
1899
|
+
# end # => #<Net::HTTPOK 200 OK readbody=true>
|
1900
|
+
#
|
1901
|
+
# Output:
|
1253
1902
|
#
|
1254
|
-
#
|
1255
|
-
# It still works but you must not use it.
|
1903
|
+
# "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n}"
|
1256
1904
|
#
|
1257
|
-
#
|
1905
|
+
# With no block given, simply returns the response object:
|
1258
1906
|
#
|
1259
|
-
#
|
1907
|
+
# http.get('/') # => #<Net::HTTPOK 200 OK readbody=true>
|
1260
1908
|
#
|
1261
|
-
#
|
1262
|
-
#
|
1263
|
-
#
|
1264
|
-
#
|
1265
|
-
# end
|
1266
|
-
# }
|
1909
|
+
# Related:
|
1910
|
+
#
|
1911
|
+
# - Net::HTTP::Get: request class for \HTTP method GET.
|
1912
|
+
# - Net::HTTP.get: sends GET request, returns response body.
|
1267
1913
|
#
|
1268
1914
|
def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+
|
1269
1915
|
res = nil
|
1916
|
+
|
1270
1917
|
request(Get.new(path, initheader)) {|r|
|
1271
1918
|
r.read_body dest, &block
|
1272
1919
|
res = r
|
@@ -1274,198 +1921,312 @@ module Net #:nodoc:
|
|
1274
1921
|
res
|
1275
1922
|
end
|
1276
1923
|
|
1277
|
-
#
|
1278
|
-
#
|
1924
|
+
# Sends a HEAD request to the server;
|
1925
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
1279
1926
|
#
|
1280
|
-
#
|
1927
|
+
# The request is based on the Net::HTTP::Head object
|
1928
|
+
# created from string +path+ and initial headers hash +initheader+:
|
1281
1929
|
#
|
1282
|
-
#
|
1283
|
-
#
|
1284
|
-
#
|
1285
|
-
#
|
1286
|
-
#
|
1287
|
-
#
|
1288
|
-
#
|
1930
|
+
# res = http.head('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
|
1931
|
+
# res.body # => nil
|
1932
|
+
# res.to_hash.take(3)
|
1933
|
+
# # =>
|
1934
|
+
# [["date", ["Wed, 15 Feb 2023 15:25:42 GMT"]],
|
1935
|
+
# ["content-type", ["application/json; charset=utf-8"]],
|
1936
|
+
# ["connection", ["close"]]]
|
1289
1937
|
#
|
1290
1938
|
def head(path, initheader = nil)
|
1291
1939
|
request(Head.new(path, initheader))
|
1292
1940
|
end
|
1293
1941
|
|
1294
|
-
#
|
1295
|
-
#
|
1942
|
+
# :call-seq:
|
1943
|
+
# post(path, data, initheader = nil) {|res| ... }
|
1296
1944
|
#
|
1297
|
-
#
|
1945
|
+
# Sends a POST request to the server;
|
1946
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
1298
1947
|
#
|
1299
|
-
#
|
1300
|
-
#
|
1301
|
-
# the socket. Note that in this case, the returned response
|
1302
|
-
# object will *not* contain a (meaningful) body.
|
1948
|
+
# The request is based on the Net::HTTP::Post object
|
1949
|
+
# created from string +path+, string +data+, and initial headers hash +initheader+.
|
1303
1950
|
#
|
1304
|
-
#
|
1305
|
-
#
|
1951
|
+
# With a block given, calls the block with the response body:
|
1952
|
+
#
|
1953
|
+
# data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
|
1954
|
+
# http = Net::HTTP.new(hostname)
|
1955
|
+
# http.post('/todos', data) do |res|
|
1956
|
+
# p res
|
1957
|
+
# end # => #<Net::HTTPCreated 201 Created readbody=true>
|
1306
1958
|
#
|
1307
|
-
#
|
1959
|
+
# Output:
|
1308
1960
|
#
|
1309
|
-
#
|
1961
|
+
# "{\n \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\",\n \"id\": 201\n}"
|
1310
1962
|
#
|
1311
|
-
#
|
1312
|
-
# File.open('result.txt', 'w') {|f|
|
1313
|
-
# http.post('/cgi-bin/search.rb', 'query=foo') do |str|
|
1314
|
-
# f.write str
|
1315
|
-
# end
|
1316
|
-
# }
|
1963
|
+
# With no block given, simply returns the response object:
|
1317
1964
|
#
|
1318
|
-
#
|
1319
|
-
#
|
1320
|
-
#
|
1965
|
+
# http.post('/todos', data) # => #<Net::HTTPCreated 201 Created readbody=true>
|
1966
|
+
#
|
1967
|
+
# Related:
|
1968
|
+
#
|
1969
|
+
# - Net::HTTP::Post: request class for \HTTP method POST.
|
1970
|
+
# - Net::HTTP.post: sends POST request, returns response body.
|
1321
1971
|
#
|
1322
1972
|
def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
|
1323
1973
|
send_entity(path, data, initheader, dest, Post, &block)
|
1324
1974
|
end
|
1325
1975
|
|
1326
|
-
#
|
1327
|
-
#
|
1976
|
+
# :call-seq:
|
1977
|
+
# patch(path, data, initheader = nil) {|res| ... }
|
1978
|
+
#
|
1979
|
+
# Sends a PATCH request to the server;
|
1980
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
1981
|
+
#
|
1982
|
+
# The request is based on the Net::HTTP::Patch object
|
1983
|
+
# created from string +path+, string +data+, and initial headers hash +initheader+.
|
1984
|
+
#
|
1985
|
+
# With a block given, calls the block with the response body:
|
1986
|
+
#
|
1987
|
+
# data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
|
1988
|
+
# http = Net::HTTP.new(hostname)
|
1989
|
+
# http.patch('/todos/1', data) do |res|
|
1990
|
+
# p res
|
1991
|
+
# end # => #<Net::HTTPOK 200 OK readbody=true>
|
1992
|
+
#
|
1993
|
+
# Output:
|
1994
|
+
#
|
1995
|
+
# "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false,\n \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\"\n}"
|
1996
|
+
#
|
1997
|
+
# With no block given, simply returns the response object:
|
1998
|
+
#
|
1999
|
+
# http.patch('/todos/1', data) # => #<Net::HTTPCreated 201 Created readbody=true>
|
2000
|
+
#
|
1328
2001
|
def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
|
1329
2002
|
send_entity(path, data, initheader, dest, Patch, &block)
|
1330
2003
|
end
|
1331
2004
|
|
1332
|
-
|
2005
|
+
# Sends a PUT request to the server;
|
2006
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2007
|
+
#
|
2008
|
+
# The request is based on the Net::HTTP::Put object
|
2009
|
+
# created from string +path+, string +data+, and initial headers hash +initheader+.
|
2010
|
+
#
|
2011
|
+
# data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
|
2012
|
+
# http = Net::HTTP.new(hostname)
|
2013
|
+
# http.put('/todos/1', data) # => #<Net::HTTPOK 200 OK readbody=true>
|
2014
|
+
#
|
2015
|
+
def put(path, data, initheader = nil)
|
1333
2016
|
request(Put.new(path, initheader), data)
|
1334
2017
|
end
|
1335
2018
|
|
1336
|
-
# Sends a PROPPATCH request to the
|
1337
|
-
#
|
2019
|
+
# Sends a PROPPATCH request to the server;
|
2020
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2021
|
+
#
|
2022
|
+
# The request is based on the Net::HTTP::Proppatch object
|
2023
|
+
# created from string +path+, string +body+, and initial headers hash +initheader+.
|
2024
|
+
#
|
2025
|
+
# data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
|
2026
|
+
# http = Net::HTTP.new(hostname)
|
2027
|
+
# http.proppatch('/todos/1', data)
|
2028
|
+
#
|
1338
2029
|
def proppatch(path, body, initheader = nil)
|
1339
2030
|
request(Proppatch.new(path, initheader), body)
|
1340
2031
|
end
|
1341
2032
|
|
1342
|
-
# Sends a LOCK request to the
|
1343
|
-
#
|
2033
|
+
# Sends a LOCK request to the server;
|
2034
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2035
|
+
#
|
2036
|
+
# The request is based on the Net::HTTP::Lock object
|
2037
|
+
# created from string +path+, string +body+, and initial headers hash +initheader+.
|
2038
|
+
#
|
2039
|
+
# data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
|
2040
|
+
# http = Net::HTTP.new(hostname)
|
2041
|
+
# http.lock('/todos/1', data)
|
2042
|
+
#
|
1344
2043
|
def lock(path, body, initheader = nil)
|
1345
2044
|
request(Lock.new(path, initheader), body)
|
1346
2045
|
end
|
1347
2046
|
|
1348
|
-
# Sends
|
1349
|
-
#
|
2047
|
+
# Sends an UNLOCK request to the server;
|
2048
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2049
|
+
#
|
2050
|
+
# The request is based on the Net::HTTP::Unlock object
|
2051
|
+
# created from string +path+, string +body+, and initial headers hash +initheader+.
|
2052
|
+
#
|
2053
|
+
# data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
|
2054
|
+
# http = Net::HTTP.new(hostname)
|
2055
|
+
# http.unlock('/todos/1', data)
|
2056
|
+
#
|
1350
2057
|
def unlock(path, body, initheader = nil)
|
1351
2058
|
request(Unlock.new(path, initheader), body)
|
1352
2059
|
end
|
1353
2060
|
|
1354
|
-
# Sends
|
1355
|
-
#
|
2061
|
+
# Sends an Options request to the server;
|
2062
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2063
|
+
#
|
2064
|
+
# The request is based on the Net::HTTP::Options object
|
2065
|
+
# created from string +path+ and initial headers hash +initheader+.
|
2066
|
+
#
|
2067
|
+
# http = Net::HTTP.new(hostname)
|
2068
|
+
# http.options('/')
|
2069
|
+
#
|
1356
2070
|
def options(path, initheader = nil)
|
1357
2071
|
request(Options.new(path, initheader))
|
1358
2072
|
end
|
1359
2073
|
|
1360
|
-
# Sends a PROPFIND request to the
|
1361
|
-
#
|
2074
|
+
# Sends a PROPFIND request to the server;
|
2075
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2076
|
+
#
|
2077
|
+
# The request is based on the Net::HTTP::Propfind object
|
2078
|
+
# created from string +path+, string +body+, and initial headers hash +initheader+.
|
2079
|
+
#
|
2080
|
+
# data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
|
2081
|
+
# http = Net::HTTP.new(hostname)
|
2082
|
+
# http.propfind('/todos/1', data)
|
2083
|
+
#
|
1362
2084
|
def propfind(path, body = nil, initheader = {'Depth' => '0'})
|
1363
2085
|
request(Propfind.new(path, initheader), body)
|
1364
2086
|
end
|
1365
2087
|
|
1366
|
-
# Sends a DELETE request to the
|
1367
|
-
#
|
2088
|
+
# Sends a DELETE request to the server;
|
2089
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2090
|
+
#
|
2091
|
+
# The request is based on the Net::HTTP::Delete object
|
2092
|
+
# created from string +path+ and initial headers hash +initheader+.
|
2093
|
+
#
|
2094
|
+
# http = Net::HTTP.new(hostname)
|
2095
|
+
# http.delete('/todos/1')
|
2096
|
+
#
|
1368
2097
|
def delete(path, initheader = {'Depth' => 'Infinity'})
|
1369
2098
|
request(Delete.new(path, initheader))
|
1370
2099
|
end
|
1371
2100
|
|
1372
|
-
# Sends a MOVE request to the
|
1373
|
-
#
|
2101
|
+
# Sends a MOVE request to the server;
|
2102
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2103
|
+
#
|
2104
|
+
# The request is based on the Net::HTTP::Move object
|
2105
|
+
# created from string +path+ and initial headers hash +initheader+.
|
2106
|
+
#
|
2107
|
+
# http = Net::HTTP.new(hostname)
|
2108
|
+
# http.move('/todos/1')
|
2109
|
+
#
|
1374
2110
|
def move(path, initheader = nil)
|
1375
2111
|
request(Move.new(path, initheader))
|
1376
2112
|
end
|
1377
2113
|
|
1378
|
-
# Sends a COPY request to the
|
1379
|
-
#
|
2114
|
+
# Sends a COPY request to the server;
|
2115
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2116
|
+
#
|
2117
|
+
# The request is based on the Net::HTTP::Copy object
|
2118
|
+
# created from string +path+ and initial headers hash +initheader+.
|
2119
|
+
#
|
2120
|
+
# http = Net::HTTP.new(hostname)
|
2121
|
+
# http.copy('/todos/1')
|
2122
|
+
#
|
1380
2123
|
def copy(path, initheader = nil)
|
1381
2124
|
request(Copy.new(path, initheader))
|
1382
2125
|
end
|
1383
2126
|
|
1384
|
-
# Sends a MKCOL request to the
|
1385
|
-
#
|
2127
|
+
# Sends a MKCOL request to the server;
|
2128
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2129
|
+
#
|
2130
|
+
# The request is based on the Net::HTTP::Mkcol object
|
2131
|
+
# created from string +path+, string +body+, and initial headers hash +initheader+.
|
2132
|
+
#
|
2133
|
+
# data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
|
2134
|
+
# http.mkcol('/todos/1', data)
|
2135
|
+
# http = Net::HTTP.new(hostname)
|
2136
|
+
#
|
1386
2137
|
def mkcol(path, body = nil, initheader = nil)
|
1387
2138
|
request(Mkcol.new(path, initheader), body)
|
1388
2139
|
end
|
1389
2140
|
|
1390
|
-
# Sends a TRACE request to the
|
1391
|
-
#
|
2141
|
+
# Sends a TRACE request to the server;
|
2142
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2143
|
+
#
|
2144
|
+
# The request is based on the Net::HTTP::Trace object
|
2145
|
+
# created from string +path+ and initial headers hash +initheader+.
|
2146
|
+
#
|
2147
|
+
# http = Net::HTTP.new(hostname)
|
2148
|
+
# http.trace('/todos/1')
|
2149
|
+
#
|
1392
2150
|
def trace(path, initheader = nil)
|
1393
2151
|
request(Trace.new(path, initheader))
|
1394
2152
|
end
|
1395
2153
|
|
1396
|
-
# Sends a GET request to the
|
1397
|
-
#
|
2154
|
+
# Sends a GET request to the server;
|
2155
|
+
# forms the response into a Net::HTTPResponse object.
|
2156
|
+
#
|
2157
|
+
# The request is based on the Net::HTTP::Get object
|
2158
|
+
# created from string +path+ and initial headers hash +initheader+.
|
1398
2159
|
#
|
1399
|
-
#
|
1400
|
-
# The body of the response will not have been read yet;
|
1401
|
-
# the block can process it using HTTPResponse#read_body,
|
1402
|
-
# if desired.
|
2160
|
+
# With no block given, returns the response object:
|
1403
2161
|
#
|
1404
|
-
#
|
2162
|
+
# http = Net::HTTP.new(hostname)
|
2163
|
+
# http.request_get('/todos') # => #<Net::HTTPOK 200 OK readbody=true>
|
2164
|
+
#
|
2165
|
+
# With a block given, calls the block with the response object
|
2166
|
+
# and returns the response object:
|
1405
2167
|
#
|
1406
|
-
#
|
2168
|
+
# http.request_get('/todos') do |res|
|
2169
|
+
# p res
|
2170
|
+
# end # => #<Net::HTTPOK 200 OK readbody=true>
|
1407
2171
|
#
|
1408
|
-
#
|
1409
|
-
# # The entity body is already read in this case.
|
1410
|
-
# p response['content-type']
|
1411
|
-
# puts response.body
|
2172
|
+
# Output:
|
1412
2173
|
#
|
1413
|
-
#
|
1414
|
-
# http.request_get('/index.html') {|response|
|
1415
|
-
# p response['content-type']
|
1416
|
-
# response.read_body do |str| # read body now
|
1417
|
-
# print str
|
1418
|
-
# end
|
1419
|
-
# }
|
2174
|
+
# #<Net::HTTPOK 200 OK readbody=false>
|
1420
2175
|
#
|
1421
2176
|
def request_get(path, initheader = nil, &block) # :yield: +response+
|
1422
2177
|
request(Get.new(path, initheader), &block)
|
1423
2178
|
end
|
1424
2179
|
|
1425
|
-
# Sends a HEAD request to the
|
1426
|
-
#
|
2180
|
+
# Sends a HEAD request to the server;
|
2181
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
1427
2182
|
#
|
1428
|
-
#
|
2183
|
+
# The request is based on the Net::HTTP::Head object
|
2184
|
+
# created from string +path+ and initial headers hash +initheader+.
|
1429
2185
|
#
|
1430
|
-
#
|
1431
|
-
#
|
1432
|
-
# response = http.request_head('/index.html')
|
1433
|
-
# p response['content-type']
|
2186
|
+
# http = Net::HTTP.new(hostname)
|
2187
|
+
# http.head('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
|
1434
2188
|
#
|
1435
2189
|
def request_head(path, initheader = nil, &block)
|
1436
2190
|
request(Head.new(path, initheader), &block)
|
1437
2191
|
end
|
1438
2192
|
|
1439
|
-
# Sends a POST request to the
|
2193
|
+
# Sends a POST request to the server;
|
2194
|
+
# forms the response into a Net::HTTPResponse object.
|
1440
2195
|
#
|
1441
|
-
#
|
2196
|
+
# The request is based on the Net::HTTP::Post object
|
2197
|
+
# created from string +path+, string +data+, and initial headers hash +initheader+.
|
1442
2198
|
#
|
1443
|
-
#
|
1444
|
-
# object. The body of that response will not have been read yet;
|
1445
|
-
# the block can process it using HTTPResponse#read_body, if desired.
|
2199
|
+
# With no block given, returns the response object:
|
1446
2200
|
#
|
1447
|
-
#
|
2201
|
+
# http = Net::HTTP.new(hostname)
|
2202
|
+
# http.post('/todos', 'xyzzy')
|
2203
|
+
# # => #<Net::HTTPCreated 201 Created readbody=true>
|
2204
|
+
#
|
2205
|
+
# With a block given, calls the block with the response body
|
2206
|
+
# and returns the response object:
|
1448
2207
|
#
|
1449
|
-
#
|
2208
|
+
# http.post('/todos', 'xyzzy') do |res|
|
2209
|
+
# p res
|
2210
|
+
# end # => #<Net::HTTPCreated 201 Created readbody=true>
|
1450
2211
|
#
|
1451
|
-
#
|
1452
|
-
# response = http.request_post('/cgi-bin/nice.rb', 'datadatadata...')
|
1453
|
-
# p response.status
|
1454
|
-
# puts response.body # body is already read in this case
|
2212
|
+
# Output:
|
1455
2213
|
#
|
1456
|
-
#
|
1457
|
-
# http.request_post('/cgi-bin/nice.rb', 'datadatadata...') {|response|
|
1458
|
-
# p response.status
|
1459
|
-
# p response['content-type']
|
1460
|
-
# response.read_body do |str| # read body now
|
1461
|
-
# print str
|
1462
|
-
# end
|
1463
|
-
# }
|
2214
|
+
# "{\n \"xyzzy\": \"\",\n \"id\": 201\n}"
|
1464
2215
|
#
|
1465
2216
|
def request_post(path, data, initheader = nil, &block) # :yield: +response+
|
1466
2217
|
request Post.new(path, initheader), data, &block
|
1467
2218
|
end
|
1468
2219
|
|
2220
|
+
# Sends a PUT request to the server;
|
2221
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
2222
|
+
#
|
2223
|
+
# The request is based on the Net::HTTP::Put object
|
2224
|
+
# created from string +path+, string +data+, and initial headers hash +initheader+.
|
2225
|
+
#
|
2226
|
+
# http = Net::HTTP.new(hostname)
|
2227
|
+
# http.put('/todos/1', 'xyzzy')
|
2228
|
+
# # => #<Net::HTTPOK 200 OK readbody=true>
|
2229
|
+
#
|
1469
2230
|
def request_put(path, data, initheader = nil, &block) #:nodoc:
|
1470
2231
|
request Put.new(path, initheader), data, &block
|
1471
2232
|
end
|
@@ -1475,16 +2236,25 @@ module Net #:nodoc:
|
|
1475
2236
|
alias post2 request_post #:nodoc: obsolete
|
1476
2237
|
alias put2 request_put #:nodoc: obsolete
|
1477
2238
|
|
1478
|
-
|
1479
|
-
#
|
1480
|
-
# Also sends a DATA string if +data+ is given.
|
2239
|
+
# Sends an \HTTP request to the server;
|
2240
|
+
# returns an instance of a subclass of Net::HTTPResponse.
|
1481
2241
|
#
|
1482
|
-
#
|
2242
|
+
# The request is based on the Net::HTTPRequest object
|
2243
|
+
# created from string +path+, string +data+, and initial headers hash +header+.
|
2244
|
+
# That object is an instance of the
|
2245
|
+
# {subclass of Net::HTTPRequest}[rdoc-ref:Net::HTTPRequest@Request+Subclasses],
|
2246
|
+
# that corresponds to the given uppercase string +name+,
|
2247
|
+
# which must be
|
2248
|
+
# an {HTTP request method}[https://en.wikipedia.org/wiki/HTTP#Request_methods]
|
2249
|
+
# or a {WebDAV request method}[https://en.wikipedia.org/wiki/WebDAV#Implementation].
|
1483
2250
|
#
|
1484
|
-
#
|
2251
|
+
# Examples:
|
1485
2252
|
#
|
1486
|
-
#
|
1487
|
-
#
|
2253
|
+
# http = Net::HTTP.new(hostname)
|
2254
|
+
# http.send_request('GET', '/todos/1')
|
2255
|
+
# # => #<Net::HTTPOK 200 OK readbody=true>
|
2256
|
+
# http.send_request('POST', '/todos', 'xyzzy')
|
2257
|
+
# # => #<Net::HTTPCreated 201 Created readbody=true>
|
1488
2258
|
#
|
1489
2259
|
def send_request(name, path, data = nil, header = nil)
|
1490
2260
|
has_response_body = name != 'HEAD'
|
@@ -1492,20 +2262,35 @@ module Net #:nodoc:
|
|
1492
2262
|
request r, data
|
1493
2263
|
end
|
1494
2264
|
|
1495
|
-
# Sends
|
2265
|
+
# Sends the given request +req+ to the server;
|
2266
|
+
# forms the response into a Net::HTTPResponse object.
|
1496
2267
|
#
|
1497
|
-
#
|
1498
|
-
#
|
1499
|
-
#
|
2268
|
+
# The given +req+ must be an instance of a
|
2269
|
+
# {subclass of Net::HTTPRequest}[rdoc-ref:Net::HTTPRequest@Request+Subclasses].
|
2270
|
+
# Argument +body+ should be given only if needed for the request.
|
1500
2271
|
#
|
1501
|
-
#
|
2272
|
+
# With no block given, returns the response object:
|
1502
2273
|
#
|
1503
|
-
#
|
1504
|
-
#
|
1505
|
-
#
|
1506
|
-
#
|
2274
|
+
# http = Net::HTTP.new(hostname)
|
2275
|
+
#
|
2276
|
+
# req = Net::HTTP::Get.new('/todos/1')
|
2277
|
+
# http.request(req)
|
2278
|
+
# # => #<Net::HTTPOK 200 OK readbody=true>
|
2279
|
+
#
|
2280
|
+
# req = Net::HTTP::Post.new('/todos')
|
2281
|
+
# http.request(req, 'xyzzy')
|
2282
|
+
# # => #<Net::HTTPCreated 201 Created readbody=true>
|
2283
|
+
#
|
2284
|
+
# With a block given, calls the block with the response and returns the response:
|
1507
2285
|
#
|
1508
|
-
#
|
2286
|
+
# req = Net::HTTP::Get.new('/todos/1')
|
2287
|
+
# http.request(req) do |res|
|
2288
|
+
# p res
|
2289
|
+
# end # => #<Net::HTTPOK 200 OK readbody=true>
|
2290
|
+
#
|
2291
|
+
# Output:
|
2292
|
+
#
|
2293
|
+
# #<Net::HTTPOK 200 OK readbody=false>
|
1509
2294
|
#
|
1510
2295
|
def request(req, body = nil, &block) # :yield: +response+
|
1511
2296
|
unless started?
|
@@ -1556,6 +2341,8 @@ module Net #:nodoc:
|
|
1556
2341
|
begin
|
1557
2342
|
res = HTTPResponse.read_new(@socket)
|
1558
2343
|
res.decode_content = req.decode_content
|
2344
|
+
res.body_encoding = @response_body_encoding
|
2345
|
+
res.ignore_eof = @ignore_eof
|
1559
2346
|
end while res.kind_of?(HTTPInformation)
|
1560
2347
|
|
1561
2348
|
res.uri = req.uri
|
@@ -1575,10 +2362,10 @@ module Net #:nodoc:
|
|
1575
2362
|
if count < max_retries && IDEMPOTENT_METHODS_.include?(req.method)
|
1576
2363
|
count += 1
|
1577
2364
|
@socket.close if @socket
|
1578
|
-
|
2365
|
+
debug "Conn close because of error #{exception}, and retry"
|
1579
2366
|
retry
|
1580
2367
|
end
|
1581
|
-
|
2368
|
+
debug "Conn close because of error #{exception}"
|
1582
2369
|
@socket.close if @socket
|
1583
2370
|
raise
|
1584
2371
|
end
|
@@ -1586,7 +2373,7 @@ module Net #:nodoc:
|
|
1586
2373
|
end_transport req, res
|
1587
2374
|
res
|
1588
2375
|
rescue => exception
|
1589
|
-
|
2376
|
+
debug "Conn close because of error #{exception}"
|
1590
2377
|
@socket.close if @socket
|
1591
2378
|
raise exception
|
1592
2379
|
end
|
@@ -1596,11 +2383,11 @@ module Net #:nodoc:
|
|
1596
2383
|
connect
|
1597
2384
|
elsif @last_communicated
|
1598
2385
|
if @last_communicated + @keep_alive_timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
1599
|
-
|
2386
|
+
debug 'Conn close because of keep_alive_timeout'
|
1600
2387
|
@socket.close
|
1601
2388
|
connect
|
1602
2389
|
elsif @socket.io.to_io.wait_readable(0) && @socket.eof?
|
1603
|
-
|
2390
|
+
debug "Conn close because of EOF"
|
1604
2391
|
@socket.close
|
1605
2392
|
connect
|
1606
2393
|
end
|
@@ -1618,15 +2405,15 @@ module Net #:nodoc:
|
|
1618
2405
|
@curr_http_version = res.http_version
|
1619
2406
|
@last_communicated = nil
|
1620
2407
|
if @socket.closed?
|
1621
|
-
|
2408
|
+
debug 'Conn socket closed'
|
1622
2409
|
elsif not res.body and @close_on_empty_response
|
1623
|
-
|
2410
|
+
debug 'Conn close'
|
1624
2411
|
@socket.close
|
1625
2412
|
elsif keep_alive?(req, res)
|
1626
|
-
|
2413
|
+
debug 'Conn keep-alive'
|
1627
2414
|
@last_communicated = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
1628
2415
|
else
|
1629
|
-
|
2416
|
+
debug 'Conn close'
|
1630
2417
|
@socket.close
|
1631
2418
|
end
|
1632
2419
|
end
|
@@ -1681,11 +2468,14 @@ module Net #:nodoc:
|
|
1681
2468
|
default_port == port ? addr : "#{addr}:#{port}"
|
1682
2469
|
end
|
1683
2470
|
|
1684
|
-
|
2471
|
+
# Adds a message to debugging output
|
2472
|
+
def debug(msg)
|
1685
2473
|
return unless @debug_output
|
1686
2474
|
@debug_output << msg
|
1687
2475
|
@debug_output << "\n"
|
1688
2476
|
end
|
2477
|
+
|
2478
|
+
alias_method :D, :debug
|
1689
2479
|
end
|
1690
2480
|
|
1691
2481
|
end
|