模块 Net

常量

HTTPGatewayTimeOut

Gateway Timeout 响应(状态码 504)的响应类。

服务器充当网关或代理,但未及时收到上游服务器的响应。

参考

HTTPMovedTemporarily

Found 响应(状态码 302)的响应类。

Found 响应表明客户端应查看(浏览到)另一个 URL。

参考

HTTPMultipleChoice

Multiple Choices 响应(状态码 300)的响应类。

Multiple Choices 响应表明服务器为客户端可能选择的资源提供了多个选项。

参考

HTTPRequestEntityTooLarge

Payload Too Large 响应(状态码 413)的响应类。

请求大于服务器愿意或能够处理的大小。

参考

HTTPRequestTimeOut

Request Timeout 响应(状态码 408)的响应类。

服务器等待请求超时。

参考

HTTPRequestURITooLarge

URI Too Long 响应(状态码 414)的响应类。

提供的 URI 对于服务器处理来说太长。

参考

HTTPRequestURITooLong

URI Too Long 响应(状态码 414)的响应类。

提供的 URI 对于服务器处理来说太长。

参考

HTTPRequestedRangeNotSatisfiable

Range Not Satisfiable 响应(状态码 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

在 Internet 上,URI(通用资源标识符)是一个标识特定资源的字符串。它由以下部分或全部组成:方案、主机名、路径、查询和片段;请参阅URI 语法

Ruby URI::Generic 对象表示 Internet URI。它提供诸如 schemehostnamepathqueryfragment 等方法。

方案

Internet URI 具有方案

Net::HTTP 中支持的两种方案是 '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.start;该方法通过以下方式自动处理会话

  • 在块执行之前调用 start。

  • 执行块。

  • 在块执行后调用 finish。

在该块中,您可以使用这些实例方法,每个方法都会发送一个请求

  • HTTP 方法:

    • get, request_get:GET。

    • head, request_head:HEAD。

    • post, request_post:POST。

    • delete:DELETE。

    • options:OPTIONS。

    • trace:TRACE。

    • patch:PATCH。

  • WebDAV 方法:

    • 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 连接启用 HTTPS

Net::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 方案,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"

这会请求服务器压缩编码响应正文(如果有);不要求服务器这样做。

如果响应具有标头 'Content-Range',则 Net::HTTP 不会自动解压缩响应正文。

否则,解压缩(或不解压缩)取决于标头 Content-Encoding 的值

  • 'deflate''gzip''x-gzip':解压缩正文并删除标头。

  • 'none''identity':不解压缩主体,但删除标头。

  • 任何其他值:保持主体和标头不变。

本页内容

首先,介绍其他地方的内容。类 Net::HTTP

  • 继承自类 Object。

这是方法和属性的分类摘要。

Net::HTTP 对象

  • ::new:创建一个新的实例。

  • #inspect:返回 self 的字符串表示形式。

会话

  • ::start:在一个新的 Net::HTTP 对象中开始一个新的会话。

  • #started?:返回是否在会话中。

  • #finish:结束一个活动会话。

  • #start:在现有 Net::HTTP 对象(self)中开始一个新的会话。

连接

请求

  • ::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 请求并返回一个响应对象。

响应

代理

安全

  • :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 会话开始时服务器证书验证的标志。

地址和端口

HTTP 版本

调试