net-http 0.1.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/net/http.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
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
- # == 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
+ # == 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
- # Net::HTTP provides a rich library which can be used to build HTTP
37
- # user-agents. For more details about HTTP see
38
- # [RFC2616](http://www.ietf.org/rfc/rfc2616.txt).
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
- # Net::HTTP is designed to work closely with URI. URI::HTTP#host,
41
- # URI::HTTP#port and URI::HTTP#request_uri are designed to work with
42
- # Net::HTTP.
101
+ # == URIs
43
102
  #
44
- # If you are only performing a few GET requests you should try OpenURI.
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
- # == Simple Examples
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
- # All examples assume you have loaded Net::HTTP with:
114
+ # === Schemes
49
115
  #
50
- # require 'net/http'
116
+ # An internet \URI has
117
+ # a {scheme}[https://en.wikipedia.org/wiki/List_of_URI_schemes].
51
118
  #
52
- # This will also require 'uri' so you don't need to require it separately.
119
+ # The two schemes supported in \Net::HTTP are <tt>'https'</tt> and <tt>'http'</tt>:
53
120
  #
54
- # The Net::HTTP methods in the following section do not persist
55
- # connections. They are not recommended if you are performing many HTTP
56
- # requests.
121
+ # uri.scheme # => "https"
122
+ # URI('http://example.com').scheme # => "http"
57
123
  #
58
- # === GET
124
+ # === Hostnames
59
125
  #
60
- # Net::HTTP.get('example.com', '/index.html') # => String
126
+ # A hostname identifies a server (host) to which requests may be sent:
61
127
  #
62
- # === GET by URI
128
+ # hostname = uri.hostname # => "jsonplaceholder.typicode.com"
129
+ # Net::HTTP.start(hostname) do |http|
130
+ # # Some HTTP stuff.
131
+ # end
63
132
  #
64
- # uri = URI('http://example.com/index.html?count=10')
65
- # Net::HTTP.get(uri) # => String
133
+ # === Paths
66
134
  #
67
- # === GET with Dynamic Parameters
135
+ # A host-specific path identifies a resource on the host:
68
136
  #
69
- # uri = URI('http://example.com/index.html')
70
- # params = { :limit => 10, :page => 3 }
71
- # uri.query = URI.encode_www_form(params)
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
- # res = Net::HTTP.get_response(uri)
74
- # puts res.body if res.is_a?(Net::HTTPSuccess)
143
+ # === Queries
75
144
  #
76
- # === POST
145
+ # A host-specific query adds name/value pairs to the URI:
77
146
  #
78
- # uri = URI('http://www.example.com/search.cgi')
79
- # res = Net::HTTP.post_form(uri, 'q' => 'ruby', 'max' => '50')
80
- # puts res.body
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
- # === POST with Multiple Values
153
+ # === Fragments
83
154
  #
84
- # uri = URI('http://www.example.com/search.cgi')
85
- # res = Net::HTTP.post_form(uri, 'q' => ['ruby', 'perl'], 'max' => '50')
86
- # puts res.body
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
- # == How to use Net::HTTP
159
+ # == Request Headers
89
160
  #
90
- # The following example code can be used as the basis of an HTTP user-agent
91
- # which can perform a variety of request types using persistent
92
- # connections.
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
- # uri = URI('http://example.com/some_path?query=string')
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
- # Net::HTTP.start(uri.host, uri.port) do |http|
97
- # request = Net::HTTP::Get.new uri
169
+ # headers = {Accept: 'application/json', Connection: 'Keep-Alive'}
170
+ # Net::HTTP.get(uri, headers)
98
171
  #
99
- # response = http.request request # Net::HTTPResponse object
100
- # end
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
- # Net::HTTP::start immediately creates a connection to an HTTP server which
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
- # If you wish to re-use a connection across multiple HTTP requests without
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
- # The request types Net::HTTP supports are listed below in the section "HTTP
112
- # Request Classes".
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
- # For all the Net::HTTP request objects and shortcut request methods you may
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
- # === Response Data
186
+ # === Session Using \Net::HTTP.start
119
187
  #
120
- # uri = URI('http://example.com/index.html')
121
- # res = Net::HTTP.get_response(uri)
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
- # # Headers
124
- # res['Set-Cookie'] # => String
125
- # res.get_fields('set-cookie') # => Array
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
- # # Status
130
- # puts res.code # => '200'
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
- # # Body
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
- # === Following Redirection
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
- # Each Net::HTTPResponse object belongs to a class for its response code.
209
+ # - {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
140
210
  #
141
- # For example, all 2XX responses are instances of a Net::HTTPSuccess
142
- # subclass, a 3XX response is an instance of a Net::HTTPRedirection
143
- # subclass and a 200 response is an instance of the Net::HTTPOK class. For
144
- # details of response classes, see the section "HTTP Response Classes"
145
- # below.
211
+ # - #copy: COPY.
212
+ # - #lock: LOCK.
213
+ # - #mkcol: MKCOL.
214
+ # - #move: MOVE.
215
+ # - #propfind: PROPFIND.
216
+ # - #proppatch: PROPPATCH.
217
+ # - #unlock: UNLOCK.
146
218
  #
147
- # Using a case statement you can handle various types of responses properly:
219
+ # === Session Using \Net::HTTP.start and \Net::HTTP.finish
148
220
  #
149
- # def fetch(uri_str, limit = 10)
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
- # response = Net::HTTP.get_response(URI(uri_str))
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
- # case response
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
- # print fetch('http://www.ruby-lang.org')
232
+ # Certain convenience methods automatically handle a session by:
168
233
  #
169
- # === POST
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
- # A POST can be made using the Net::HTTP::Post request class. This example
172
- # creates a URL encoded POST body:
240
+ # Such methods that send GET requests:
173
241
  #
174
- # uri = URI('http://www.example.com/todo.cgi')
175
- # req = Net::HTTP::Post.new(uri)
176
- # req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')
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
- # res = Net::HTTP.start(uri.hostname, uri.port) do |http|
179
- # http.request(req)
180
- # end
246
+ # Such methods that send POST requests:
181
247
  #
182
- # case res
183
- # when Net::HTTPSuccess, Net::HTTPRedirection
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
- # To send multipart/form-data use Net::HTTPHeader#set_form:
251
+ # == \HTTP Requests and Responses
190
252
  #
191
- # req = Net::HTTP::Post.new(uri)
192
- # req.set_form([['upload', File.open('foo.bar')]], 'multipart/form-data')
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
- # Other requests that can contain a body such as PUT can be created in the
195
- # same way using the corresponding request class (Net::HTTP::Put).
257
+ # You can, however, directly create a request object, send the request,
258
+ # and retrieve the response object; see:
196
259
  #
197
- # === Setting Headers
260
+ # - Net::HTTPRequest.
261
+ # - Net::HTTPResponse.
198
262
  #
199
- # The following example performs a conditional GET using the
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
- # uri = URI('http://example.com/cached_response')
205
- # file = File.stat 'cached_response'
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
- # req = Net::HTTP::Get.new(uri)
208
- # req['If-Modified-Since'] = file.mtime.rfc2822
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
- # res = Net::HTTP.start(uri.hostname, uri.port) {|http|
211
- # http.request(req)
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
- # open 'cached_response', 'w' do |io|
215
- # io.write res.body
216
- # end if res.is_a?(Net::HTTPSuccess)
289
+ # fetch(uri)
217
290
  #
218
- # === Basic Authentication
291
+ # == Basic Authentication
219
292
  #
220
293
  # Basic authentication is performed according to
221
- # [RFC2617](http://www.ietf.org/rfc/rfc2617.txt).
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 'user', 'pass'
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
- # === Streaming Response Bodies
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
- # uri = URI('http://example.com/large_file')
240
- #
241
- # Net::HTTP.start(uri.host, uri.port) do |http|
242
- # request = Net::HTTP::Get.new uri
243
- #
244
- # http.request request do |response|
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
- # === HTTPS
254
- #
255
- # HTTPS is enabled for an HTTP connection by Net::HTTP#use_ssl=.
319
+ # == HTTPS
256
320
  #
257
- # uri = URI('https://secure.example.com/some_path?query=string')
321
+ # HTTPS is enabled for an \HTTP connection by Net::HTTP#use_ssl=:
258
322
  #
259
- # Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
260
- # request = Net::HTTP::Get.new uri
261
- # response = http.request request # Net::HTTPResponse object
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 an URI
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
- # uri = URI('https://example.com/')
269
- # Net::HTTP.get(uri) # => String
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
- # In previous versions of Ruby you would need to require 'net/https' to use
272
- # HTTPS. This is no longer true.
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 will automatically create a proxy from the +http_proxy+
277
- # environment variable if it is present. To disable use of +http_proxy+,
278
- # pass +nil+ for the proxy address.
279
- #
280
- # You may also create a custom proxy:
281
- #
282
- # proxy_addr = 'your.proxy.host'
283
- # proxy_port = 8080
284
- #
285
- # Net::HTTP.new('example.com', nil, proxy_addr, proxy_port).start { |http|
286
- # # always proxy via your.proxy.addr:8080
287
- # }
288
- #
289
- # See Net::HTTP.new for further details and examples such as proxies that
290
- # require a username and password.
291
- #
292
- # === Compression
293
- #
294
- # Net::HTTP automatically adds Accept-Encoding for compression of response
295
- # bodies and automatically decompresses gzip and deflate responses unless a
296
- # Range header was sent.
297
- #
298
- # Compression can be disabled through the Accept-Encoding: identity header.
299
- #
300
- # == HTTP Request Classes
301
- #
302
- # Here is the HTTP request class hierarchy.
303
- #
304
- # * Net::HTTPRequest
305
- # * Net::HTTP::Get
306
- # * Net::HTTP::Head
307
- # * Net::HTTP::Post
308
- # * Net::HTTP::Patch
309
- # * Net::HTTP::Put
310
- # * Net::HTTP::Proppatch
311
- # * Net::HTTP::Lock
312
- # * Net::HTTP::Unlock
313
- # * Net::HTTP::Options
314
- # * Net::HTTP::Propfind
315
- # * Net::HTTP::Delete
316
- # * Net::HTTP::Move
317
- # * Net::HTTP::Copy
318
- # * Net::HTTP::Mkcol
319
- # * Net::HTTP::Trace
320
- #
321
- # == HTTP Response Classes
322
- #
323
- # Here is HTTP response class hierarchy. All classes are defined in Net
324
- # module and are subclasses of Net::HTTPResponse.
325
- #
326
- # HTTPUnknownResponse:: For unhandled HTTP extensions
327
- # HTTPInformation:: 1xx
328
- # HTTPContinue:: 100
329
- # HTTPSwitchProtocol:: 101
330
- # HTTPSuccess:: 2xx
331
- # HTTPOK:: 200
332
- # HTTPCreated:: 201
333
- # HTTPAccepted:: 202
334
- # HTTPNonAuthoritativeInformation:: 203
335
- # HTTPNoContent:: 204
336
- # HTTPResetContent:: 205
337
- # HTTPPartialContent:: 206
338
- # HTTPMultiStatus:: 207
339
- # HTTPIMUsed:: 226
340
- # HTTPRedirection:: 3xx
341
- # HTTPMultipleChoices:: 300
342
- # HTTPMovedPermanently:: 301
343
- # HTTPFound:: 302
344
- # HTTPSeeOther:: 303
345
- # HTTPNotModified:: 304
346
- # HTTPUseProxy:: 305
347
- # HTTPTemporaryRedirect:: 307
348
- # HTTPClientError:: 4xx
349
- # HTTPBadRequest:: 400
350
- # HTTPUnauthorized:: 401
351
- # HTTPPaymentRequired:: 402
352
- # HTTPForbidden:: 403
353
- # HTTPNotFound:: 404
354
- # HTTPMethodNotAllowed:: 405
355
- # HTTPNotAcceptable:: 406
356
- # HTTPProxyAuthenticationRequired:: 407
357
- # HTTPRequestTimeOut:: 408
358
- # HTTPConflict:: 409
359
- # HTTPGone:: 410
360
- # HTTPLengthRequired:: 411
361
- # HTTPPreconditionFailed:: 412
362
- # HTTPRequestEntityTooLarge:: 413
363
- # HTTPRequestURITooLong:: 414
364
- # HTTPUnsupportedMediaType:: 415
365
- # HTTPRequestedRangeNotSatisfiable:: 416
366
- # HTTPExpectationFailed:: 417
367
- # HTTPUnprocessableEntity:: 422
368
- # HTTPLocked:: 423
369
- # HTTPFailedDependency:: 424
370
- # HTTPUpgradeRequired:: 426
371
- # HTTPPreconditionRequired:: 428
372
- # HTTPTooManyRequests:: 429
373
- # HTTPRequestHeaderFieldsTooLarge:: 431
374
- # HTTPUnavailableForLegalReasons:: 451
375
- # HTTPServerError:: 5xx
376
- # HTTPInternalServerError:: 500
377
- # HTTPNotImplemented:: 501
378
- # HTTPBadGateway:: 502
379
- # HTTPServiceUnavailable:: 503
380
- # HTTPGatewayTimeOut:: 504
381
- # HTTPVersionNotSupported:: 505
382
- # HTTPInsufficientStorage:: 507
383
- # HTTPNetworkAuthenticationRequired:: 511
384
- #
385
- # There is also the Net::HTTPBadResponse exception which is raised when
386
- # there is a protocol error.
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.1.1"
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
- # Turns on net/http 1.2 (Ruby 1.8) features.
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 if net/http is in version 1.2 mode.
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
- # short cut methods
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
- # Sends a GET request to the target and returns the HTTP response
453
- # as a string. The target can either be specified as
454
- # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
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
- # or:
774
+ # Sends a GET request and returns the \HTTP response body as a string.
459
775
  #
460
- # print Net::HTTP.get('www.example.com', '/index.html')
776
+ # With string arguments +hostname+ and +path+:
461
777
  #
462
- # you can also specify request headers:
778
+ # hostname = 'jsonplaceholder.typicode.com'
779
+ # path = '/todos/1'
780
+ # puts Net::HTTP.get(hostname, path)
463
781
  #
464
- # Net::HTTP.get(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
782
+ # Output:
465
783
  #
466
- def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
467
- get_response(uri_or_host, path_or_headers, port).body
468
- end
469
-
470
- # Sends a GET request to the target and returns the HTTP response
471
- # as a Net::HTTPResponse object. The target can either be specified as
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
- # res = Net::HTTP.get_response(URI('http://www.example.com/index.html'))
475
- # print res.body
791
+ # With URI object +uri+ and optional hash argument +headers+:
476
792
  #
477
- # or:
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
- # res = Net::HTTP.get_response('www.example.com', '/index.html')
480
- # print res.body
797
+ # Related:
481
798
  #
482
- # you can also specify request headers:
799
+ # - Net::HTTP::Get: request class for \HTTP method +GET+.
800
+ # - Net::HTTP#get: convenience method for \HTTP method +GET+.
483
801
  #
484
- # Net::HTTP.get_response(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
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 the specified URI object.
829
+ # Posts data to a host; returns a Net::HTTPResponse object.
504
830
  #
505
- # Example:
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
- # require 'net/http'
508
- # require 'uri'
843
+ # {
844
+ # "title": "foo",
845
+ # "body": "bar",
846
+ # "userId": 1,
847
+ # "id": 101
848
+ # }
509
849
  #
510
- # Net::HTTP.post URI('http://www.example.com/api/search'),
511
- # { "q" => "ruby", "max" => "50" }.to_json,
512
- # "Content-Type" => "application/json"
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 HTML form data to the specified URI object.
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
- # { "cmd" => "search", "q" => "ruby", "max" => "50" }
864
+ # Argument +url+ must be a URI;
865
+ # argument +data+ must be a hash:
526
866
  #
527
- # This method also does Basic Authentication iff +url+.user exists.
528
- # But userinfo for authentication is deprecated (RFC3986).
529
- # So this feature will be removed.
530
- #
531
- # Example:
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
- # require 'net/http'
534
- # require 'uri'
873
+ # Output:
535
874
  #
536
- # Net::HTTP.post_form URI('http://www.example.com/search.cgi'),
537
- # { "q" => "ruby", "max" => "50" }
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
- # The default port to use for HTTP requests; defaults to 80.
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
- # The default port to use for HTTP requests; defaults to 80.
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
- # The default port to use for HTTPS requests; defaults to 443.
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, &block)
574
- # HTTP.start(address, port=nil, p_addr=:ENV, p_port=nil, p_user=nil, p_pass=nil, opt, &block)
575
- #
576
- # Creates a new Net::HTTP object, then additionally opens the TCP
577
- # connection and HTTP session.
578
- #
579
- # Arguments are the following:
580
- # _address_ :: hostname or IP address of the server
581
- # _port_ :: port of the server
582
- # _p_addr_ :: address of proxy
583
- # _p_port_ :: port of proxy
584
- # _p_user_ :: user of proxy
585
- # _p_pass_ :: pass of proxy
586
- # _opt_ :: optional hash
587
- #
588
- # _opt_ sets following values by its accessor.
589
- # The keys are ipaddr, ca_file, ca_path, cert, cert_store, ciphers, keep_alive_timeout,
590
- # close_on_empty_response, key, open_timeout, read_timeout, write_timeout, ssl_timeout,
591
- # ssl_version, use_ssl, verify_callback, verify_depth and verify_mode.
592
- # If you set :use_ssl as true, you can use https and default value of
593
- # verify_mode is set as OpenSSL::SSL::VERIFY_PEER.
594
- #
595
- # If the optional block is given, the newly
596
- # created Net::HTTP object is passed to it and closed when the
597
- # block finishes. In this case, the return value of this method
598
- # is the return value of the block. If no block is given, the
599
- # return value of this method is the newly created Net::HTTP object
600
- # itself, and the caller is responsible for closing it upon completion
601
- # using the finish() method.
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
- # Creates a new Net::HTTP object without opening a TCP connection or
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
- # The +address+ should be a DNS hostname or IP address, the +port+ is the
632
- # port the server operates on. If no +port+ is given the default port for
633
- # HTTP or HTTPS is used.
1039
+ # With only string argument +address+ given
1040
+ # (and <tt>ENV['http_proxy']</tt> undefined or +nil+),
1041
+ # the returned +http+:
634
1042
  #
635
- # If none of the +p_+ arguments are given, the proxy host and port are
636
- # taken from the +http_proxy+ environment variable (or its uppercase
637
- # equivalent) if present. If the proxy requires authentication you must
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
- # If you are connecting to a custom proxy, +p_addr+ specifies the DNS name
643
- # or IP address of the proxy host, +p_port+ the port to use to access the
644
- # proxy, +p_user+ and +p_pass+ the username and password if authorization
645
- # is required to use the proxy, and p_no_proxy hosts which do not
646
- # use the proxy.
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?(p_addr, p_addr, p_port, p_no_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 an output stream for debugging.
1142
+ # Sets the output stream for debugging:
719
1143
  #
720
1144
  # http = Net::HTTP.new(hostname)
721
- # http.set_debug_output $stderr
722
- # http.start { .... }
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
- # The DNS host name or IP address to connect to.
1193
+ # Returns the string host name or host IP given as argument +address+ in ::new.
730
1194
  attr_reader :address
731
1195
 
732
- # The port number to connect to.
1196
+ # Returns the integer port number given as argument +port+ in ::new.
733
1197
  attr_reader :port
734
1198
 
735
- # The local host used to establish the connection.
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
- # The local port used to establish the connection.
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
- # The IP address to connect to/used to connect to
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
- # Set the IP address to connect to
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
- # Number of seconds to wait for the connection to open. Any number
759
- # may be used, including Floats for fractional seconds. If the HTTP
760
- # object cannot open a connection in this many seconds, it raises a
761
- # Net::OpenTimeout exception. The default value is 60 seconds.
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
- # Number of seconds to wait for one block to be read (via one read(2)
765
- # call). Any number may be used, including Floats for fractional
766
- # seconds. If the HTTP object cannot read data in this many seconds,
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
- # Number of seconds to wait for one block to be written (via one write(2)
771
- # call). Any number may be used, including Floats for fractional
772
- # seconds. If the HTTP object cannot write data in this many seconds,
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
- # Maximum number of times to retry an idempotent request in case of
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
- # Should be a non-negative integer number. Zero means no retries.
782
- # The default value is 1.
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
- # Setter for the read_timeout attribute.
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
- # Setter for the write_timeout attribute.
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
- # Seconds to wait for 100 Continue response. If the HTTP object does not
806
- # receive a response in this many seconds it sends the request body. The
807
- # default value is +nil+.
1372
+ # Returns the continue timeout value;
1373
+ # see continue_timeout=.
808
1374
  attr_reader :continue_timeout
809
1375
 
810
- # Setter for the continue_timeout attribute.
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
- # Seconds to reuse the connection of the previous request.
817
- # If the idle time is less than this Keep-Alive Timeout,
818
- # Net::HTTP reuses the TCP/IP socket used by the previous communication.
819
- # The default value is 2 seconds.
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
- # Returns true if the HTTP session has been started.
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 SSL/TLS is being used with HTTP.
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
- # Turn on/off SSL.
837
- # This flag must be set before starting session.
838
- # If you change use_ssl value after session started,
839
- # a Net::HTTP object raises IOError.
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 of a CA certification file in PEM format.
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 a CA certification directory containing certifications in
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 an OpenSSL::X509::Certificate object as client certificate.
893
- # (This method is appeared in Michal Rokos's OpenSSL extension).
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 verify peer certificate.
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. See OpenSSL::SSL::SSLContext#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#extra_chain_cert=
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 an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
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. See OpenSSL::SSL::SSLContext#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. See OpenSSL::SSL::SSLContext#min_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. See OpenSSL::SSL::SSLContext#max_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 verify callback for the server certification verification.
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 at beginning of
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 check the server certificate is valid for the hostname.
935
- # See OpenSSL::SSL::SSLContext#verify_hostname=
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 X.509 certificates the server presented.
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
- # Opens a TCP connection and HTTP session.
1544
+ # Starts an \HTTP session.
947
1545
  #
948
- # When this method is called with a block, it passes the Net::HTTP
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
- # When called with a block, it returns the return value of the
953
- # block; otherwise, it returns self.
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
- D "opening connection to #{conn_addr}:#{conn_port}..."
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
- D "opened"
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
- buf << "Host: #{@address}:#{@port}\r\n"
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
- OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
1027
- OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
1028
- @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
1029
- D "starting SSL for #{conn_addr}:#{conn_port}..."
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
- # Server Name Indication (SNI) RFC 3546
1033
- s.hostname = @address if s.respond_to? :hostname=
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) && @ssl_context.verify_hostname
1675
+ if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
1040
1676
  s.post_connection_check(@address)
1041
1677
  end
1042
- D "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
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
- D "Conn close because of connect error #{exception}"
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 and closes the TCP connection.
1063
- # Raises IOError if the session has not been started.
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
- # returns true if self is a class which was created by HTTP::Proxy.
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
- # Address of proxy host. If Net::HTTP does not use a proxy, nil.
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
- # Port number of proxy host. If Net::HTTP does not use a proxy, nil.
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
- # User name for accessing proxy. If Net::HTTP does not use a proxy, nil.
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
- # User password for accessing proxy. If Net::HTTP does not use a proxy,
1132
- # nil.
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
- # True if requests for this connection will be proxied
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
- # True if the proxy for this connection is determined from the environment
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".freeze, nil, address, port, nil, nil, nil, nil, nil
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
- # The address of the proxy server, if one is configured.
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
- # The port of the proxy server, if one is configured.
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
- # [Bug #12921]
1174
- if /linux|freebsd|darwin/ =~ RUBY_PLATFORM
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 ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE && @proxy_from_env
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
- # The password of the proxy server, if one is configured.
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 ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE && @proxy_from_env
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
- # Retrieves data from +path+ on the connected-to host which may be an
1232
- # absolute path String or a URI to extract the path from.
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
- # +initheader+ must be a Hash like { 'Accept' => '*/*', ... },
1235
- # and it defaults to an empty hash.
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
- # This method returns a Net::HTTPResponse object.
1894
+ # With a block given, calls the block with the response body:
1248
1895
  #
1249
- # If called with a block, yields each fragment of the
1250
- # entity body in turn as a string as it is read from
1251
- # the socket. Note that in this case, the returned response
1252
- # object will *not* contain a (meaningful) body.
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
- # +dest+ argument is obsolete.
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
- # This method never raises an exception.
1905
+ # With no block given, simply returns the response object:
1258
1906
  #
1259
- # response = http.get('/index.html')
1907
+ # http.get('/') # => #<Net::HTTPOK 200 OK readbody=true>
1260
1908
  #
1261
- # # using block
1262
- # File.open('result.txt', 'w') {|f|
1263
- # http.get('/~foo/') do |str|
1264
- # f.write str
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
- # Gets only the header from +path+ on the connected-to host.
1278
- # +header+ is a Hash like { 'Accept' => '*/*', ... }.
1924
+ # Sends a HEAD request to the server;
1925
+ # returns an instance of a subclass of Net::HTTPResponse.
1279
1926
  #
1280
- # This method returns a Net::HTTPResponse object.
1927
+ # The request is based on the Net::HTTP::Head object
1928
+ # created from string +path+ and initial headers hash +initheader+:
1281
1929
  #
1282
- # This method never raises an exception.
1283
- #
1284
- # response = nil
1285
- # Net::HTTP.start('some.www.server', 80) {|http|
1286
- # response = http.head('/index.html')
1287
- # }
1288
- # p response['content-type']
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
- # Posts +data+ (must be a String) to +path+. +header+ must be a Hash
1295
- # like { 'Accept' => '*/*', ... }.
1942
+ # :call-seq:
1943
+ # post(path, data, initheader = nil) {|res| ... }
1296
1944
  #
1297
- # This method returns a Net::HTTPResponse object.
1945
+ # Sends a POST request to the server;
1946
+ # returns an instance of a subclass of Net::HTTPResponse.
1298
1947
  #
1299
- # If called with a block, yields each fragment of the
1300
- # entity body in turn as a string as it is read from
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
- # +dest+ argument is obsolete.
1305
- # It still works but you must not use it.
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
- # This method never raises exception.
1959
+ # Output:
1308
1960
  #
1309
- # response = http.post('/cgi-bin/search.rb', 'query=foo')
1961
+ # "{\n \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\",\n \"id\": 201\n}"
1310
1962
  #
1311
- # # using block
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
- # You should set Content-Type: header field for POST.
1319
- # If no Content-Type: field given, this method uses
1320
- # "application/x-www-form-urlencoded" by default.
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
- # Sends a PATCH request to the +path+ and gets a response,
1327
- # as an HTTPResponse object.
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
- def put(path, data, initheader = nil) #:nodoc:
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 +path+ and gets a response,
1337
- # as an HTTPResponse object.
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 +path+ and gets a response,
1343
- # as an HTTPResponse object.
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 a UNLOCK request to the +path+ and gets a response,
1349
- # as an HTTPResponse object.
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 a OPTIONS request to the +path+ and gets a response,
1355
- # as an HTTPResponse object.
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 +path+ and gets a response,
1361
- # as an HTTPResponse object.
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 +path+ and gets a response,
1367
- # as an HTTPResponse object.
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 +path+ and gets a response,
1373
- # as an HTTPResponse object.
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 +path+ and gets a response,
1379
- # as an HTTPResponse object.
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 +path+ and gets a response,
1385
- # as an HTTPResponse object.
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 +path+ and gets a response,
1391
- # as an HTTPResponse object.
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 +path+.
1397
- # Returns the response as a Net::HTTPResponse object.
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
- # When called with a block, passes an HTTPResponse object to the block.
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
- # Returns the response.
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
- # This method never raises Net::* exceptions.
2168
+ # http.request_get('/todos') do |res|
2169
+ # p res
2170
+ # end # => #<Net::HTTPOK 200 OK readbody=true>
1407
2171
  #
1408
- # response = http.request_get('/index.html')
1409
- # # The entity body is already read in this case.
1410
- # p response['content-type']
1411
- # puts response.body
2172
+ # Output:
1412
2173
  #
1413
- # # Using a block
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 +path+ and returns the response
1426
- # as a Net::HTTPResponse object.
2180
+ # Sends a HEAD request to the server;
2181
+ # returns an instance of a subclass of Net::HTTPResponse.
1427
2182
  #
1428
- # Returns the response.
2183
+ # The request is based on the Net::HTTP::Head object
2184
+ # created from string +path+ and initial headers hash +initheader+.
1429
2185
  #
1430
- # This method never raises Net::* exceptions.
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 +path+.
2193
+ # Sends a POST request to the server;
2194
+ # forms the response into a Net::HTTPResponse object.
1440
2195
  #
1441
- # Returns the response as a Net::HTTPResponse object.
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
- # When called with a block, the block is passed an HTTPResponse
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
- # Returns the response.
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
- # This method never raises Net::* exceptions.
2208
+ # http.post('/todos', 'xyzzy') do |res|
2209
+ # p res
2210
+ # end # => #<Net::HTTPCreated 201 Created readbody=true>
1450
2211
  #
1451
- # # example
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
- # # using block
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
- # Sends an HTTP request to the HTTP server.
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
- # Returns a Net::HTTPResponse object.
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
- # This method never raises Net::* exceptions.
2251
+ # Examples:
1485
2252
  #
1486
- # response = http.send_request('GET', '/index.html')
1487
- # puts response.body
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 an HTTPRequest object +req+ to the HTTP server.
2265
+ # Sends the given request +req+ to the server;
2266
+ # forms the response into a Net::HTTPResponse object.
1496
2267
  #
1497
- # If +req+ is a Net::HTTP::Post or Net::HTTP::Put request containing
1498
- # data, the data is also sent. Providing data for a Net::HTTP::Head or
1499
- # Net::HTTP::Get request results in an ArgumentError.
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
- # Returns an HTTPResponse object.
2272
+ # With no block given, returns the response object:
1502
2273
  #
1503
- # When called with a block, passes an HTTPResponse object to the block.
1504
- # The body of the response will not have been read yet;
1505
- # the block can process it using HTTPResponse#read_body,
1506
- # if desired.
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
- # This method never raises Net::* exceptions.
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
- D "Conn close because of error #{exception}, and retry"
2365
+ debug "Conn close because of error #{exception}, and retry"
1579
2366
  retry
1580
2367
  end
1581
- D "Conn close because of error #{exception}"
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
- D "Conn close because of error #{exception}"
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
- D 'Conn close because of keep_alive_timeout'
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
- D "Conn close because of EOF"
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
- D 'Conn socket closed'
2408
+ debug 'Conn socket closed'
1622
2409
  elsif not res.body and @close_on_empty_response
1623
- D 'Conn close'
2410
+ debug 'Conn close'
1624
2411
  @socket.close
1625
2412
  elsif keep_alive?(req, res)
1626
- D 'Conn keep-alive'
2413
+ debug 'Conn keep-alive'
1627
2414
  @last_communicated = Process.clock_gettime(Process::CLOCK_MONOTONIC)
1628
2415
  else
1629
- D 'Conn close'
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
- def D(msg)
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