模块 Net
常量
- HTTPGatewayTimeOut
网关超时
响应的响应类(状态码 504)。服务器充当网关或代理,但未及时收到上游服务器的响应。
参考
- HTTPMovedTemporarily
已找到
响应的响应类(状态码 302)。已找到
响应表示客户端应查看(浏览到)另一个 URL。参考
- HTTPMultipleChoice
多重选择
响应的响应类(状态码 300)。多重选择
响应表示服务器为客户端可能选择的资源提供了多个选项。参考
- HTTPRequestEntityTooLarge
有效负载过大
响应的响应类(状态码 413)。请求大于服务器愿意或能够处理的大小。
参考
- HTTPRequestTimeOut
请求超时
响应的响应类(状态码 408)。服务器等待请求超时。
参考
- HTTPRequestURITooLarge
URI 过长
响应的响应类(状态码 414)。提供的 URI 对于服务器来说过长,无法处理。
参考
- HTTPRequestURITooLong
URI 过长
响应的响应类(状态码 414)。提供的 URI 对于服务器来说过长,无法处理。
参考
- HTTPRequestedRangeNotSatisfiable
范围不可满足
响应的响应类(状态码 416)。请求实体具有服务器或资源不支持的媒体类型。
参考
- HTTPSession
类 Net::HTTP 提供了一个丰富的库,它实现了使用 HTTP 请求-响应协议的客户端-服务器模型中的客户端。有关 HTTP 的信息,请参阅
关于示例¶ ↑
策略¶ ↑
-
如果您只发出少量 GET 请求,请考虑使用 OpenURI。
-
如果您只发出少量各种类型的请求,请考虑使用此类中的各种单例便捷方法。以下每种方法都会自动启动并完成发送单个请求的会话
# Return string response body. Net::HTTP.get(hostname, path) Net::HTTP.get(uri) # Write string response body to $stdout. Net::HTTP.get_print(hostname, path) Net::HTTP.get_print(uri) # Return response as Net::HTTPResponse object. Net::HTTP.get_response(hostname, path) Net::HTTP.get_response(uri) data = '{"title": "foo", "body": "bar", "userId": 1}' Net::HTTP.post(uri, data) params = {title: 'foo', body: 'bar', userId: 1} Net::HTTP.post_form(uri, params) data = '{"title": "foo", "body": "bar", "userId": 1}' Net::HTTP.put(uri, data)
-
如果性能很重要,请考虑使用会话,这会降低请求开销。此会话有多个针对HTTP 方法和WebDAV 方法的请求
Net::HTTP.start(hostname) do |http| # Session started automatically before block execution. http.get(path) http.head(path) body = 'Some text' http.post(path, body) # Can also have a block. http.put(path, body) http.delete(path) http.options(path) http.trace(path) http.patch(path, body) # Can also have a block. http.copy(path) http.lock(path, body) http.mkcol(path, body) http.move(path) http.propfind(path, body) http.proppatch(path, body) http.unlock(path, body) # Session finished automatically at block exit. end
上面引用的方法是便捷方法,它们通过少量参数允许对请求进行最小的控制。要获得更大的控制,请考虑使用请求对象。
URI¶ ↑
在互联网上,URI(通用资源标识符)是一个字符串,用于标识特定的资源。它由以下部分或全部组成:scheme、hostname、path、query 和 fragment;请参阅URI 语法。
Ruby URI::Generic 对象表示互联网 URI。它提供 `scheme`、`hostname`、`path`、`query` 和 `fragment` 等方法。
Scheme¶ ↑
互联网 URI 具有一个scheme。
Net::HTTP 中支持的两个 scheme 是
'https'
和'http'
uri.scheme # => "https" URI('http://example.com').scheme # => "http"
主机名¶ ↑
主机名标识可以向其发送请求的服务器(主机)
hostname = uri.hostname # => "jsonplaceholder.typicode.com" Net::HTTP.start(hostname) do |http| # Some HTTP stuff. end
路径¶ ↑
主机特定的路径标识主机上的资源
_uri = uri.dup _uri.path = '/todos/1' hostname = _uri.hostname path = _uri.path Net::HTTP.get(hostname, path)
查询¶ ↑
主机特定的查询将名称/值对添加到 URI
_uri = uri.dup params = {userId: 1, completed: false} _uri.query = URI.encode_www_form(params) _uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com?userId=1&completed=false> Net::HTTP.get(_uri)
片段¶ ↑
URI 片段在 Net::HTTP 中没有效果;无论是否包含片段,都会返回相同的数据。
请求标头¶ ↑
请求标头可用于将其他信息传递给主机,类似于在方法调用中传递的参数;每个标头都是一个名称/值对。
向主机发送请求的每个 Net::HTTP 方法都有一个可选参数 `headers`,其中标头表示为字段名称/值对的哈希
headers = {Accept: 'application/json', Connection: 'Keep-Alive'} Net::HTTP.get(uri, headers)
请参阅请求字段中的标准请求字段和常用请求字段列表。主机也可能接受其他自定义字段。
HTTP 会话¶ ↑
_会话_是服务器(主机)和客户端之间的连接,它
-
由实例方法
Net::HTTP#start
启动。 -
可以包含任意数量的请求。
-
由实例方法
Net::HTTP#finish
结束。
请参阅策略中的示例会话。
使用 Net::HTTP.start 的会话¶ ↑
如果您要向单个主机(和端口)发出许多请求,请考虑使用带块的单例方法
Net::HTTP.start
;该方法通过以下方式自动处理会话-
在块执行之前调用 start。
-
执行块。
-
在块执行后调用 finish。
在该块中,您可以使用以下实例方法,每种方法都发送单个请求
-
-
get、request_get:GET。
-
head、request_head:HEAD。
-
post、request_post:POST。
-
delete:DELETE。
-
options:OPTIONS。
-
trace:TRACE。
-
patch:PATCH。
-
-
-
copy:COPY。
-
lock:LOCK。
-
mkcol:MKCOL。
-
move:MOVE。
-
propfind:PROPFIND。
-
proppatch:PROPPATCH。
-
unlock:UNLOCK。
-
使用 Net::HTTP.start 和 Net::HTTP.finish 的会话¶ ↑
您可以使用方法 start 和 finish 手动管理会话
http = Net::HTTP.new(hostname) http.start http.get('/todos/1') http.get('/todos/2') http.delete('/posts/1') http.finish # Needed to free resources.
单请求会话¶ ↑
某些便捷方法通过以下方式自动处理会话
-
创建 HTTP 对象
-
启动会话。
-
发送单个请求。
-
完成会话。
-
销毁对象。
发送 GET 请求的此类方法
-
::get:返回字符串响应正文。
-
::get_print:将字符串响应正文写入 $stdout。
-
::get_response:返回
Net::HTTPResponse
对象。
发送 POST 请求的此类方法
-
::post:将数据发布到主机。
-
::post_form:将表单数据发布到主机。
HTTP 请求和响应¶ ↑
上面的许多方法都是便捷方法,每种方法都发送请求并返回一个字符串,而无需直接使用 Net::HTTPRequest 和 Net::HTTPResponse 对象。
但是,您可以直接创建请求对象、发送请求并检索响应对象;请参阅
跟随重定向¶ ↑
每个返回的响应都是
Net::HTTPResponse
子类的实例。请参阅响应类层次结构。特别是,类
Net::HTTPRedirection
是所有重定向类的父类。这允许您构造 case 语句以正确处理重定向def fetch(uri, limit = 10) # You should choose a better exception. raise ArgumentError, 'Too many HTTP redirects' if limit == 0 res = Net::HTTP.get_response(URI(uri)) case res when Net::HTTPSuccess # Any success class. res when Net::HTTPRedirection # Any redirection class. location = res['Location'] warn "Redirected to #{location}" fetch(location, limit - 1) else # Any other class. res.value end end fetch(uri)
基本身份验证¶ ↑
基本身份验证是根据RFC2617执行的
req = Net::HTTP::Get.new(uri) req.basic_auth('user', 'pass') res = Net::HTTP.start(hostname) do |http| http.request(req) end
流式处理响应正文¶ ↑
默认情况下,Net::HTTP 将整个响应读取到内存中。如果您正在处理大型文件或希望实现进度条,则可以改为将正文直接流式传输到 IO。
Net::HTTP.start(hostname) do |http| req = Net::HTTP::Get.new(uri) http.request(req) do |res| open('t.tmp', 'w') do |f| res.read_body do |chunk| f.write chunk end end end end
HTTPS¶ ↑
通过
Net::HTTP#use_ssl=
为 HTTP 连接启用 HTTPSNet::HTTP.start(hostname, :use_ssl => true) do |http| req = Net::HTTP::Get.new(uri) res = http.request(req) end
或者,如果您只想发出 GET 请求,您可以传入一个具有 HTTPS URL 的 URI 对象。如果 URI 对象具有 'https' URI scheme,则 Net::HTTP 会自动启用 TLS 验证
uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com/> Net::HTTP.get(uri)
代理服务器¶ ↑
HTTP 对象可以有一个代理服务器。
您可以使用方法
Net::HTTP.new
或方法Net::HTTP.start
创建具有代理服务器的 HTTP 对象。代理可以通过参数 `p_addr` 或环境变量 `'http_proxy'` 定义。
使用参数 `p_addr` 作为字符串的代理¶ ↑
当参数 `p_addr` 是字符串主机名时,返回的 `http` 将给定的主机作为其代理
http = Net::HTTP.new(hostname, nil, 'proxy.example') http.proxy? # => true http.proxy_from_env? # => false http.proxy_address # => "proxy.example" # These use default values. http.proxy_port # => 80 http.proxy_user # => nil http.proxy_pass # => nil
也可以给出代理的端口、用户名和密码
http = Net::HTTP.new(hostname, nil, 'proxy.example', 8000, 'pname', 'ppass') # => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false> http.proxy? # => true http.proxy_from_env? # => false http.proxy_address # => "proxy.example" http.proxy_port # => 8000 http.proxy_user # => "pname" http.proxy_pass # => "ppass"
使用 `ENV['http_proxy']` 的代理¶ ↑
当环境变量 `'http_proxy'` 设置为 URI 字符串时,返回的 `http` 将以该 URI 的服务器作为其代理;请注意,URI 字符串必须具有诸如 `'http'` 或 `'https'` 之类的协议
ENV['http_proxy'] = 'http://example.com' http = Net::HTTP.new(hostname) http.proxy? # => true http.proxy_from_env? # => true http.proxy_address # => "example.com" # These use default values. http.proxy_port # => 80 http.proxy_user # => nil http.proxy_pass # => nil
URI 字符串可以包含代理用户名、密码和端口号
ENV['http_proxy'] = 'http://pname:[email protected]:8000' http = Net::HTTP.new(hostname) http.proxy? # => true http.proxy_from_env? # => true http.proxy_address # => "example.com" http.proxy_port # => 8000 http.proxy_user # => "pname" http.proxy_pass # => "ppass"
筛选代理¶ ↑
使用方法
Net::HTTP.new
(但不是Net::HTTP.start
),您可以使用参数 `p_no_proxy` 来筛选代理-
拒绝某个地址
http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example') http.proxy_address # => nil
-
拒绝某些域或子域
http = Net::HTTP.new('example.com', nil, 'my.proxy.example', 8000, 'pname', 'ppass', 'proxy.example') http.proxy_address # => nil
-
拒绝某些地址和端口组合
http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:1234') http.proxy_address # => "proxy.example" http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:8000') http.proxy_address # => nil
-
拒绝使用逗号分隔的上述类型的列表
http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000') http.proxy_address # => nil http = Net::HTTP.new('example.com', nil, 'my.proxy', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000') http.proxy_address # => nil
压缩和解压缩¶ ↑
Net::HTTP 在发送之前不会压缩请求的正文。
默认情况下,Net::HTTP 将标头 `'Accept-Encoding'` 添加到新的请求对象
Net::HTTP::Get.new(uri)['Accept-Encoding'] # => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
这会请求服务器对响应正文(如果有)进行 zip 编码;服务器并非必须这样做。
如果响应具有标头 `'Content-Range'`,则 Net::HTTP 不会自动解压缩响应正文。
否则,解压缩(或不解压缩)取决于标头Content-Encoding的值
-
'deflate'
、'gzip'
或'x-gzip'
:解压缩正文并删除标头。 -
'none'
或'identity'
:不解压缩正文,但删除标头。 -
任何其他值:保持正文和标头不变。
这里有什么¶ ↑
首先,看看别处有什么。类
Net::HTTP
-
继承自类 Object。
这是方法和属性的分类摘要。
Net::HTTP 对象¶ ↑
会话¶ ↑
-
::start:在新 Net::HTTP 对象中开始新的会话。
-
#started?:返回是否处于会话中。
-
#finish:结束活动会话。
-
#start:在现有 Net::HTTP 对象(`self`)中开始新的会话。
连接¶ ↑
-
:continue_timeout:返回继续超时。
-
#continue_timeout=:设置继续超时秒数。
-
:keep_alive_timeout:返回保持活动超时。
-
:keep_alive_timeout=:设置保持活动超时。
-
:max_retries:返回最大重试次数。
-
#max_retries=: 设置最大重试次数。
-
:open_timeout: 返回打开超时时间。
-
:open_timeout=: 设置打开超时时间。
-
:read_timeout: 返回读取超时时间。
-
:read_timeout=: 设置读取超时时间。
-
:ssl_timeout: 返回 SSL 超时时间。
-
:ssl_timeout=: 设置 SSL 超时时间。
-
:write_timeout: 返回写入超时时间。
-
write_timeout=: 设置写入超时时间。
请求¶ ↑
-
::get: 发送 GET 请求并返回字符串响应体。
-
::get_print: 发送 GET 请求并将字符串响应体写入 $stdout。
-
::get_response: 发送 GET 请求并返回响应对象。
-
::post_form: 发送带有表单数据的 POST 请求并返回响应对象。
-
::post: 发送带有数据的 POST 请求并返回响应对象。
-
::put: 发送带有数据的 PUT 请求并返回响应对象。
-
#copy: 发送 COPY 请求并返回响应对象。
-
#delete: 发送 DELETE 请求并返回响应对象。
-
#get: 发送 GET 请求并返回响应对象。
-
#head: 发送 HEAD 请求并返回响应对象。
-
#lock: 发送 LOCK 请求并返回响应对象。
-
#mkcol: 发送 MKCOL 请求并返回响应对象。
-
#move: 发送 MOVE 请求并返回响应对象。
-
#options: 发送 OPTIONS 请求并返回响应对象。
-
#patch: 发送 PATCH 请求并返回响应对象。
-
#post: 发送 POST 请求并返回响应对象。
-
#propfind: 发送 PROPFIND 请求并返回响应对象。
-
#proppatch: 发送 PROPPATCH 请求并返回响应对象。
-
#put: 发送 PUT 请求并返回响应对象。
-
#request: 发送请求并返回响应对象。
-
#request_get: 发送 GET 请求并创建一个响应对象;如果提供了代码块,则使用该对象调用代码块,否则返回该对象。
-
#request_head: 发送 HEAD 请求并创建一个响应对象;如果提供了代码块,则使用该对象调用代码块,否则返回该对象。
-
#request_post: 发送 POST 请求并创建一个响应对象;如果提供了代码块,则使用该对象调用代码块,否则返回该对象。
-
#send_request: 发送请求并返回响应对象。
-
#trace: 发送 TRACE 请求并返回响应对象。
-
#unlock: 发送 UNLOCK 请求并返回响应对象。
响应¶ ↑
-
:close_on_empty_response: 返回是否在空响应时关闭连接。
-
:close_on_empty_response=: 设置是否在空响应时关闭连接。
-
:ignore_eof: 返回在读取具有
Content-Length
标头的响应体时是否忽略文件结束符。 -
:ignore_eof=: 设置在读取具有
Content-Length
标头的响应体时是否忽略文件结束符。 -
:response_body_encoding: 返回用于响应体的编码。
-
#response_body_encoding=: 设置响应体编码。
代理¶ ↑
-
:proxy_address: 返回代理地址。
-
:proxy_address=: 设置代理地址。
-
::proxy_class?: 返回
self
是否是代理类。 -
#proxy?: 返回
self
是否具有代理。 -
#proxy_address: 返回代理地址。
-
#proxy_from_env?: 返回是否从环境变量获取代理。
-
:proxy_from_env=: 设置是否从环境变量获取代理。
-
:proxy_pass: 返回代理密码。
-
:proxy_pass=: 设置代理密码。
-
:proxy_port: 返回代理端口。
-
:proxy_port=: 设置代理端口。
-
#proxy_user: 返回代理用户名。
-
:proxy_user=: 设置代理用户。
安全¶ ↑
-
:ca_file: 返回 CA 证书文件的路径。
-
:ca_file=: 设置 CA 证书文件的路径。
-
:ca_path: 返回包含证书文件的 CA 目录的路径。
-
:ca_path=: 设置包含证书文件的 CA 目录的路径。
-
:cert: 返回用于客户端证书的 OpenSSL::X509::Certificate 对象。
-
:cert=: 设置用于客户端证书的 OpenSSL::X509::Certificate 对象。
-
:cert_store: 返回用于验证对等证书的 X509::Store。
-
:cert_store=: 设置用于验证对等证书的 X509::Store。
-
:ciphers: 返回可用的 SSL 密码。
-
:ciphers=: 设置可用的 SSL 密码。
-
:extra_chain_cert: 返回要添加到证书链的额外 X509 证书。
-
:extra_chain_cert=: 设置要添加到证书链的额外 X509 证书。
-
:key: 返回 OpenSSL::PKey::RSA 或 OpenSSL::PKey::DSA 对象。
-
:key=: 设置 OpenSSL::PKey::RSA 或 OpenSSL::PKey::DSA 对象。
-
:max_version: 返回最大 SSL 版本。
-
:max_version=: 设置最大 SSL 版本。
-
:min_version: 返回最小 SSL 版本。
-
:min_version=: 设置最小 SSL 版本。
-
#peer_cert: 返回会话套接字对等方的 X509 证书链。
-
:ssl_version: 返回 SSL 版本。
-
:ssl_version=: 设置 SSL 版本。
-
#use_ssl=: 设置新会话是否使用传输层安全协议。
-
#use_ssl?: 返回
self
是否使用 SSL。 -
:verify_callback: 返回用于服务器证书验证的回调。
-
:verify_callback=: 设置用于服务器证书验证的回调。
-
:verify_depth: 返回证书链验证的最大深度。
-
:verify_depth=: 设置证书链验证的最大深度。
-
:verify_hostname: 返回 SSL/TLS 会话开始时用于服务器证书验证的标志。
-
:verify_hostname=: 设置 SSL/TLS 会话开始时用于服务器证书验证的标志。
-
:verify_mode: 返回 SSL/TLS 会话开始时用于服务器证书验证的标志。
-
:verify_mode=: 设置 SSL/TLS 会话开始时用于服务器证书验证的标志。
地址和端口¶ ↑
-
:address: 返回字符串主机名或主机 IP。
-
::default_port: 返回整数 80,用于
HTTP
请求的默认端口。 -
::http_default_port: 返回整数 80,用于
HTTP
请求的默认端口。 -
::https_default_port: 返回整数 443,用于 HTTPS 请求的默认端口。
-
#ipaddr: 返回连接的 IP 地址。
-
#ipaddr=: 设置连接的 IP 地址。
-
:local_host: 返回用于建立连接的字符串本地主机。
-
:local_host=: 设置用于建立连接的字符串本地主机。
-
:local_port: 返回用于建立连接的整数本地端口。
-
:local_port=: 设置用于建立连接的整数本地端口。
-
:port: 返回整数端口号。
HTTP 版本¶ ↑
-
::version_1_2? (别名为 ::version_1_2): 返回 true;保留以实现兼容性。
调试¶ ↑
-
#set_debug_output: 设置调试的输出流。
-