net-http 0.2.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/net/http.rb CHANGED
@@ -32,110 +32,237 @@ module Net #:nodoc:
32
32
  class HTTPHeaderSyntaxError < StandardError; end
33
33
  # :startdoc:
34
34
 
35
- # == An HTTP client API for Ruby.
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
+ # Note: If you are performing only a few GET requests, consider using
43
+ # {OpenURI}[https://docs.ruby-lang.org/en/master/OpenURI.html];
44
+ # otherwise, read on.
45
+ #
46
+ # == Synopsis
47
+ #
48
+ # If you are already familiar with \HTTP, this synopsis may be helpful.
49
+ #
50
+ # {Session}[rdoc-ref:Net::HTTP@Sessions] with multiple requests for
51
+ # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
52
+ #
53
+ # Net::HTTP.start(hostname) do |http|
54
+ # # Session started automatically before block execution.
55
+ # http.get(path_or_uri, headers = {})
56
+ # http.head(path_or_uri, headers = {})
57
+ # http.post(path_or_uri, data, headers = {}) # Can also have a block.
58
+ # http.put(path_or_uri, data, headers = {})
59
+ # http.delete(path_or_uri, headers = {Depth: 'Infinity'})
60
+ # http.options(path_or_uri, headers = {})
61
+ # http.trace(path_or_uri, headers = {})
62
+ # http.patch(path_or_uri, data, headers = {}) # Can also have a block.
63
+ # # Session finished automatically at block exit.
64
+ # end
36
65
  #
37
- # Net::HTTP provides a rich library which can be used to build HTTP
38
- # user-agents. For more details about HTTP see
39
- # [RFC2616](http://www.ietf.org/rfc/rfc2616.txt).
66
+ # {Session}[rdoc-ref:Net::HTTP@Sessions] with multiple requests for
67
+ # {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
68
+ #
69
+ # Net::HTTP.start(hostname) do |http|
70
+ # # Session started automatically before block execution.
71
+ # http.copy(path_or_uri, headers = {})
72
+ # http.lock(path_or_uri, body, headers = {})
73
+ # http.mkcol(path_or_uri, body = nil, headers = {})
74
+ # http.move(path_or_uri, headers = {})
75
+ # http.propfind(path_or_uri, body = nil, headers = {'Depth' => '0'})
76
+ # http.proppatch(path_or_uri, body, headers = {})
77
+ # http.unlock(path_or_uri, body, headers = {})
78
+ # # Session finished automatically at block exit.
79
+ # end
40
80
  #
41
- # Net::HTTP is designed to work closely with URI. URI::HTTP#host,
42
- # URI::HTTP#port and URI::HTTP#request_uri are designed to work with
43
- # Net::HTTP.
81
+ # Each of the following methods automatically starts and finishes
82
+ # a {session}[rdoc-ref:Net::HTTP@Sessions] that sends a single request:
44
83
  #
45
- # If you are only performing a few GET requests you should try OpenURI.
84
+ # # Return string response body.
85
+ # Net::HTTP.get(hostname, path, port = 80)
86
+ # Net::HTTP.get(uri, headers = {}, port = 80)
46
87
  #
47
- # == Simple Examples
88
+ # # Write string response body to $stdout.
89
+ # Net::HTTP.get_print(hostname, path_or_uri, port = 80)
90
+ # Net::HTTP.get_print(uri, headers = {}, port = 80)
48
91
  #
49
- # All examples assume you have loaded Net::HTTP with:
92
+ # # Return response as Net::HTTPResponse object.
93
+ # Net::HTTP.get_response(hostname, path_or_uri, port = 80)
94
+ # Net::HTTP.get_response(uri, headers = {}, port = 80)
50
95
  #
51
- # require 'net/http'
96
+ # Net::HTTP.post(uri, data, headers = {})
97
+ # Net::HTTP.post_form(uri, params)
52
98
  #
53
- # This will also require 'uri' so you don't need to require it separately.
99
+ # == About the Examples
54
100
  #
55
- # The Net::HTTP methods in the following section do not persist
56
- # connections. They are not recommended if you are performing many HTTP
57
- # requests.
101
+ # :include: doc/net-http/examples.rdoc
58
102
  #
59
- # === GET
103
+ # == URIs
60
104
  #
61
- # Net::HTTP.get('example.com', '/index.html') # => String
105
+ # On the internet, a URI
106
+ # ({Universal Resource Identifier}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier])
107
+ # is a string that identifies a particular resource.
108
+ # It consists of some or all of: scheme, hostname, path, query, and fragment;
109
+ # see {URI syntax}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax].
62
110
  #
63
- # === GET by URI
111
+ # A Ruby {URI::Generic}[https://docs.ruby-lang.org/en/master/URI/Generic.html] object
112
+ # represents an internet URI.
113
+ # It provides, among others, methods
114
+ # +scheme+, +hostname+, +path+, +query+, and +fragment+.
64
115
  #
65
- # uri = URI('http://example.com/index.html?count=10')
66
- # Net::HTTP.get(uri) # => String
116
+ # === Schemes
67
117
  #
68
- # === GET with Dynamic Parameters
118
+ # An internet \URI has
119
+ # a {scheme}[https://en.wikipedia.org/wiki/List_of_URI_schemes].
69
120
  #
70
- # uri = URI('http://example.com/index.html')
71
- # params = { :limit => 10, :page => 3 }
72
- # uri.query = URI.encode_www_form(params)
121
+ # The two schemes supported in \Net::HTTP are <tt>'https'</tt> and <tt>'http'</tt>:
73
122
  #
74
- # res = Net::HTTP.get_response(uri)
75
- # puts res.body if res.is_a?(Net::HTTPSuccess)
123
+ # uri.scheme # => "https"
124
+ # URI('http://example.com').scheme # => "http"
76
125
  #
77
- # === POST
126
+ # === Hostnames
78
127
  #
79
- # uri = URI('http://www.example.com/search.cgi')
80
- # res = Net::HTTP.post_form(uri, 'q' => 'ruby', 'max' => '50')
81
- # puts res.body
128
+ # A hostname identifies a server (host) to which requests may be sent:
82
129
  #
83
- # === POST with Multiple Values
130
+ # hostname = uri.hostname # => "jsonplaceholder.typicode.com"
131
+ # Net::HTTP.start(hostname) do |http|
132
+ # # Some HTTP stuff.
133
+ # end
84
134
  #
85
- # uri = URI('http://www.example.com/search.cgi')
86
- # res = Net::HTTP.post_form(uri, 'q' => ['ruby', 'perl'], 'max' => '50')
87
- # puts res.body
135
+ # === Paths
88
136
  #
89
- # == How to use Net::HTTP
137
+ # A host-specific path identifies a resource on the host:
90
138
  #
91
- # The following example code can be used as the basis of an HTTP user-agent
92
- # which can perform a variety of request types using persistent
93
- # connections.
139
+ # _uri = uri.dup
140
+ # _uri.path = '/todos/1'
141
+ # hostname = _uri.hostname
142
+ # path = _uri.path
143
+ # Net::HTTP.get(hostname, path)
94
144
  #
95
- # uri = URI('http://example.com/some_path?query=string')
145
+ # === Queries
96
146
  #
97
- # Net::HTTP.start(uri.host, uri.port) do |http|
98
- # request = Net::HTTP::Get.new uri
147
+ # A host-specific query adds name/value pairs to the URI:
99
148
  #
100
- # response = http.request request # Net::HTTPResponse object
101
- # end
149
+ # _uri = uri.dup
150
+ # params = {userId: 1, completed: false}
151
+ # _uri.query = URI.encode_www_form(params)
152
+ # _uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com?userId=1&completed=false>
153
+ # Net::HTTP.get(_uri)
154
+ #
155
+ # === Fragments
156
+ #
157
+ # A {URI fragment}[https://en.wikipedia.org/wiki/URI_fragment] has no effect
158
+ # in \Net::HTTP;
159
+ # the same data is returned, regardless of whether a fragment is included.
160
+ #
161
+ # == Request Headers
162
+ #
163
+ # Request headers may be used to pass additional information to the host,
164
+ # similar to arguments passed in a method call;
165
+ # each header is a name/value pair.
166
+ #
167
+ # Each of the \Net::HTTP methods that sends a request to the host
168
+ # has optional argument +headers+,
169
+ # where the headers are expressed as a hash of field-name/value pairs:
170
+ #
171
+ # headers = {Accept: 'application/json', Connection: 'Keep-Alive'}
172
+ # Net::HTTP.get(uri, headers)
173
+ #
174
+ # See lists of both standard request fields and common request fields at
175
+ # {Request Fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields].
176
+ # A host may also accept other custom fields.
177
+ #
178
+ # == Sessions
179
+ #
180
+ # A _session_ is a connection between a server (host) and a client that:
181
+ #
182
+ # - Is begun by instance method Net::HTTP#start.
183
+ # - May contain any number of requests.
184
+ # - Is ended by instance method Net::HTTP#finish.
185
+ #
186
+ # See example sessions at the {Synopsis}[rdoc-ref:Net::HTTP@Synopsis].
187
+ #
188
+ # === Session Using \Net::HTTP.start
189
+ #
190
+ # If you have many requests to make to a single host (and port),
191
+ # consider using singleton method Net::HTTP.start with a block;
192
+ # the method handles the session automatically by:
102
193
  #
103
- # Net::HTTP::start immediately creates a connection to an HTTP server which
104
- # is kept open for the duration of the block. The connection will remain
105
- # open for multiple requests in the block if the server indicates it
106
- # supports persistent connections.
194
+ # - Calling #start before block execution.
195
+ # - Executing the block.
196
+ # - Calling #finish after block execution.
107
197
  #
108
- # If you wish to re-use a connection across multiple HTTP requests without
109
- # automatically closing it you can use ::new and then call #start and
110
- # #finish manually.
198
+ # In the block, you can use these instance methods,
199
+ # each of which that sends a single request:
111
200
  #
112
- # The request types Net::HTTP supports are listed below in the section "HTTP
113
- # Request Classes".
201
+ # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
114
202
  #
115
- # For all the Net::HTTP request objects and shortcut request methods you may
116
- # supply either a String for the request path or a URI from which Net::HTTP
117
- # will extract the request path.
203
+ # - #get, #request_get: GET.
204
+ # - #head, #request_head: HEAD.
205
+ # - #post, #request_post: POST.
206
+ # - #delete: DELETE.
207
+ # - #options: OPTIONS.
208
+ # - #trace: TRACE.
209
+ # - #patch: PATCH.
118
210
  #
119
- # === Response Data
211
+ # - {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
120
212
  #
121
- # uri = URI('http://example.com/index.html')
122
- # res = Net::HTTP.get_response(uri)
213
+ # - #copy: COPY.
214
+ # - #lock: LOCK.
215
+ # - #mkcol: MKCOL.
216
+ # - #move: MOVE.
217
+ # - #propfind: PROPFIND.
218
+ # - #proppatch: PROPPATCH.
219
+ # - #unlock: UNLOCK.
123
220
  #
124
- # # Headers
125
- # res['Set-Cookie'] # => String
126
- # res.get_fields('set-cookie') # => Array
127
- # res.to_hash['set-cookie'] # => Array
128
- # puts "Headers: #{res.to_hash.inspect}"
221
+ # === Session Using \Net::HTTP.start and \Net::HTTP.finish
129
222
  #
130
- # # Status
131
- # puts res.code # => '200'
132
- # puts res.message # => 'OK'
133
- # puts res.class.name # => 'HTTPOK'
223
+ # You can manage a session manually using methods #start and #finish:
134
224
  #
135
- # # Body
136
- # puts res.body if res.response_body_permitted?
225
+ # http = Net::HTTP.new(hostname)
226
+ # http.start
227
+ # http.get('/todos/1')
228
+ # http.get('/todos/2')
229
+ # http.delete('/posts/1')
230
+ # http.finish # Needed to free resources.
137
231
  #
138
- # === Following Redirection
232
+ # === Single-Request Session
233
+ #
234
+ # Certain convenience methods automatically handle a session by:
235
+ #
236
+ # - Creating an \HTTP object
237
+ # - Starting a session.
238
+ # - Sending a single request.
239
+ # - Finishing the session.
240
+ # - Destroying the object.
241
+ #
242
+ # Such methods that send GET requests:
243
+ #
244
+ # - ::get: Returns the string response body.
245
+ # - ::get_print: Writes the string response body to $stdout.
246
+ # - ::get_response: Returns a Net::HTTPResponse object.
247
+ #
248
+ # Such methods that send POST requests:
249
+ #
250
+ # - ::post: Posts data to the host.
251
+ # - ::post_form: Posts form data to the host.
252
+ #
253
+ # == \HTTP Requests and Responses
254
+ #
255
+ # Many of the methods above are convenience methods,
256
+ # each of which sends a request and returns a string
257
+ # without directly using \Net::HTTPRequest and \Net::HTTPResponse objects.
258
+ #
259
+ # You can, however, directly create a request object, send the request,
260
+ # and retrieve the response object; see:
261
+ #
262
+ # - Net::HTTPRequest.
263
+ # - Net::HTTPResponse.
264
+ #
265
+ # == Following Redirection
139
266
  #
140
267
  # Each Net::HTTPResponse object belongs to a class for its response code.
141
268
  #
@@ -167,56 +294,7 @@ module Net #:nodoc:
167
294
  #
168
295
  # print fetch('http://www.ruby-lang.org')
169
296
  #
170
- # === POST
171
- #
172
- # A POST can be made using the Net::HTTP::Post request class. This example
173
- # creates a URL encoded POST body:
174
- #
175
- # uri = URI('http://www.example.com/todo.cgi')
176
- # req = Net::HTTP::Post.new(uri)
177
- # req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')
178
- #
179
- # res = Net::HTTP.start(uri.hostname, uri.port) do |http|
180
- # http.request(req)
181
- # end
182
- #
183
- # case res
184
- # when Net::HTTPSuccess, Net::HTTPRedirection
185
- # # OK
186
- # else
187
- # res.value
188
- # end
189
- #
190
- # To send multipart/form-data use Net::HTTPHeader#set_form:
191
- #
192
- # req = Net::HTTP::Post.new(uri)
193
- # req.set_form([['upload', File.open('foo.bar')]], 'multipart/form-data')
194
- #
195
- # Other requests that can contain a body such as PUT can be created in the
196
- # same way using the corresponding request class (Net::HTTP::Put).
197
- #
198
- # === Setting Headers
199
- #
200
- # The following example performs a conditional GET using the
201
- # If-Modified-Since header. If the files has not been modified since the
202
- # time in the header a Not Modified response will be returned. See RFC 2616
203
- # section 9.3 for further details.
204
- #
205
- # uri = URI('http://example.com/cached_response')
206
- # file = File.stat 'cached_response'
207
- #
208
- # req = Net::HTTP::Get.new(uri)
209
- # req['If-Modified-Since'] = file.mtime.rfc2822
210
- #
211
- # res = Net::HTTP.start(uri.hostname, uri.port) {|http|
212
- # http.request(req)
213
- # }
214
- #
215
- # open 'cached_response', 'w' do |io|
216
- # io.write res.body
217
- # end if res.is_a?(Net::HTTPSuccess)
218
- #
219
- # === Basic Authentication
297
+ # == Basic Authentication
220
298
  #
221
299
  # Basic authentication is performed according to
222
300
  # [RFC2617](http://www.ietf.org/rfc/rfc2617.txt).
@@ -231,7 +309,7 @@ module Net #:nodoc:
231
309
  # }
232
310
  # puts res.body
233
311
  #
234
- # === Streaming Response Bodies
312
+ # == Streaming Response Bodies
235
313
  #
236
314
  # By default Net::HTTP reads an entire response into memory. If you are
237
315
  # handling large files or wish to implement a progress bar you can instead
@@ -251,7 +329,7 @@ module Net #:nodoc:
251
329
  # end
252
330
  # end
253
331
  #
254
- # === HTTPS
332
+ # == HTTPS
255
333
  #
256
334
  # HTTPS is enabled for an HTTP connection by Net::HTTP#use_ssl=.
257
335
  #
@@ -272,7 +350,7 @@ module Net #:nodoc:
272
350
  # In previous versions of Ruby you would need to require 'net/https' to use
273
351
  # HTTPS. This is no longer true.
274
352
  #
275
- # === Proxies
353
+ # == Proxies
276
354
  #
277
355
  # Net::HTTP will automatically create a proxy from the +http_proxy+
278
356
  # environment variable if it is present. To disable use of +http_proxy+,
@@ -290,7 +368,7 @@ module Net #:nodoc:
290
368
  # See Net::HTTP.new for further details and examples such as proxies that
291
369
  # require a username and password.
292
370
  #
293
- # === Compression
371
+ # == Compression
294
372
  #
295
373
  # Net::HTTP automatically adds Accept-Encoding for compression of response
296
374
  # bodies and automatically decompresses gzip and deflate responses unless a
@@ -298,106 +376,10 @@ module Net #:nodoc:
298
376
  #
299
377
  # Compression can be disabled through the Accept-Encoding: identity header.
300
378
  #
301
- # == HTTP Request Classes
302
- #
303
- # Here is the HTTP request class hierarchy.
304
- #
305
- # * Net::HTTPRequest
306
- # * Net::HTTP::Get
307
- # * Net::HTTP::Head
308
- # * Net::HTTP::Post
309
- # * Net::HTTP::Patch
310
- # * Net::HTTP::Put
311
- # * Net::HTTP::Proppatch
312
- # * Net::HTTP::Lock
313
- # * Net::HTTP::Unlock
314
- # * Net::HTTP::Options
315
- # * Net::HTTP::Propfind
316
- # * Net::HTTP::Delete
317
- # * Net::HTTP::Move
318
- # * Net::HTTP::Copy
319
- # * Net::HTTP::Mkcol
320
- # * Net::HTTP::Trace
321
- #
322
- # == HTTP Response Classes
323
- #
324
- # Here is HTTP response class hierarchy. All classes are defined in Net
325
- # module and are subclasses of Net::HTTPResponse.
326
- #
327
- # HTTPUnknownResponse:: For unhandled HTTP extensions
328
- # HTTPInformation:: 1xx
329
- # HTTPContinue:: 100
330
- # HTTPSwitchProtocol:: 101
331
- # HTTPProcessing:: 102
332
- # HTTPEarlyHints:: 103
333
- # HTTPSuccess:: 2xx
334
- # HTTPOK:: 200
335
- # HTTPCreated:: 201
336
- # HTTPAccepted:: 202
337
- # HTTPNonAuthoritativeInformation:: 203
338
- # HTTPNoContent:: 204
339
- # HTTPResetContent:: 205
340
- # HTTPPartialContent:: 206
341
- # HTTPMultiStatus:: 207
342
- # HTTPAlreadyReported:: 208
343
- # HTTPIMUsed:: 226
344
- # HTTPRedirection:: 3xx
345
- # HTTPMultipleChoices:: 300
346
- # HTTPMovedPermanently:: 301
347
- # HTTPFound:: 302
348
- # HTTPSeeOther:: 303
349
- # HTTPNotModified:: 304
350
- # HTTPUseProxy:: 305
351
- # HTTPTemporaryRedirect:: 307
352
- # HTTPPermanentRedirect:: 308
353
- # HTTPClientError:: 4xx
354
- # HTTPBadRequest:: 400
355
- # HTTPUnauthorized:: 401
356
- # HTTPPaymentRequired:: 402
357
- # HTTPForbidden:: 403
358
- # HTTPNotFound:: 404
359
- # HTTPMethodNotAllowed:: 405
360
- # HTTPNotAcceptable:: 406
361
- # HTTPProxyAuthenticationRequired:: 407
362
- # HTTPRequestTimeOut:: 408
363
- # HTTPConflict:: 409
364
- # HTTPGone:: 410
365
- # HTTPLengthRequired:: 411
366
- # HTTPPreconditionFailed:: 412
367
- # HTTPRequestEntityTooLarge:: 413
368
- # HTTPRequestURITooLong:: 414
369
- # HTTPUnsupportedMediaType:: 415
370
- # HTTPRequestedRangeNotSatisfiable:: 416
371
- # HTTPExpectationFailed:: 417
372
- # HTTPMisdirectedRequest:: 421
373
- # HTTPUnprocessableEntity:: 422
374
- # HTTPLocked:: 423
375
- # HTTPFailedDependency:: 424
376
- # HTTPUpgradeRequired:: 426
377
- # HTTPPreconditionRequired:: 428
378
- # HTTPTooManyRequests:: 429
379
- # HTTPRequestHeaderFieldsTooLarge:: 431
380
- # HTTPUnavailableForLegalReasons:: 451
381
- # HTTPServerError:: 5xx
382
- # HTTPInternalServerError:: 500
383
- # HTTPNotImplemented:: 501
384
- # HTTPBadGateway:: 502
385
- # HTTPServiceUnavailable:: 503
386
- # HTTPGatewayTimeOut:: 504
387
- # HTTPVersionNotSupported:: 505
388
- # HTTPVariantAlsoNegotiates:: 506
389
- # HTTPInsufficientStorage:: 507
390
- # HTTPLoopDetected:: 508
391
- # HTTPNotExtended:: 510
392
- # HTTPNetworkAuthenticationRequired:: 511
393
- #
394
- # There is also the Net::HTTPBadResponse exception which is raised when
395
- # there is a protocol error.
396
- #
397
379
  class HTTP < Protocol
398
380
 
399
381
  # :stopdoc:
400
- VERSION = "0.2.2"
382
+ VERSION = "0.3.1"
401
383
  Revision = %q$Revision$.split[1]
402
384
  HTTPVersion = '1.1'
403
385
  begin
@@ -408,18 +390,17 @@ module Net #:nodoc:
408
390
  end
409
391
  # :startdoc:
410
392
 
411
- # Turns on net/http 1.2 (Ruby 1.8) features.
412
- # Defaults to ON in Ruby 1.8 or later.
393
+ # Returns +true+; retained for compatibility.
413
394
  def HTTP.version_1_2
414
395
  true
415
396
  end
416
397
 
417
- # Returns true if net/http is in version 1.2 mode.
418
- # Defaults to true.
398
+ # Returns +true+; retained for compatibility.
419
399
  def HTTP.version_1_2?
420
400
  true
421
401
  end
422
402
 
403
+ # Returns +false+; retained for compatibility.
423
404
  def HTTP.version_1_1? #:nodoc:
424
405
  false
425
406
  end
@@ -429,25 +410,12 @@ module Net #:nodoc:
429
410
  alias is_version_1_2? version_1_2? #:nodoc:
430
411
  end
431
412
 
413
+ # :call-seq:
414
+ # Net::HTTP.get_print(hostname, path, port = 80) -> nil
415
+ # Net::HTTP:get_print(uri, headers = {}, port = uri.port) -> nil
432
416
  #
433
- # short cut methods
434
- #
435
-
436
- #
437
- # Gets the body text from the target and outputs it to $stdout. The
438
- # target can either be specified as
439
- # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
440
- #
441
- # Net::HTTP.get_print URI('http://www.example.com/index.html')
442
- #
443
- # or:
444
- #
445
- # Net::HTTP.get_print 'www.example.com', '/index.html'
446
- #
447
- # you can also specify request headers:
448
- #
449
- # Net::HTTP.get_print URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' }
450
- #
417
+ # Like Net::HTTP.get, but writes the returned body to $stdout;
418
+ # returns +nil+.
451
419
  def HTTP.get_print(uri_or_host, path_or_headers = nil, port = nil)
452
420
  get_response(uri_or_host, path_or_headers, port) {|res|
453
421
  res.read_body do |chunk|
@@ -457,40 +425,43 @@ module Net #:nodoc:
457
425
  nil
458
426
  end
459
427
 
460
- # Sends a GET request to the target and returns the HTTP response
461
- # as a string. The target can either be specified as
462
- # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
428
+ # :call-seq:
429
+ # Net::HTTP.get(hostname, path, port = 80) -> body
430
+ # Net::HTTP:get(uri, headers = {}, port = uri.port) -> body
463
431
  #
464
- # print Net::HTTP.get(URI('http://www.example.com/index.html'))
432
+ # Sends a GET request and returns the \HTTP response body as a string.
465
433
  #
466
- # or:
434
+ # With string arguments +hostname+ and +path+:
467
435
  #
468
- # print Net::HTTP.get('www.example.com', '/index.html')
436
+ # hostname = 'jsonplaceholder.typicode.com'
437
+ # path = '/todos/1'
438
+ # puts Net::HTTP.get(hostname, path)
469
439
  #
470
- # you can also specify request headers:
440
+ # Output:
471
441
  #
472
- # Net::HTTP.get(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
442
+ # {
443
+ # "userId": 1,
444
+ # "id": 1,
445
+ # "title": "delectus aut autem",
446
+ # "completed": false
447
+ # }
448
+ #
449
+ # With URI object +uri+ and optional hash argument +headers+:
450
+ #
451
+ # uri = URI('https://jsonplaceholder.typicode.com/todos/1')
452
+ # headers = {'Content-type' => 'application/json; charset=UTF-8'}
453
+ # Net::HTTP.get(uri, headers)
473
454
  #
474
455
  def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
475
456
  get_response(uri_or_host, path_or_headers, port).body
476
457
  end
477
458
 
478
- # Sends a GET request to the target and returns the HTTP response
479
- # as a Net::HTTPResponse object. The target can either be specified as
480
- # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
481
- #
482
- # res = Net::HTTP.get_response(URI('http://www.example.com/index.html'))
483
- # print res.body
484
- #
485
- # or:
486
- #
487
- # res = Net::HTTP.get_response('www.example.com', '/index.html')
488
- # print res.body
489
- #
490
- # you can also specify request headers:
491
- #
492
- # Net::HTTP.get_response(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
459
+ # :call-seq:
460
+ # Net::HTTP.get_response(hostname, path, port = 80) -> http_response
461
+ # Net::HTTP:get_response(uri, headers = {}, port = uri.port) -> http_response
493
462
  #
463
+ # Like Net::HTTP.get, but returns an Net::HTTPResponse object
464
+ # instead of the body string.
494
465
  def HTTP.get_response(uri_or_host, path_or_headers = nil, port = nil, &block)
495
466
  if path_or_headers && !path_or_headers.is_a?(Hash)
496
467
  host = uri_or_host
@@ -577,35 +548,80 @@ module Net #:nodoc:
577
548
  end
578
549
 
579
550
  # :call-seq:
580
- # HTTP.start(address, port, p_addr, p_port, p_user, p_pass, &block)
581
- # HTTP.start(address, port=nil, p_addr=:ENV, p_port=nil, p_user=nil, p_pass=nil, opt, &block)
582
- #
583
- # Creates a new Net::HTTP object, then additionally opens the TCP
584
- # connection and HTTP session.
585
- #
586
- # Arguments are the following:
587
- # _address_ :: hostname or IP address of the server
588
- # _port_ :: port of the server
589
- # _p_addr_ :: address of proxy
590
- # _p_port_ :: port of proxy
591
- # _p_user_ :: user of proxy
592
- # _p_pass_ :: pass of proxy
593
- # _opt_ :: optional hash
594
- #
595
- # _opt_ sets following values by its accessor.
596
- # The keys are ipaddr, ca_file, ca_path, cert, cert_store, ciphers, keep_alive_timeout,
597
- # close_on_empty_response, key, open_timeout, read_timeout, write_timeout, ssl_timeout,
598
- # ssl_version, use_ssl, verify_callback, verify_depth and verify_mode.
599
- # If you set :use_ssl as true, you can use https and default value of
600
- # verify_mode is set as OpenSSL::SSL::VERIFY_PEER.
601
- #
602
- # If the optional block is given, the newly
603
- # created Net::HTTP object is passed to it and closed when the
604
- # block finishes. In this case, the return value of this method
605
- # is the return value of the block. If no block is given, the
606
- # return value of this method is the newly created Net::HTTP object
607
- # itself, and the caller is responsible for closing it upon completion
608
- # using the finish() method.
551
+ # HTTP.start(address, port, p_addr, p_port, p_user, p_pass) {|http| ... }
552
+ # HTTP.start(address, port=nil, p_addr=:ENV, p_port=nil, p_user=nil, p_pass=nil, opt) {|http| ... }
553
+ # Creates a new \Net::HTTP object,
554
+ # opens a TCP connection and \HTTP session.
555
+ #
556
+ # Argument +address+ is the hostname or IP address of the server.
557
+ #
558
+ # With a block given:
559
+ #
560
+ # - Passes the object to the given block,
561
+ # which may make any number of requests to the host.
562
+ # - Closes the \HTTP session on block exit.
563
+ # - Returns the block's value.
564
+ #
565
+ # Example:
566
+ #
567
+ # hostname = 'jsonplaceholder.typicode.com'
568
+ # Net::HTTP.start(hostname) do |http|
569
+ # puts http.get('/todos/1').body
570
+ # puts http.get('/todos/2').body
571
+ # end
572
+ #
573
+ # Output:
574
+ #
575
+ # {
576
+ # "userId": 1,
577
+ # "id": 1,
578
+ # "title": "delectus aut autem",
579
+ # "completed": false
580
+ # }
581
+ # {
582
+ # "userId": 1,
583
+ # "id": 2,
584
+ # "title": "quis ut nam facilis et officia qui",
585
+ # "completed": false
586
+ # }
587
+ #
588
+ # With no block given, returns the \Net::HTTP object;
589
+ # the caller should call #finish to close the session.
590
+ #
591
+ # Other arguments:
592
+ #
593
+ # - +port+: Server port number.
594
+ # - +p_addr+: Proxy address.
595
+ # - +p_port+: Proxy port.
596
+ # - +p_user+: Proxy user name.
597
+ # - +p_pass+: Proxy password.
598
+ # - +opts+: Optional options hash.
599
+ #
600
+ # The options hash +opts+ sets certain values,
601
+ # where each key is a method or accessor to be called,
602
+ # and its value is the value to be set.
603
+ #
604
+ # The keys may include:
605
+ #
606
+ # - #ca_file
607
+ # - #ca_path
608
+ # - #cert
609
+ # - #cert_store
610
+ # - #ciphers
611
+ # - #close_on_empty_response
612
+ # - +ipaddr+ (calls #ipaddr=)
613
+ # - #keep_alive_timeout
614
+ # - #key
615
+ # - #open_timeout
616
+ # - #read_timeout
617
+ # - #ssl_timeout
618
+ # - #ssl_version
619
+ # - +use_ssl+ (calls #use_ssl=)
620
+ # - #verify_callback
621
+ # - #verify_depth
622
+ # - #verify_mode
623
+ # - #write_timeout
624
+ #
609
625
  def HTTP.start(address, *arg, &block) # :yield: +http+
610
626
  arg.pop if opt = Hash.try_convert(arg[-1])
611
627
  port, p_addr, p_port, p_user, p_pass = *arg
@@ -1013,13 +1029,14 @@ module Net #:nodoc:
1013
1029
  end
1014
1030
 
1015
1031
  debug "opening connection to #{conn_addr}:#{conn_port}..."
1016
- begin
1017
- s = Socket.tcp conn_addr, conn_port, @local_host, @local_port, connect_timeout: @open_timeout
1018
- rescue => e
1019
- e = Net::OpenTimeout.new(e) if e.is_a?(Errno::ETIMEDOUT) #for compatibility with previous versions
1020
- raise e, "Failed to open TCP connection to " +
1021
- "#{conn_addr}:#{conn_port} (#{e.message})"
1022
- end
1032
+ s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
1033
+ begin
1034
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
1035
+ rescue => e
1036
+ raise e, "Failed to open TCP connection to " +
1037
+ "#{conn_addr}:#{conn_port} (#{e.message})"
1038
+ end
1039
+ }
1023
1040
  s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
1024
1041
  debug "opened"
1025
1042
  if use_ssl?
@@ -1221,16 +1238,9 @@ module Net #:nodoc:
1221
1238
  end
1222
1239
  end
1223
1240
 
1224
- # [Bug #12921]
1225
- if /linux|freebsd|darwin/ =~ RUBY_PLATFORM
1226
- ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE = true
1227
- else
1228
- ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE = false
1229
- end
1230
-
1231
1241
  # The username of the proxy server, if one is configured.
1232
1242
  def proxy_user
1233
- if ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE && @proxy_from_env
1243
+ if @proxy_from_env
1234
1244
  user = proxy_uri&.user
1235
1245
  unescape(user) if user
1236
1246
  else
@@ -1240,7 +1250,7 @@ module Net #:nodoc:
1240
1250
 
1241
1251
  # The password of the proxy server, if one is configured.
1242
1252
  def proxy_pass
1243
- if ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE && @proxy_from_env
1253
+ if @proxy_from_env
1244
1254
  pass = proxy_uri&.password
1245
1255
  unescape(pass) if pass
1246
1256
  else