DESCRIPTION
HTTPAccess::Client -- Client to retrieve web resources via HTTP.
How to create your client.
1. Create simple client. clnt = HTTPAccess::Client.new 2. Accessing resources through HTTP proxy. clnt = HTTPAccess::Client.new("http://myproxy:8080") 3. Set User-Agent and From in HTTP request header.(nil means "No proxy") clnt = HTTPAccess::Client.new(nil, "MyAgent", "nahi@keynauts.com")
How to retrieve web resources.
1. Get content of specified URL. puts clnt.get_content("http://www.ruby-lang.org/en/") 2. Do HEAD request. res = clnt.head(uri) 3. Do GET request with query. res = clnt.get(uri) 4. Do POST request. res = clnt.post(uri) res = clnt.get|post|head(uri, proxy)
- conn_request
- connect_timeout
- connect_timeout=
- create_request
- debug_dev
- debug_dev=
- default_redirect_uri_callback
- delete
- delete_async
- do_get_block
- do_get_header
- do_get_stream
- dump_dummy_request_response
- get
- get_async
- get_content
- head
- head_async
- new
- no_proxy
- no_proxy=
- no_proxy?
- options
- options_async
- post
- post_async
- post_content
- protocol_version
- protocol_version=
- proxy
- proxy=
- put
- put_async
- receive_timeout
- receive_timeout=
- redirect_uri_callback=
- request
- request_async
- reset
- reset_all
- retry_connect
- save_cookie_store
- send_timeout
- send_timeout=
- set_basic_auth
- set_cookie_store
- socket_sync=
- trace
- trace_async
NO_PROXY_HOSTS | = | ['localhost'] |
[R] | agent_name | |
[RW] | cookie_manager | |
[R] | from | |
[R] | ssl_config | |
[R] | test_loopback_response |
SYNOPSIS
Client.new(proxy = nil, agent_name = nil, from = nil)
ARGS
proxy A String of HTTP proxy URL. ex. "http://proxy:8080". agent_name A String for "User-Agent" HTTP request header. from A String for "From" HTTP request header.
DESCRIPTION
Create an instance. SSLConfig cannot be re-initialized. Create new client.
[ show source ]
# File lib/facets/more/httpaccess.rb, line 117 def initialize(proxy = nil, agent_name = nil, from = nil) @proxy = nil # assigned later. @no_proxy = nil @agent_name = agent_name @from = from @basic_auth = BasicAuth.new(self) @debug_dev = nil @ssl_config = SSLConfig.new(self) @redirect_uri_callback = method(:default_redirect_uri_callback) @test_loopback_response = [] @session_manager = SessionManager.new @session_manager.agent_name = @agent_name @session_manager.from = @from @session_manager.ssl_config = @ssl_config @cookie_manager = WebAgent::CookieManager.new self.proxy = proxy end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 154 def connect_timeout @session_manager.connect_timeout end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 158 def connect_timeout=(connect_timeout) reset_all @session_manager.connect_timeout = connect_timeout end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 135 def debug_dev @debug_dev end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 139 def debug_dev=(dev) @debug_dev = dev reset_all @session_manager.debug_dev = dev end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 270 def default_redirect_uri_callback(res) uri = res.header['location'][0] puts "Redirect to: #{uri}" if $DEBUG uri end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 292 def delete(uri, extheader = {}, &block) request('DELETE', uri, nil, nil, extheader, &block) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 328 def delete_async(uri, extheader = {}) request_async('DELETE', uri, nil, nil, extheader) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 280 def get(uri, query = nil, extheader = {}, &block) request('GET', uri, query, nil, extheader, &block) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 316 def get_async(uri, query = nil, extheader = {}) request_async('GET', uri, query, nil, extheader) end
SYNOPSIS
Client#get_content(uri, query = nil, extheader = {}, &block = nil)
ARGS
uri an_URI or a_string of uri to connect. query a_hash or an_array of query part. e.g. { "a" => "b" }. Give an array to pass multiple value like [["a" => "b"], ["a" => "c"]]. extheader a_hash of extra headers like { "SOAPAction" => "urn:foo" }. &block Give a block to get chunked message-body of response like get_content(uri) { |chunked_body| ... } Size of each chunk may not be the same.
DESCRIPTION
Get a_sring of message-body of response.
[ show source ]
# File lib/facets/more/httpaccess.rb, line 258 def get_content(uri, query = nil, extheader = {}, &block) retry_connect(uri, query) do |uri, query| get(uri, query, extheader, &block) end end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 276 def head(uri, query = nil, extheader = {}) request('HEAD', uri, query, nil, extheader) end
Async interface.
[ show source ]
# File lib/facets/more/httpaccess.rb, line 312 def head_async(uri, query = nil, extheader = {}) request_async('HEAD', uri, query, nil, extheader) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 203 def no_proxy @no_proxy end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 207 def no_proxy=(no_proxy) @no_proxy = no_proxy reset_all end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 296 def options(uri, extheader = {}, &block) request('OPTIONS', uri, nil, nil, extheader, &block) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 332 def options_async(uri, extheader = {}) request_async('OPTIONS', uri, nil, nil, extheader) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 284 def post(uri, body = nil, extheader = {}, &block) request('POST', uri, nil, body, extheader, &block) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 320 def post_async(uri, body = nil, extheader = {}) request_async('POST', uri, nil, body, extheader) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 264 def post_content(uri, body = nil, extheader = {}, &block) retry_connect(uri, nil) do |uri, query| post(uri, body, extheader, &block) end end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 145 def protocol_version @session_manager.protocol_version end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 149 def protocol_version=(protocol_version) reset_all @session_manager.protocol_version = protocol_version end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 181 def proxy @proxy end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 185 def proxy=(proxy) if proxy.nil? @proxy = nil else if proxy.is_a?(URI) @proxy = proxy else @proxy = URI.parse(proxy) end if @proxy.scheme == nil or @proxy.scheme.downcase != 'http' or @proxy.host == nil or @proxy.port == nil raise ArgumentError.new("unsupported proxy `#{proxy}'") end end reset_all @proxy end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 288 def put(uri, body = nil, extheader = {}, &block) request('PUT', uri, nil, body, extheader, &block) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 324 def put_async(uri, body = nil, extheader = {}) request_async('PUT', uri, nil, body, extheader) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 172 def receive_timeout @session_manager.receive_timeout end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 176 def receive_timeout=(receive_timeout) reset_all @session_manager.receive_timeout = receive_timeout end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 237 def redirect_uri_callback=(redirect_uri_callback) @redirect_uri_callback = redirect_uri_callback end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 304 def request(method, uri, query = nil, body = nil, extheader = {}, &block) conn = Connection.new conn_request(conn, method, uri, query, body, extheader, &block) conn.pop end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 340 def request_async(method, uri, query = nil, body = nil, extheader = {}) conn = Connection.new t = Thread.new(conn) { |tconn| conn_request(tconn, method, uri, query, body, extheader) } conn.async_thread = t conn end
Management interface.
[ show source ]
# File lib/facets/more/httpaccess.rb, line 357 def reset(uri) @session_manager.reset(uri) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 361 def reset_all @session_manager.reset_all end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 233 def save_cookie_store @cookie_manager.save_cookies end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 163 def send_timeout @session_manager.send_timeout end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 167 def send_timeout=(send_timeout) reset_all @session_manager.send_timeout = send_timeout end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 218 def set_basic_auth(uri, user_id, passwd) unless uri.is_a?(URI) uri = URI.parse(uri) end @basic_auth.set(uri, user_id, passwd) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 225 def set_cookie_store(filename) if @cookie_manager.cookies_file raise RuntimeError.new("overriding cookie file location") end @cookie_manager.cookies_file = filename @cookie_manager.load_cookies if filename end
if your ruby is older than 2005-09-06, do not set socket_sync = false to avoid an SSL socket blocking bug in openssl/buffering.rb.
[ show source ]
# File lib/facets/more/httpaccess.rb, line 214 def socket_sync=(socket_sync) @session_manager.socket_sync = socket_sync end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 300 def trace(uri, query = nil, body = nil, extheader = {}, &block) request('TRACE', uri, query, body, extheader, &block) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 336 def trace_async(uri, query = nil, body = nil, extheader = {}) request_async('TRACE', uri, query, body, extheader) end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 384 def conn_request(conn, method, uri, query, body, extheader, &block) unless uri.is_a?(URI) uri = URI.parse(uri) end proxy = no_proxy?(uri) ? nil : @proxy begin req = create_request(method, uri, query, body, extheader, !proxy.nil?) do_get_block(req, proxy, conn, &block) rescue Session::KeepAliveDisconnected req = create_request(method, uri, query, body, extheader, !proxy.nil?) do_get_block(req, proxy, conn, &block) end end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 398 def create_request(method, uri, query, body, extheader, proxy) if extheader.is_a?(Hash) extheader = extheader.to_a end cred = @basic_auth.get(uri) if cred extheader << ['Authorization', "Basic " << cred] end if cookies = @cookie_manager.find(uri) extheader << ['Cookie', cookies] end boundary = nil content_type = extheader.find { |key, value| key.downcase == 'content-type' } if content_type && content_type[1] =~ /boundary=(.+)\z/ boundary = $1 end req = HTTP::Message.new_request(method, uri, query, body, proxy, boundary) extheader.each do |key, value| req.header.set(key, value) end if content_type.nil? and !body.nil? req.header.set('content-type', 'application/x-www-form-urlencoded') end req end
!! CAUTION !!
Method 'do_get*' runs under MT conditon. Be careful to change.
[ show source ]
# File lib/facets/more/httpaccess.rb, line 446 def do_get_block(req, proxy, conn, &block) if str = @test_loopback_response.shift dump_dummy_request_response(req.body.dump, str) if @debug_dev conn.push(HTTP::Message.new_response(str)) return end content = '' res = HTTP::Message.new_response(content) @debug_dev << "= Request\n\n" if @debug_dev sess = @session_manager.query(req, proxy) @debug_dev << "\n\n= Response\n\n" if @debug_dev do_get_header(req, res, sess) conn.push(res) sess.get_data() do |str| block.call(str) if block content << str end @session_manager.keep(sess) unless sess.closed? end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 486 def do_get_header(req, res, sess) res.version, res.status, res.reason = sess.get_status sess.get_header().each do |line| unless /^([^:]+)\s*:\s*(.*)$/ =~ line raise RuntimeError.new("Unparsable header: '#{line}'.") if $DEBUG end res.header.set($1, $2) end if res.header['set-cookie'] res.header['set-cookie'].each do |cookie| @cookie_manager.parse(cookie, req.header.request_uri) end end end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 466 def do_get_stream(req, proxy, conn) if str = @test_loopback_response.shift dump_dummy_request_response(req.body.dump, str) if @debug_dev conn.push(HTTP::Message.new_response(str)) return end piper, pipew = IO.pipe res = HTTP::Message.new_response(piper) @debug_dev << "= Request\n\n" if @debug_dev sess = @session_manager.query(req, proxy) @debug_dev << "\n\n= Response\n\n" if @debug_dev do_get_header(req, res, sess) conn.push(res) sess.get_data() do |str| pipew.syswrite(str) end pipew.close @session_manager.keep(sess) unless sess.closed? end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 501 def dump_dummy_request_response(req, res) @debug_dev << "= Dummy Request\n\n" @debug_dev << req @debug_dev << "\n\n= Dummy Response\n\n" @debug_dev << res end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 428 def no_proxy?(uri) if !@proxy or NO_PROXY_HOSTS.include?(uri.host) return true end unless @no_proxy return false end @no_proxy.scan(/([^:,]+)(?::(\d+))?/) do |host, port| if /(\A|\.)#{Regexp.quote(host)}\z/i =~ uri.host && (!port || uri.port == port.to_i) return true end end false end
[ show source ]
# File lib/facets/more/httpaccess.rb, line 367 def retry_connect(uri, query = nil) retry_number = 0 while retry_number < 10 res = yield(uri, query) if res.status == HTTP::Status::OK return res.content elsif HTTP::Status.redirect?(res.status) uri = @redirect_uri_callback.call(res) query = nil retry_number += 1 else raise RuntimeError.new("Unexpected response: #{res.header.inspect}") end end raise RuntimeError.new("Retry count exceeded.") end