Một HTTP client API của Ruby
Net::HTTP cung cấp một thư viện rất mạnh, nó có thể sử dụng để xây dựng các HTTP user-agent. Để biết thêm về HTTP bạn hãy xem RFC2616. Net::HTTP được thiết kế để làm việc được với URI. URI::HTTP#host, URI::HTTP#port và URI::HTTP#request_uri được thiết kế để làm việc được với Net::HTTP.
Nếu bạn chỉ thực hiện một vài yêu cầu GET, bạn nên thử OpenURI
Một vài ví dụ đơn giản
Tất cả ví dụ này bạn nên tải Net::HTTP với lệnh:
require 'net/http'
Khi khai báo như trên thì chúng ta cũng đã tải uri. Vì vậy bạn không cần tải riêng.
GET
GET
Net::HTTP.get('example.com', '/index.html') # => String
GET bởi URI
uri = URI('http://example.com/index.html?count=10')
Net::HTTP.get(uri) # => String
GET bởi những tham số động
uri = URI('http://example.com/index.html')
params = { :limit => 10, :page => 3 }
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
puts res.body if res.is_a?(Net::HTTPSuccess)
POSTuri = URI('http://www.example.com/search.cgi')
res = Net::HTTP.post_form(uri, 'q' => 'ruby', 'max' => '50')
puts res.body
POST cùng với nhiều giá trịuri = URI('http://www.example.com/search.cgi')
res = Net::HTTP.post_form(uri, 'q' => ['ruby', 'perl'], 'max' => '50')
puts res.body
Làm thế nào để sử dụng Net::HTTPTheo như ví dụ dưới đây, chúng ta có thể sử dụng HTTP user-agent để thực hiện nhiều loại request với các kết nối liên tục.
uri = URI('http://example.com/some_path?query=string')
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Get.new uri
response = http.request request # Net::HTTPResponse object
end
::start ngay lập tức tạo ra kết nối đến một HTTP server và được giữ kết nối trong suốt thời gian của block. Kết nối được mở cho nhiều request trong khối nếu server có thể hỗ trợ các kết nối liên tục.
Các request Net::HTTP hỗ trợ được liệt kê trong phần
Các request Net::HTTP hỗ trợ được liệt kê trong phần
HTTP Request Classes
bên dưới.
Nếu bạn muốn sử dụng lại HTTP request qua nhiều lần mà không tự động đóng thì bạn có thể sử dụng ::new thay cho :start. Request sẽ tự động mở một kết nối đến server nếu server chưa có kết nối. Bạn có thể đóng kết nối nếu đã kết thúc.
Đối với tất cả các đối tượng HTTP request và các phương thức request bạn có thể cung cấp một String của request path hoặc một URI trích xuất ra từ request path của Net::HTTP.
Dữ liệu trả về
uri = URI('http://example.com/index.html')
res = Net::HTTP.get_response(uri)
# Headers
res['Set-Cookie'] # => String
res.get_fields('set-cookie') # => Array
res.to_hash['set-cookie'] # => Array
puts "Headers: #{res.to_hash.inspect}"
# Status
puts res.code # => '200'
puts res.message # => 'OK'
puts res.class.name # => 'HTTPOK'
# Body
puts res.body if res.response_body_permitted?
Following Redirecti
Mỗi đối tượng Net::HTTPResponse thuộc về một lớp cùng với response code của nó.
Ví dụ, tất cả các response 2XX là những instance của một lớp con Net::HTTPSuccess, response 3XX là một instance của một lớp con Net::HTTPRedirection và một response 200 là một instance của lớp Net::HTTPOK. Để biết chi tiết về các response, hãy xem phần HTTP Response Classes bên dưới.
Sử dụng case statement, bạn có thể xử lý được các loại response
Ví dụ, tất cả các response 2XX là những instance của một lớp con Net::HTTPSuccess, response 3XX là một instance của một lớp con Net::HTTPRedirection và một response 200 là một instance của lớp Net::HTTPOK. Để biết chi tiết về các response, hãy xem phần HTTP Response Classes bên dưới.
Sử dụng case statement, bạn có thể xử lý được các loại response
def fetch(uri_str, limit = 10)
# You should choose a better exception.
raise ArgumentError, 'too many HTTP redirects' if limit == 0
response = Net::HTTP.get_response(URI(uri_str))
case response
when Net::HTTPSuccess then
response
when Net::HTTPRedirection then
location = response['location']
warn "redirected to #{location}"
fetch(location, limit - 1)
else
response.value
end
end
print fetch('http://www.ruby-lang.org')
POSTMột POST có thể được thực hiện bằng cách sử dụng lớp Net::HTTP::Post. Ví dụ tạo ra một body để post
uri = URI('http://www.example.com/todo.cgi')
req = Net::HTTP::Post.new(uri)
req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(req)
end
case res
when Net::HTTPSuccess, Net::HTTPRedirection
# OK
else
res.value
end
Tại thời điểm này, Net::HTTP không hỗ trợ multipart/form-data. Để gửi multipart/form-data sử dụng Net::HTTPGenericRequest#body= và Net::HTTPHeader#content_type=:
req = Net::HTTP::Post.new(uri)
req.body = multipart_data
req.content_type = 'multipart/form-data'
Những request khác có thể chứa một body giống như request PUT và cũng có thể tạo theo cùng một cách sử dụng lớp request tương ứng Net::HTTP::Put
Cài đặt Header
Ví dụ sau thực hiện một request GET sử dụng điều kiện If-Modified-Since ở header. Nếu như các file không được định nghĩa trong header thì sẽ không có Modified response được trả về
uri = URI('http://example.com/cached_response')
file = File.stat 'cached_response'
req = Net::HTTP::Get.new(uri)
req['If-Modified-Since'] = file.mtime.rfc2822
res = Net::HTTP.start(uri.hostname, uri.port) {|http|
http.request(req)
}
open 'cached_response', 'w' do |io|
io.write res.body
end if res.is_a?(Net::HTTPSuccess)
Basic Authentication
uri = URI('http://example.com/index.html?key=value')
req = Net::HTTP::Get.new(uri)
req.basic_auth 'user', 'pass'
res = Net::HTTP.start(uri.hostname, uri.port) {|http|
http.request(req)
}
puts res.body
Streaming Response Bodies
Bởi theo mặc định Net::HTTP đọc toàn bộ response trả về vào bộ nhớ. Nếu bạn đang xử lý các tệp lớn bạn có thể truyền trực tiếp đến một IO
uri = URI('http://example.com/large_file')
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Get.new uri
http.request request do |response|
open 'large_file', 'w' do |io|
response.read_body do |chunk|
io.write chunk
end
end
end
end
HTTPS
HTTPS được bật cho kết nối HTTP bởi #use_ssl=
uri = URI('https://secure.example.com/some_path?query=string')
Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
request = Net::HTTP::Get.new uri
response = http.request request # Net::HTTPResponse object
end
Hoặc nếu bạn chỉ muốn thực hiện một request GET, bạn có thể truyền vào một đối tượng URI có HTTPS URL. Net::HTTP tự động bật TLS verification
uri = URI('https://example.com/')
Net::HTTP.get(uri) # => String
Trong những phiên bản trước của ruby, bạn cần phải require 'net/https' để sử dụng HTTPS. Nhưng bây giờ thì đã không cần thiết nữa.
Proxy
Net::HTTP sẽ tự động tạo ra một proxy từ biến môi trường http_proxy nếu nó tồn tại. Để vô hiệu hóa việc sử dụng http_proxy, bạn hãy truyền nil đến address proxy.
Bạn cũng có thể tạo ra một custom proxy
proxy_addr = 'your.proxy.host'
proxy_port = 8080
Net::HTTP.new('example.com', nil, proxy_addr, proxy_port).start { |http|
# always proxy via your.proxy.addr:8080
}
Xem thêm : học lập trình java ở đâu
No comments:
Post a Comment