Tuesday, October 10, 2017

Net::HTTP



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
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)
POST

uri = 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::HTTP

Theo 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 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
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')
POST

Mộ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
Basic authentication được thực hiện theo như RFC2617
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