類別 Net::HTTP

Net::HTTP 類別提供一個豐富的函式庫,在使用 HTTP 要求回應協定的客戶端伺服器模型中實作客戶端。有關 HTTP 的資訊,請參閱

關於範例

此處的範例假設已載入 net/http(這也需要 uri

require 'net/http'

此處的許多程式碼範例使用下列範例網站

有些範例也假設下列變數

uri = URI('https://jsonplaceholder.typicode.com/')
uri.freeze # Examples may not modify.
hostname = uri.hostname # => "jsonplaceholder.typicode.com"
path = uri.path         # => "/"
port = uri.port         # => 443

因此範例要求可以寫成

Net::HTTP.get(uri)
Net::HTTP.get(hostname, '/index.html')
Net::HTTP.start(hostname) do |http|
  http.get('/todos/1')
  http.get('/todos/2')
end

需要修改 URI 的範例會先複製 uri,然後修改複製的內容

_uri = uri.dup
_uri.path = '/todos/1'

策略

上述方法是方便方法,透過其少數引數,允許對要求進行最低限度的控制。若要進行更進一步的控制,請考慮使用 要求物件

URI

在網際網路上,URI統一資源識別碼)是一個識別特定資源的字串。它包含下列部分或全部:架構、主機名稱、路徑、查詢和片段;請參閱 URI 語法

Ruby URI::Generic 物件表示網際網路 URI。它提供下列方法,包括 schemehostnamepathqueryfragment

架構

網際網路 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 和區塊;此方法會透過以下方式自動處理會話

在區塊中,您可以使用這些實例方法,每個方法都會傳送單一要求

使用 Net::HTTP.start 和 Net::HTTP.finish 的會話

您可以使用 startfinish 方法手動管理會話

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.

單一要求會話

某些便利方法會自動處理會話,方法是

傳送 GET 要求的此類方法

傳送 POST 要求的此類方法

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

HTTPS 是透過 Net::HTTP#use_ssl= 為 HTTP 連線啟用

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 會將指定的 host 設定為其代理伺服器

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 來過濾代理伺服器

壓縮與解壓縮

在傳送之前,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 的值

此處內容

這是方法和屬性的分類摘要。

Net::HTTP 物件

工作階段

連線

要求

回應

代理

安全性

位址和埠

HTTP 版本

除錯

屬性

proxy_address[R]

傳回代理主機的位址,或 nil(如果沒有);請參閱 Net::HTTP 中的代理伺服器

proxy_pass[R]

傳回存取代理伺服器的密碼,或 nil(如果沒有);請參閱 Net::HTTP 中的代理伺服器

proxy_port[R]

傳回代理主機的埠號,或 nil(如果沒有);請參閱 Net::HTTP 中的代理伺服器

proxy_user[R]

傳回存取代理伺服器的使用者名稱,或 nil(如果沒有);請參閱 Net::HTTP 中的代理伺服器

address[R]

傳回 ::new 中作為引數 address 給出的字串主機名稱或主機 IP。

ca_file[RW]

設定或傳回 PEM 格式 CA 憑證檔案的路徑。

ca_path[RW]

設定或傳回包含 PEM 格式憑證檔案的 CA 目錄路徑。

cert[RW]

設定或傳回要使用於客戶端憑證的 OpenSSL::X509::Certificate 物件。

cert_store[RW]

設定或傳回要使用於驗證同儕憑證的 X509::Store。

ciphers[RW]

設定或傳回可用的 SSL 加密。請參閱 OpenSSL::SSL::SSLContext#ciphers=

close_on_empty_response[RW]

設定或傳回是否在回應為空時關閉連線;預設為 false

continue_timeout[R]

傳回繼續逾時值;請參閱 continue_timeout=。

extra_chain_cert[RW]

設定或傳回要加入憑證鏈中的額外 X509 憑證。請參閱 OpenSSL::SSL::SSLContext#add_certificate

ignore_eof[RW]

設定或傳回在讀取具有 Content-Length 標頭的回應主體時是否忽略檔案結尾;最初為 true

keep_alive_timeout[RW]

設定或傳回在傳送要求後保持連線開啟的秒數(整數或浮點數);最初為 2。如果在給定的區間內提出新的要求,則會使用仍開啟的連線;否則,連線將關閉並開啟新的連線。

key[RW]

設定或傳回 OpenSSL::PKey::RSAOpenSSL::PKey::DSA 物件。

local_host[RW]

設定或傳回用於建立連線的本機主機字串;最初為 nil

local_port[RW]

設定或傳回用於建立連線的本機埠號;最初為 nil

max_retries[R]

傳回重試冪等要求的最大次數;請參閱 max_retries=

max_version[RW]

設定或傳回最大的 SSL 版本。請參閱 OpenSSL::SSL::SSLContext#max_version=。

min_version[RW]

設定或傳回最小的 SSL 版本。請參閱 OpenSSL::SSL::SSLContext#min_version=。

open_timeout[RW]

設定或傳回等待連線開啟的秒數(整數或浮點數);最初為 60。如果在給定的區間內未建立連線,則會引發例外狀況。

port[R]

傳回在 ::new 中作為參數 port 給出的整數埠號。

proxy_address[W]

設定代理伺服器地址;請參閱 代理伺服器

proxy_from_env[W]

設定是否要從環境變數「ENV['http_proxy']」判斷代理伺服器;請參閱 使用 ENV[‘http_proxy’] 的代理伺服器

proxy_pass[W]

設定代理伺服器密碼;請參閱 代理伺服器

proxy_port[W]

設定代理伺服器埠號;請參閱 代理伺服器

proxy_user[W]

設定代理伺服器使用者;請參閱 代理伺服器

read_timeout[R]

傳回等待讀取一個區塊(透過一次 read(2) 呼叫)的秒數(整數或浮點數);請參閱 read_timeout=

response_body_encoding[R]

傳回回應主體要使用的編碼;請參閱 response_body_encoding=

ssl_timeout[RW]

設定或傳回 SSL 超時秒數。

ssl_version[RW]

設定或傳回 SSL 版本。請參閱 OpenSSL::SSL::SSLContext#ssl_version=。

verify_callback[RW]

設定或傳回伺服器憑證驗證的回呼函式。

verify_depth[RW]

設定或傳回憑證鏈驗證的最大深度。

verify_hostname[RW]

設定或傳回是否驗證伺服器憑證對主機名稱有效。請參閱 OpenSSL::SSL::SSLContext#verify_hostname=。

verify_mode[RW]

設定或傳回 SSL/TLS 會話開始時伺服器憑證驗證的旗標。OpenSSL::SSL::VERIFY_NONE 或 OpenSSL::SSL::VERIFY_PEER 是可接受的。

write_timeout[R]

傳回等待寫入一個區塊(透過一次 write(2) 呼叫)的秒數(整數或浮點數);請參閱 write_timeout=

公開類別方法

default_port() 按一下以切換原始碼

傳回整數 80,這是 HTTP 要求要使用的預設埠

Net::HTTP.default_port # => 80
# File lib/net/http.rb, line 900
def HTTP.default_port
  http_default_port()
end
Net::HTTP.get(hostname, path, port = 80) → body 按一下以切換原始碼
Net::HTTP:get(uri, headers = {}, port = uri.port) → body

傳送 GET 要求並傳回 HTTP 回應主體作為字串。

使用字串引數 hostnamepath

hostname = 'jsonplaceholder.typicode.com'
path = '/todos/1'
puts Net::HTTP.get(hostname, path)

輸出

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

使用 URI 物件 uri 和選用雜湊引數 headers

uri = URI('https://jsonplaceholder.typicode.com/todos/1')
headers = {'Content-type' => 'application/json; charset=UTF-8'}
Net::HTTP.get(uri, headers)

相關

# File lib/net/http.rb, line 802
def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
  get_response(uri_or_host, path_or_headers, port).body
end
Net::HTTP.get_print(hostname, path, port = 80) → nil 按一下以切換原始碼
Net::HTTP:get_print(uri, headers = {}, port = uri.port) → nil

類似 Net::HTTP.get,但會將傳回的主體寫入 $stdout;傳回 nil

# File lib/net/http.rb, line 761
def HTTP.get_print(uri_or_host, path_or_headers = nil, port = nil)
  get_response(uri_or_host, path_or_headers, port) {|res|
    res.read_body do |chunk|
      $stdout.print chunk
    end
  }
  nil
end
Net::HTTP.get_response(hostname, path, port = 80) → http_response 按一下以切換原始碼
Net::HTTP:get_response(uri, headers = {}, port = uri.port) → http_response

類似 Net::HTTP.get,但會傳回 Net::HTTPResponse 物件,而非主體字串。

# File lib/net/http.rb, line 812
def HTTP.get_response(uri_or_host, path_or_headers = nil, port = nil, &block)
  if path_or_headers && !path_or_headers.is_a?(Hash)
    host = uri_or_host
    path = path_or_headers
    new(host, port || HTTP.default_port).start {|http|
      return http.request_get(path, &block)
    }
  else
    uri = uri_or_host
    headers = path_or_headers
    start(uri.hostname, uri.port,
          :use_ssl => uri.scheme == 'https') {|http|
      return http.request_get(uri, headers, &block)
    }
  end
end
http_default_port() 按一下以切換原始碼

傳回整數 80,這是 HTTP 要求要使用的預設埠

Net::HTTP.http_default_port # => 80
# File lib/net/http.rb, line 908
def HTTP.http_default_port
  80
end
https_default_port() 按一下以切換原始碼

傳回整數 443,這是 HTTPS 請求要使用的預設埠

Net::HTTP.https_default_port # => 443
# File lib/net/http.rb, line 916
def HTTP.https_default_port
  443
end
is_version_1_2?()
別名:version_1_2?
new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil) 按一下以切換原始碼

傳回新的 Net::HTTP 物件 http(但不會開啟 TCP 連線或 HTTP 會話)。

僅提供字串引數 address(且 ENV['http_proxy'] 未定義或為 nil),傳回的 http

範例

http = Net::HTTP.new(hostname)
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
http.address # => "jsonplaceholder.typicode.com"
http.port    # => 80
http.proxy?  # => false

如果同時提供整數引數 port,傳回的 http 會具有指定的埠

http = Net::HTTP.new(hostname, 8000)
# => #<Net::HTTP jsonplaceholder.typicode.com:8000 open=false>
http.port # => 8000

有關代理伺服器定義引數 p_addrp_no_proxy,請參閱 代理伺服器

呼叫超類別方法
# File lib/net/http.rb, line 1065
def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
  http = super address, port

  if proxy_class? then # from Net::HTTP::Proxy()
    http.proxy_from_env = @proxy_from_env
    http.proxy_address  = @proxy_address
    http.proxy_port     = @proxy_port
    http.proxy_user     = @proxy_user
    http.proxy_pass     = @proxy_pass
  elsif p_addr == :ENV then
    http.proxy_from_env = true
  else
    if p_addr && p_no_proxy && !URI::Generic.use_proxy?(address, address, port, p_no_proxy)
      p_addr = nil
      p_port = nil
    end
    http.proxy_address = p_addr
    http.proxy_port    = p_port || default_port
    http.proxy_user    = p_user
    http.proxy_pass    = p_pass
  end

  http
end
別名為:newobj
newobj(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
別名為:new
post(url, data, header = nil) 按一下以切換來源

將資料傳送到主機;傳回 Net::HTTPResponse 物件。

引數 url 必須是 URL;引數 data 必須是字串

_uri = uri.dup
_uri.path = '/posts'
data = '{"title": "foo", "body": "bar", "userId": 1}'
headers = {'content-type': 'application/json'}
res = Net::HTTP.post(_uri, data, headers) # => #<Net::HTTPCreated 201 Created readbody=true>
puts res.body

輸出

{
  "title": "foo",
  "body": "bar",
  "userId": 1,
  "id": 101
}

相關

# File lib/net/http.rb, line 855
def HTTP.post(url, data, header = nil)
  start(url.hostname, url.port,
        :use_ssl => url.scheme == 'https' ) {|http|
    http.post(url, data, header)
  }
end
post_form(url, params) 按一下以切換來源

將資料傳送到主機;傳回 Net::HTTPResponse 物件。

引數 url 必須是 URI;引數 data 必須是雜湊

_uri = uri.dup
_uri.path = '/posts'
data = {title: 'foo', body: 'bar', userId: 1}
res = Net::HTTP.post_form(_uri, data) # => #<Net::HTTPCreated 201 Created readbody=true>
puts res.body

輸出

{
  "title": "foo",
  "body": "bar",
  "userId": "1",
  "id": 101
}
# File lib/net/http.rb, line 882
def HTTP.post_form(url, params)
  req = Post.new(url)
  req.form_data = params
  req.basic_auth url.user, url.password if url.user
  start(url.hostname, url.port,
        :use_ssl => url.scheme == 'https' ) {|http|
    http.request(req)
  }
end
proxy_class?() 按一下以切換來源

如果自己是 HTTP::Proxy 建立的類別,則傳回 true。

# File lib/net/http.rb, line 1762
def proxy_class?
  defined?(@is_proxy_class) ? @is_proxy_class : false
end
start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) → http 按一下以切換來源
start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) {|http| ... } → object

透過 Net::HTTP.new 建立新的 Net::HTTP 物件 http

  • 對於引數 addressport,請參閱 Net::HTTP.new

  • 對於定義 proxy 的引數 p_addrp_pass,請參閱 Proxy Server

  • 對於引數 opts,請參閱下方。

沒有提供區塊

  • 呼叫 http.start,沒有區塊(請參閱 start),這會開啟 TCP 連線和 HTTP 工作階段。

  • 傳回 http

  • 呼叫者應該呼叫 finish 以關閉工作階段

    http = Net::HTTP.start(hostname)
    http.started? # => true
    http.finish
    http.started? # => false
    

提供區塊

  • 使用區塊呼叫 http.start(請參閱 start),其中

    • 開啟 TCP 連線和 HTTP 會話。

    • 呼叫區塊,其中可能會對主機提出任意數量的要求。

    • 在區塊結束時關閉 HTTP 會話和 TCP 連線。

    • 傳回區塊的值 object

  • 傳回 object

範例

hostname = 'jsonplaceholder.typicode.com'
Net::HTTP.start(hostname) do |http|
  puts http.get('/todos/1').body
  puts http.get('/todos/2').body
end

輸出

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}
{
  "userId": 1,
  "id": 2,
  "title": "quis ut nam facilis et officia qui",
  "completed": false
}

如果給定的最後一個參數是雜湊,則它就是 opts 雜湊,其中每個鍵都是要呼叫的方法或存取器,而其值是要設定的值。

鍵可能包含

注意:如果 portnilopts[:use_ssl] 為真值,傳遞給 new 的值為 Net::HTTP.https_default_port,而不是 port

# File lib/net/http.rb, line 1010
def HTTP.start(address, *arg, &block) # :yield: +http+
  arg.pop if opt = Hash.try_convert(arg[-1])
  port, p_addr, p_port, p_user, p_pass = *arg
  p_addr = :ENV if arg.size < 2
  port = https_default_port if !port && opt && opt[:use_ssl]
  http = new(address, port, p_addr, p_port, p_user, p_pass)
  http.ipaddr = opt[:ipaddr] if opt && opt[:ipaddr]

  if opt
    if opt[:use_ssl]
      opt = {verify_mode: OpenSSL::SSL::VERIFY_PEER}.update(opt)
    end
    http.methods.grep(/\A(\w+)=\z/) do |meth|
      key = $1.to_sym
      opt.key?(key) or next
      http.__send__(meth, opt[key])
    end
  end

  http.start(&block)
end
version_1_2() 按一下以切換來源

傳回 true;保留以維持相容性。

# File lib/net/http.rb, line 736
def HTTP.version_1_2
  true
end
version_1_2?() 按一下以切換來源

傳回 true;保留以維持相容性。

# File lib/net/http.rb, line 741
def HTTP.version_1_2?
  true
end
別名為:is_version_1_2?

公開執行個體方法

active?()
別名為:started?
continue_timeout=(sec) 按一下以切換來源

設定繼續逾時值,也就是等待預期 100 Continue 回應的秒數。如果 HTTP 物件在這麼多秒內未收到回應,它會傳送請求主體。

# File lib/net/http.rb, line 1380
def continue_timeout=(sec)
  @socket.continue_timeout = sec if @socket
  @continue_timeout = sec
end
copy(path, initheader = nil) 按一下以切換來源

傳送 COPY 請求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

請求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Copy 物件。

http = Net::HTTP.new(hostname)
http.copy('/todos/1')
# File lib/net/http.rb, line 2123
def copy(path, initheader = nil)
  request(Copy.new(path, initheader))
end
delete(path, initheader = {'Depth' => 'Infinity'}) 按一下以切換來源

傳送 DELETE 請求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

請求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Delete 物件。

http = Net::HTTP.new(hostname)
http.delete('/todos/1')
# File lib/net/http.rb, line 2097
def delete(path, initheader = {'Depth' => 'Infinity'})
  request(Delete.new(path, initheader))
end
finish() 按一下以切換原始碼

結束 HTTP 會話

http = Net::HTTP.new(hostname)
http.start
http.started? # => true
http.finish   # => nil
http.started? # => false

如果不在會話中,則引發 IOError

# File lib/net/http.rb, line 1708
def finish
  raise IOError, 'HTTP session not yet started' unless started?
  do_finish
end
get(path, initheader = nil) {|res| ... } 按一下以切換原始碼

傳送 GET 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Get 物件。

如果給定區塊,則使用回應主體呼叫區塊

http = Net::HTTP.new(hostname)
http.get('/todos/1') do |res|
  p res
end # => #<Net::HTTPOK 200 OK readbody=true>

輸出

"{\n  \"userId\": 1,\n  \"id\": 1,\n  \"title\": \"delectus aut autem\",\n  \"completed\": false\n}"

如果未給定區塊,則僅傳回回應物件

http.get('/') # => #<Net::HTTPOK 200 OK readbody=true>

相關

# File lib/net/http.rb, line 1914
def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+
  res = nil

  request(Get.new(path, initheader)) {|r|
    r.read_body dest, &block
    res = r
  }
  res
end
get2(path, initheader = nil)
別名:request_get
head(path, initheader = nil) 按一下以切換原始碼

傳送 HEAD 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Head 物件

res = http.head('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
res.body                    # => nil
res.to_hash.take(3)
# =>
[["date", ["Wed, 15 Feb 2023 15:25:42 GMT"]],
 ["content-type", ["application/json; charset=utf-8"]],
 ["connection", ["close"]]]
# File lib/net/http.rb, line 1938
def head(path, initheader = nil)
  request(Head.new(path, initheader))
end
head2(path, initheader = nil, &block)
別名:request_head
inspect() 按一下以切換原始碼

傳回 self 的字串表示。

Net::HTTP.new(hostname).inspect
# => "#<Net::HTTP jsonplaceholder.typicode.com:80 open=false>"
# File lib/net/http.rb, line 1135
def inspect
  "#<#{self.class} #{@address}:#{@port} open=#{started?}>"
end
ipaddr() 按一下以切換原始碼

傳回連線的 IP 位址。

如果會話尚未開始,則傳回 ipaddr= 設定的值,或如果尚未設定,則傳回 nil

http = Net::HTTP.new(hostname)
http.ipaddr # => nil
http.ipaddr = '172.67.155.76'
http.ipaddr # => "172.67.155.76"

如果會話已開始,則傳回 socket 的 IP 位址

http = Net::HTTP.new(hostname)
http.start
http.ipaddr # => "172.67.155.76"
http.finish
# File lib/net/http.rb, line 1274
def ipaddr
  started? ?  @socket.io.peeraddr[3] : @ipaddr
end
ipaddr=(addr) 按一下以切換原始碼

設定連線的 IP 位址

http = Net::HTTP.new(hostname)
http.ipaddr # => nil
http.ipaddr = '172.67.155.76'
http.ipaddr # => "172.67.155.76"

如果會話已開始,則可能無法設定 IP 位址。

# File lib/net/http.rb, line 1286
def ipaddr=(addr)
  raise IOError, "ipaddr value changed, but session already started" if started?
  @ipaddr = addr
end
lock(path, body, initheader = nil) 按一下以切換原始碼

傳送 LOCK 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path、字串 body 和初始標頭雜湊 initheader 建立的 Net::HTTP::Lock 物件。

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.lock('/todos/1', data)
# File lib/net/http.rb, line 2043
def lock(path, body, initheader = nil)
  request(Lock.new(path, initheader), body)
end
max_retries=(retries) 按一下以切換來源

設定在 Net::ReadTimeout、IOErrorEOFError、Errno::ECONNRESET、Errno::ECONNABORTED、Errno::EPIPE、OpenSSL::SSL::SSLErrorTimeout::Error 的情況下,重試冪等要求的最大次數。初始值為 1。

引數 retries 必須是非負數值

http = Net::HTTP.new(hostname)
http.max_retries = 2   # => 2
http.max_retries       # => 2
# File lib/net/http.rb, line 1320
def max_retries=(retries)
  retries = retries.to_int
  if retries < 0
    raise ArgumentError, 'max_retries should be non-negative integer number'
  end
  @max_retries = retries
end
mkcol(path, body = nil, initheader = nil) 按一下以切換來源

傳送 MKCOL 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path、字串 body 和初始標頭雜湊 initheader 建立的 Net::HTTP::Mkcol 物件。

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http.mkcol('/todos/1', data)
http = Net::HTTP.new(hostname)
# File lib/net/http.rb, line 2137
def mkcol(path, body = nil, initheader = nil)
  request(Mkcol.new(path, initheader), body)
end
move(path, initheader = nil) 按一下以切換來源

傳送 MOVE 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Move 物件。

http = Net::HTTP.new(hostname)
http.move('/todos/1')
# File lib/net/http.rb, line 2110
def move(path, initheader = nil)
  request(Move.new(path, initheader))
end
options(path, initheader = nil) 按一下以切換來源

傳送 Options 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Options 物件。

http = Net::HTTP.new(hostname)
http.options('/')
# File lib/net/http.rb, line 2070
def options(path, initheader = nil)
  request(Options.new(path, initheader))
end
patch(path, data, initheader = nil) {|res| ... } 按一下以切換來源

傳送 PATCH 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path、字串 data 和初始標頭雜湊 initheader 建立的 Net::HTTP::Patch 物件。

如果給定區塊,則使用回應主體呼叫區塊

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.patch('/todos/1', data) do |res|
  p res
end # => #<Net::HTTPOK 200 OK readbody=true>

輸出

"{\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}"

如果未給定區塊,則僅傳回回應物件

http.patch('/todos/1', data) # => #<Net::HTTPCreated 201 Created readbody=true>
# File lib/net/http.rb, line 2001
def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
  send_entity(path, data, initheader, dest, Patch, &block)
end
peer_cert() 按一下以切換來源

傳回會話 socket 對等方的 X509 憑證鏈(字串陣列),或在沒有的話傳回 nil

# File lib/net/http.rb, line 1537
def peer_cert
  if not use_ssl? or not @socket
    return nil
  end
  @socket.io.peer_cert
end
post(path, data, initheader = nil) {|res| ... } 按一下以切換來源

傳送 POST 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path、字串 data 和初始標頭雜湊 initheader 建立的 Net::HTTP::Post 物件。

如果給定區塊,則使用回應主體呼叫區塊

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.post('/todos', data) do |res|
  p res
end # => #<Net::HTTPCreated 201 Created readbody=true>

輸出

"{\n  \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\",\n  \"id\": 201\n}"

如果未給定區塊,則僅傳回回應物件

http.post('/todos', data) # => #<Net::HTTPCreated 201 Created readbody=true>

相關

# File lib/net/http.rb, line 1972
def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
  send_entity(path, data, initheader, dest, Post, &block)
end
post2(path, data, initheader = nil)
別名:request_post
propfind(path, body = nil, initheader = {'Depth' => '0'}) 按一下以切換來源

傳送 PROPFIND 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path、字串 body 和初始標頭雜湊 initheader 建立的 Net::HTTP::Propfind 物件。

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.propfind('/todos/1', data)
# File lib/net/http.rb, line 2084
def propfind(path, body = nil, initheader = {'Depth' => '0'})
  request(Propfind.new(path, initheader), body)
end
proppatch(path, body, initheader = nil) 按一下以切換來源

傳送 PROPPATCH 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path、字串 body 和初始標頭雜湊 initheader 建立的 Net::HTTP::Proppatch 物件。

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.proppatch('/todos/1', data)
# File lib/net/http.rb, line 2029
def proppatch(path, body, initheader = nil)
  request(Proppatch.new(path, initheader), body)
end
proxy?() 按一下以切換來源

如果已定義代理伺服器,傳回 true,否則傳回 false;請參閱 代理伺服器

# File lib/net/http.rb, line 1785
def proxy?
  !!(@proxy_from_env ? proxy_uri : @proxy_address)
end
proxy_address() 按一下以切換來源

傳回代理伺服器的地址(如果已定義),否則傳回 nil;請參閱 代理伺服器

# File lib/net/http.rb, line 1807
def proxy_address
  if @proxy_from_env then
    proxy_uri&.hostname
  else
    @proxy_address
  end
end
別名為:proxyaddr
proxy_from_env?() 按一下以切換來源

如果代理伺服器在環境中已定義,傳回 true,否則傳回 false;請參閱 代理伺服器

# File lib/net/http.rb, line 1792
def proxy_from_env?
  @proxy_from_env
end
proxy_pass() 按一下以切換來源

傳回代理伺服器的密碼(如果已定義),否則傳回 nil;請參閱 代理伺服器

# File lib/net/http.rb, line 1838
def proxy_pass
  if @proxy_from_env
    pass = proxy_uri&.password
    unescape(pass) if pass
  else
    @proxy_pass
  end
end
proxy_port() 按一下以切換來源

傳回代理伺服器的埠號(如果已定義),否則傳回 nil;請參閱 代理伺服器

# File lib/net/http.rb, line 1817
def proxy_port
  if @proxy_from_env then
    proxy_uri&.port
  else
    @proxy_port
  end
end
別名為:proxyport
proxy_user() 按一下以切換來源

傳回代理伺服器的使用者名稱(如果已定義),否則傳回 nil;請參閱 代理伺服器

# File lib/net/http.rb, line 1827
def proxy_user
  if @proxy_from_env
    user = proxy_uri&.user
    unescape(user) if user
  else
    @proxy_user
  end
end
proxyaddr()
別名為:proxy_address
proxyport()
別名為:proxy_port
put(path, data, initheader = nil) 按一下以切換來源

傳送 PUT 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求根據從字串 path、字串 data 和初始標頭雜湊 initheader 建立的 Net::HTTP::Put 物件。

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.put('/todos/1', data) # => #<Net::HTTPOK 200 OK readbody=true>
# File lib/net/http.rb, line 2015
def put(path, data, initheader = nil)
  request(Put.new(path, initheader), data)
end
read_timeout=(sec) 按一下以切換來源

self 的讀取逾時(以秒為單位)設定為整數 sec;初始值為 60。

引數 sec 必須是非負數值

http = Net::HTTP.new(hostname)
http.read_timeout # => 60
http.get('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
http.read_timeout = 0
http.get('/todos/1') # Raises Net::ReadTimeout.
# File lib/net/http.rb, line 1343
def read_timeout=(sec)
  @socket.read_timeout = sec if @socket
  @read_timeout = sec
end
request(req, body = nil) { |response| ... } 按一下以切換來源

將指定的請求 req 傳送至伺服器;將回應轉換成 Net::HTTPResponse 物件。

指定的 req 必須是 Net::HTTPRequest 子類別的實例。只有在請求需要時,才應提供引數 body

如果未提供區塊,則傳回回應物件

http = Net::HTTP.new(hostname)

req = Net::HTTP::Get.new('/todos/1')
http.request(req)
# => #<Net::HTTPOK 200 OK readbody=true>

req = Net::HTTP::Post.new('/todos')
http.request(req, 'xyzzy')
# => #<Net::HTTPCreated 201 Created readbody=true>

如果提供了區塊,則呼叫該區塊並傳入回應,然後傳回回應

req = Net::HTTP::Get.new('/todos/1')
http.request(req) do |res|
  p res
end # => #<Net::HTTPOK 200 OK readbody=true>

輸出

#<Net::HTTPOK 200 OK readbody=false>
# File lib/net/http.rb, line 2295
def request(req, body = nil, &block)  # :yield: +response+
  unless started?
    start {
      req['connection'] ||= 'close'
      return request(req, body, &block)
    }
  end
  if proxy_user()
    req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl?
  end
  req.set_body_internal body
  res = transport_request(req, &block)
  if sspi_auth?(res)
    sspi_auth(req)
    res = transport_request(req, &block)
  end
  res
end
request_get(path, initheader = nil) { |response| ... } 按一下以切換來源

將 GET 請求傳送至伺服器;將回應轉換成 Net::HTTPResponse 物件。

要求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Get 物件。

如果未提供區塊,則傳回回應物件

http = Net::HTTP.new(hostname)
http.request_get('/todos') # => #<Net::HTTPOK 200 OK readbody=true>

如果提供了區塊,則呼叫該區塊並傳入回應物件,然後傳回回應物件

http.request_get('/todos') do |res|
  p res
end # => #<Net::HTTPOK 200 OK readbody=true>

輸出

#<Net::HTTPOK 200 OK readbody=false>
# File lib/net/http.rb, line 2176
def request_get(path, initheader = nil, &block) # :yield: +response+
  request(Get.new(path, initheader), &block)
end
別名為:get2
request_head(path, initheader = nil, &block) 按一下以切換來源

傳送 HEAD 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

請求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Head 物件。

http = Net::HTTP.new(hostname)
http.head('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
# File lib/net/http.rb, line 2189
def request_head(path, initheader = nil, &block)
  request(Head.new(path, initheader), &block)
end
別名為:head2
request_post(path, data, initheader = nil) { |response| ... } 按一下以切換來源

將 POST 請求傳送至伺服器;將回應轉換成 Net::HTTPResponse 物件。

要求基於從字串 path、字串 data 和初始標頭雜湊 initheader 建立的 Net::HTTP::Post 物件。

如果未提供區塊,則傳回回應物件

http = Net::HTTP.new(hostname)
http.post('/todos', 'xyzzy')
# => #<Net::HTTPCreated 201 Created readbody=true>

如果提供了區塊,則呼叫該區塊並傳入回應主體,然後傳回回應物件

http.post('/todos', 'xyzzy') do |res|
  p res
end # => #<Net::HTTPCreated 201 Created readbody=true>

輸出

"{\n  \"xyzzy\": \"\",\n  \"id\": 201\n}"
# File lib/net/http.rb, line 2216
def request_post(path, data, initheader = nil, &block) # :yield: +response+
  request Post.new(path, initheader), data, &block
end
別名為:post2
response_body_encoding=(value) 按一下以切換來源

設定要使用的回應主體編碼;傳回編碼。

指定的 value 可能為

  • 編碼 物件。

  • 編碼名稱。

  • 編碼名稱的別名。

請參閱 編碼

範例

http = Net::HTTP.new(hostname)
http.response_body_encoding = Encoding::US_ASCII # => #<Encoding:US-ASCII>
http.response_body_encoding = 'US-ASCII'         # => "US-ASCII"
http.response_body_encoding = 'ASCII'            # => "ASCII"
# File lib/net/http.rb, line 1229
def response_body_encoding=(value)
  value = Encoding.find(value) if value.is_a?(String)
  @response_body_encoding = value
end
send_request(name, path, data = nil, header = nil) 按一下以切換來源

將 HTTP 請求傳送至伺服器;傳回 Net::HTTPResponse 子類別的實例。

請求基於從字串 path、字串 data 和初始標頭雜湊 header 建立的 Net::HTTPRequest 物件。該物件是 Net::HTTPRequest 子類別的實例,對應於給定的轉換為大寫的字串 name,它必須是 HTTP 請求方法WebDAV 請求方法

範例

http = Net::HTTP.new(hostname)
http.send_request('GET', '/todos/1')
# => #<Net::HTTPOK 200 OK readbody=true>
http.send_request('POST', '/todos', 'xyzzy')
# => #<Net::HTTPCreated 201 Created readbody=true>
# File lib/net/http.rb, line 2259
def send_request(name, path, data = nil, header = nil)
  has_response_body = name != 'HEAD'
  r = HTTPGenericRequest.new(name,(data ? true : false),has_response_body,path,header)
  request r, data
end
set_debug_output(output) 按一下以切換原始碼

警告此方法會開啟一個嚴重的安全性漏洞。切勿在生產程式碼中使用此方法。

設定用於偵錯的輸出串流

http = Net::HTTP.new(hostname)
File.open('t.tmp', 'w') do |file|
  http.set_debug_output(file)
  http.start
  http.get('/nosuch/1')
  http.finish
end
puts File.read('t.tmp')

輸出

opening connection to jsonplaceholder.typicode.com:80...
opened
<- "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"
-> "HTTP/1.1 404 Not Found\r\n"
-> "Date: Mon, 12 Dec 2022 21:14:11 GMT\r\n"
-> "Content-Type: application/json; charset=utf-8\r\n"
-> "Content-Length: 2\r\n"
-> "Connection: keep-alive\r\n"
-> "X-Powered-By: Express\r\n"
-> "X-Ratelimit-Limit: 1000\r\n"
-> "X-Ratelimit-Remaining: 999\r\n"
-> "X-Ratelimit-Reset: 1670879660\r\n"
-> "Vary: Origin, Accept-Encoding\r\n"
-> "Access-Control-Allow-Credentials: true\r\n"
-> "Cache-Control: max-age=43200\r\n"
-> "Pragma: no-cache\r\n"
-> "Expires: -1\r\n"
-> "X-Content-Type-Options: nosniff\r\n"
-> "Etag: W/\"2-vyGp6PvFo4RvsFtPoIWeCReyIC8\"\r\n"
-> "Via: 1.1 vegur\r\n"
-> "CF-Cache-Status: MISS\r\n"
-> "Server-Timing: cf-q-config;dur=1.3000000762986e-05\r\n"
-> "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"
-> "NEL: {\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}\r\n"
-> "Server: cloudflare\r\n"
-> "CF-RAY: 778977dc484ce591-DFW\r\n"
-> "alt-svc: h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\r\n"
-> "\r\n"
reading 2 bytes...
-> "{}"
read 2 bytes
Conn keep-alive
# File lib/net/http.rb, line 1188
def set_debug_output(output)
  warn 'Net::HTTP#set_debug_output called after HTTP started', uplevel: 1 if started?
  @debug_output = output
end
start() { |http| ... } 按一下以切換原始碼

開始 HTTP 會話。

若無區塊,傳回 self

http = Net::HTTP.new(hostname)
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
http.start
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=true>
http.started? # => true
http.finish

若有區塊,使用 self 呼叫區塊,區塊結束時結束會話,並傳回區塊的值

http.start do |http|
  http
end
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
http.started? # => false
# File lib/net/http.rb, line 1565
def start  # :yield: http
  raise IOError, 'HTTP session already opened' if @started
  if block_given?
    begin
      do_start
      return yield(self)
    ensure
      do_finish
    end
  end
  do_start
  self
end
started?() 按一下以切換原始碼

如果 HTTP 會話已開始,傳回 true

http = Net::HTTP.new(hostname)
http.started? # => false
http.start
http.started? # => true
http.finish # => nil
http.started? # => false

Net::HTTP.start(hostname) do |http|
  http.started?
end # => true
http.started? # => false
# File lib/net/http.rb, line 1413
def started?
  @started
end
別名為:active?
trace(path, initheader = nil) 按一下以切換原始碼

傳送 TRACE 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path 和初始標頭雜湊 initheader 建立的 Net::HTTP::Trace 物件。

http = Net::HTTP.new(hostname)
http.trace('/todos/1')
# File lib/net/http.rb, line 2150
def trace(path, initheader = nil)
  request(Trace.new(path, initheader))
end
unlock(path, body, initheader = nil) 按一下以切換原始碼

傳送 UNLOCK 要求至伺服器;傳回 Net::HTTPResponse 子類別的執行個體。

要求基於從字串 path、字串 body 和初始標頭雜湊 initheader 建立的 Net::HTTP::Unlock 物件。

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.unlock('/todos/1', data)
# File lib/net/http.rb, line 2057
def unlock(path, body, initheader = nil)
  request(Unlock.new(path, initheader), body)
end
use_ssl=(flag) 按一下以切換原始碼

設定新的會話是否要使用 傳輸層安全性

如果嘗試在會話期間變更,會引發 IOError

如果埠不是 HTTPS 埠,會引發 OpenSSL::SSL::SSLError

# File lib/net/http.rb, line 1435
def use_ssl=(flag)
  flag = flag ? true : false
  if started? and @use_ssl != flag
    raise IOError, "use_ssl value changed, but session already started"
  end
  @use_ssl = flag
end
use_ssl?() 按一下以切換原始碼

如果 self 使用 SSL,傳回 true,否則傳回 false。請參閱 Net::HTTP#use_ssl=

# File lib/net/http.rb, line 1425
def use_ssl?
  @use_ssl
end
write_timeout=(sec) 按一下以切換原始碼

self 的寫入逾時時間(以秒為單位)設定為整數 sec;初始值為 60。

引數 sec 必須是非負數值

_uri = uri.dup
_uri.path = '/posts'
body = 'bar' * 200000
data = <<EOF
{"title": "foo", "body": "#{body}", "userId": "1"}
EOF
headers = {'content-type': 'application/json'}
http = Net::HTTP.new(hostname)
http.write_timeout # => 60
http.post(_uri.path, data, headers)
# => #<Net::HTTPCreated 201 Created readbody=true>
http.write_timeout = 0
http.post(_uri.path, data, headers) # Raises Net::WriteTimeout.
# File lib/net/http.rb, line 1367
def write_timeout=(sec)
  @socket.write_timeout = sec if @socket
  @write_timeout = sec
end

私有實例方法

D(msg)
別名為:debug
addr_port() 按一下以切換來源

utils

# File lib/net/http.rb, line 2464
def addr_port
  addr = address
  addr = "[#{addr}]" if addr.include?(":")
  default_port = use_ssl? ? HTTP.https_default_port : HTTP.http_default_port
  default_port == port ? addr : "#{addr}:#{port}"
end
begin_transport(req) 按一下以切換來源
# File lib/net/http.rb, line 2381
def begin_transport(req)
  if @socket.closed?
    connect
  elsif @last_communicated
    if @last_communicated + @keep_alive_timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC)
      debug 'Conn close because of keep_alive_timeout'
      @socket.close
      connect
    elsif @socket.io.to_io.wait_readable(0) && @socket.eof?
      debug "Conn close because of EOF"
      @socket.close
      connect
    end
  end

  if not req.response_body_permitted? and @close_on_empty_response
    req['connection'] ||= 'close'
  end

  req.update_uri address, port, use_ssl?
  req['host'] ||= addr_port()
end
connect() 按一下以切換來源
# File lib/net/http.rb, line 1585
def connect
  if use_ssl?
    # reference early to load OpenSSL before connecting,
    # as OpenSSL may take time to load.
    @ssl_context = OpenSSL::SSL::SSLContext.new
  end

  if proxy? then
    conn_addr = proxy_address
    conn_port = proxy_port
  else
    conn_addr = conn_address
    conn_port = port
  end

  debug "opening connection to #{conn_addr}:#{conn_port}..."
  s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
    begin
      TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
    rescue => e
      raise e, "Failed to open TCP connection to " +
        "#{conn_addr}:#{conn_port} (#{e.message})"
    end
  }
  s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
  debug "opened"
  if use_ssl?
    if proxy?
      plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
                                  write_timeout: @write_timeout,
                                  continue_timeout: @continue_timeout,
                                  debug_output: @debug_output)
      buf = +"CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n" \
        "Host: #{@address}:#{@port}\r\n"
      if proxy_user
        credential = ["#{proxy_user}:#{proxy_pass}"].pack('m0')
        buf << "Proxy-Authorization: Basic #{credential}\r\n"
      end
      buf << "\r\n"
      plain_sock.write(buf)
      HTTPResponse.read_new(plain_sock).value
      # assuming nothing left in buffers after successful CONNECT response
    end

    ssl_parameters = Hash.new
    iv_list = instance_variables
    SSL_IVNAMES.each_with_index do |ivname, i|
      if iv_list.include?(ivname)
        value = instance_variable_get(ivname)
        unless value.nil?
          ssl_parameters[SSL_ATTRIBUTES[i]] = value
        end
      end
    end
    @ssl_context.set_params(ssl_parameters)
    unless @ssl_context.session_cache_mode.nil? # a dummy method on JRuby
      @ssl_context.session_cache_mode =
          OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
              OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
    end
    if @ssl_context.respond_to?(:session_new_cb) # not implemented under JRuby
      @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
    end

    # Still do the post_connection_check below even if connecting
    # to IP address
    verify_hostname = @ssl_context.verify_hostname

    # Server Name Indication (SNI) RFC 3546/6066
    case @address
    when Resolv::IPv4::Regex, Resolv::IPv6::Regex
      # don't set SNI, as IP addresses in SNI is not valid
      # per RFC 6066, section 3.

      # Avoid openssl warning
      @ssl_context.verify_hostname = false
    else
      ssl_host_address = @address
    end

    debug "starting SSL for #{conn_addr}:#{conn_port}..."
    s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
    s.sync_close = true
    s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address

    if @ssl_session and
       Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
      s.session = @ssl_session
    end
    ssl_socket_connect(s, @open_timeout)
    if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
      s.post_connection_check(@address)
    end
    debug "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
  end
  @socket = BufferedIO.new(s, read_timeout: @read_timeout,
                           write_timeout: @write_timeout,
                           continue_timeout: @continue_timeout,
                           debug_output: @debug_output)
  @last_communicated = nil
  on_connect
rescue => exception
  if s
    debug "Conn close because of connect error #{exception}"
    s.close
  end
  raise
end
debug(msg) 按一下以切換來源

將訊息新增至偵錯輸出

# File lib/net/http.rb, line 2472
def debug(msg)
  return unless @debug_output
  @debug_output << msg
  @debug_output << "\n"
end
別名為:D
do_finish() 按一下以切換來源
# File lib/net/http.rb, line 1713
def do_finish
  @started = false
  @socket.close if @socket
  @socket = nil
end
do_start() 按一下以切換來源
# File lib/net/http.rb, line 1579
def do_start
  connect
  @started = true
end
edit_path(path) 按一下以切換來源
# File lib/net/http.rb, line 1867
def edit_path(path)
  if proxy?
    if path.start_with?("ftp://") || use_ssl?
      path
    else
      "http://#{addr_port}#{path}"
    end
  else
    path
  end
end
end_transport(req, res) 按一下以切換來源
# File lib/net/http.rb, line 2404
def end_transport(req, res)
  @curr_http_version = res.http_version
  @last_communicated = nil
  if @socket.closed?
    debug 'Conn socket closed'
  elsif not res.body and @close_on_empty_response
    debug 'Conn close'
    @socket.close
  elsif keep_alive?(req, res)
    debug 'Conn keep-alive'
    @last_communicated = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  else
    debug 'Conn close'
    @socket.close
  end
end
keep_alive?(req, res) 按一下以切換來源
# File lib/net/http.rb, line 2421
def keep_alive?(req, res)
  return false if req.connection_close?
  if @curr_http_version <= '1.0'
    res.connection_keep_alive?
  else   # HTTP/1.1 or later
    not res.connection_close?
  end
end
on_connect() 按一下以切換來源
# File lib/net/http.rb, line 1695
def on_connect
end
send_entity(path, data, initheader, dest, type, &block) 按一下以切換來源

執行使用表示式並傳回其主體的請求。

# File lib/net/http.rb, line 2318
def send_entity(path, data, initheader, dest, type, &block)
  res = nil
  request(type.new(path, initheader), data) {|r|
    r.read_body dest, &block
    res = r
  }
  res
end
sspi_auth(req) 按一下以切換來源
# File lib/net/http.rb, line 2445
def sspi_auth(req)
  n = Win32::SSPI::NegotiateAuth.new
  req["Proxy-Authorization"] = "Negotiate #{n.get_initial_token}"
  # Some versions of ISA will close the connection if this isn't present.
  req["Connection"] = "Keep-Alive"
  req["Proxy-Connection"] = "Keep-Alive"
  res = transport_request(req)
  authphrase = res["Proxy-Authenticate"]  or return res
  req["Proxy-Authorization"] = "Negotiate #{n.complete_authentication(authphrase)}"
rescue => err
  raise HTTPAuthenticationError.new('HTTP authentication failed', err)
end
sspi_auth?(res) 按一下以切換來源
# File lib/net/http.rb, line 2430
def sspi_auth?(res)
  return false unless @sspi_enabled
  if res.kind_of?(HTTPProxyAuthenticationRequired) and
      proxy? and res["Proxy-Authenticate"].include?("Negotiate")
    begin
      require 'win32/sspi'
      true
    rescue LoadError
      false
    end
  else
    false
  end
end
transport_request(req) { |res| ... } 按一下以切換來源
# File lib/net/http.rb, line 2329
def transport_request(req)
  count = 0
  begin
    begin_transport req
    res = catch(:response) {
      begin
        req.exec @socket, @curr_http_version, edit_path(req.path)
      rescue Errno::EPIPE
        # Failure when writing full request, but we can probably
        # still read the received response.
      end

      begin
        res = HTTPResponse.read_new(@socket)
        res.decode_content = req.decode_content
        res.body_encoding = @response_body_encoding
        res.ignore_eof = @ignore_eof
      end while res.kind_of?(HTTPInformation)

      res.uri = req.uri

      res
    }
    res.reading_body(@socket, req.response_body_permitted?) {
      yield res if block_given?
    }
  rescue Net::OpenTimeout
    raise
  rescue Net::ReadTimeout, IOError, EOFError,
         Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE, Errno::ETIMEDOUT,
         # avoid a dependency on OpenSSL
         defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : IOError,
         Timeout::Error => exception
    if count < max_retries && IDEMPOTENT_METHODS_.include?(req.method)
      count += 1
      @socket.close if @socket
      debug "Conn close because of error #{exception}, and retry"
      retry
    end
    debug "Conn close because of error #{exception}"
    @socket.close if @socket
    raise
  end

  end_transport req, res
  res
rescue => exception
  debug "Conn close because of error #{exception}"
  @socket.close if @socket
  raise exception
end
unescape(value) 按一下以切換來源
# File lib/net/http.rb, line 1852
def unescape(value)
  require 'cgi/util'
  CGI.unescape(value)
end