Class: HttpSession
- Inherits:
-
Object
- Object
- HttpSession
- Defined in:
- lib/http_session.rb
Constant Summary collapse
- @@sessions =
place to store references to all currently-known session instances, for singleton method usage
{}
Instance Attribute Summary collapse
-
#cookies ⇒ Object
storage for cookies, for instance method usage.
-
#handle ⇒ Object
storage for open session handle, for instance method usage.
Class Method Summary collapse
-
.exists?(host, use_ssl = false, port = nil) ⇒ Boolean
check if a session exists yet ot not.
-
.get(host, use_ssl = false, port = nil) ⇒ Object
get the session for the given host and port, nil if there isn’t one yet.
-
.get_request_url(url, headers = {}) ⇒ Object
shortcut for parsing a full url and performing simple GET requests returns Net::HTTPResponse, or raises Timeout::Error, SystemCallError, OpenSSL::SSL::SSLError, EOFError, Net::ProtocolError.
-
.key(host, use_ssl, port) ⇒ Object
just our own internal session key…
-
.open_timeout=(v) ⇒ Object
it really sux that plain ruby doesn’t have cattr_accessor so we have to do 30 lines of repeating ourselves!.
-
.port_or_default(port, use_ssl) ⇒ Object
return the given port, or defaults for ssl setting if it’s nil.
-
.post_request_url(url, params, headers = {}) ⇒ Object
shortcut for parsing a full url and performing simple POST requests returns Net::HTTPResponse, or raises Timeout::Error, SystemCallError, OpenSSL::SSL::SSLError, EOFError, Net::ProtocolError.
- .read_timeout=(v) ⇒ Object
- .redirect_limit=(v) ⇒ Object
- .retry_limit=(v) ⇒ Object
- .ssl_ca_file=(v) ⇒ Object
- .ssl_timeout=(v) ⇒ Object
- .ssl_verify_depth=(v) ⇒ Object
- .ssl_verify_mode=(v) ⇒ Object
-
.use(host, use_ssl = false, port = nil) ⇒ Object
get the session for the given host and port, creating a new one if it doesn’t exist.
Instance Method Summary collapse
-
#add_cookies(response) ⇒ Object
store the cookies from the given response into the session (ignores all host/path/expires/secure/etc cookie options!).
-
#close ⇒ Object
done with this session, close and reset it but it still exists in the session storage in a dormant/empty state, so next request would easily reopen it.
-
#cookie_string ⇒ Object
return all current cookies in a comma-delimited name=value string format.
-
#cookies? ⇒ Boolean
check if a session has any cookies or not.
-
#delete ⇒ Object
delete session from session storage (you should probably call close on it too, and set all references to nil so it gets garbage collected).
-
#initialize(host, use_ssl, port) ⇒ HttpSession
constructor
don’t use new() directly, use singleton get() or use() instead.
-
#request(uri = '/', headers = {}, type = :get, post_params = {}, redirect_limit = @@redirect_limit, retry_limit = @@retry_limit) ⇒ Object
internally handle GET and POST requests (recursively for redirects and retries) returns Net::HTTPResponse, or raises Timeout::Error, SystemCallError, OpenSSL::SSL::SSLError, EOFError, Net::ProtocolError.
Constructor Details
#initialize(host, use_ssl, port) ⇒ HttpSession
don’t use new() directly, use singleton get() or use() instead
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/http_session.rb', line 124 def initialize(host, use_ssl, port) self.handle = Net::HTTP.new(host, port) self.handle.open_timeout = @@open_timeout # seems to have no effect? self.handle.read_timeout = @@read_timeout # seems to have an effect on establishing tcp connection?? self.handle.close_on_empty_response = true # seems to have no effect? if use_ssl self.handle.use_ssl = true # respond_to? check is a ruby-1.9.1-p378 (+/-?) bug workaround self.handle.ssl_timeout = @@ssl_timeout if OpenSSL::SSL::SSLContext.new.respond_to?(:ssl_timeout=) self.handle.verify_mode = @@ssl_verify_mode self.handle.ca_file = @@ssl_ca_file self.handle.verify_depth = @@ssl_verify_depth end self. = {} end |
Instance Attribute Details
#cookies ⇒ Object
storage for cookies, for instance method usage
185 186 187 |
# File 'lib/http_session.rb', line 185 def @cookies end |
#handle ⇒ Object
storage for open session handle, for instance method usage
121 122 123 |
# File 'lib/http_session.rb', line 121 def handle @handle end |
Class Method Details
.exists?(host, use_ssl = false, port = nil) ⇒ Boolean
check if a session exists yet ot not
146 147 148 |
# File 'lib/http_session.rb', line 146 def self.exists?(host, use_ssl=false, port=nil) @@sessions.has_key?(key(host, use_ssl, port)) end |
.get(host, use_ssl = false, port = nil) ⇒ Object
get the session for the given host and port, nil if there isn’t one yet
151 152 153 |
# File 'lib/http_session.rb', line 151 def self.get(host, use_ssl=false, port=nil) @@sessions[key(host, use_ssl, port)] end |
.get_request_url(url, headers = {}) ⇒ Object
shortcut for parsing a full url and performing simple GET requests returns Net::HTTPResponse, or raises Timeout::Error, SystemCallError, OpenSSL::SSL::SSLError, EOFError, Net::ProtocolError
58 59 60 61 |
# File 'lib/http_session.rb', line 58 def self.get_request_url(url, headers={}) parsed = URI.parse(url) use(parsed.host, parsed.scheme == 'https', parsed.port).request(parsed.path + (parsed.query.nil? ? '' : "?#{parsed.query}"), headers) end |
.key(host, use_ssl, port) ⇒ Object
just our own internal session key… (it looks like: “scheme://host:port”)
141 142 143 |
# File 'lib/http_session.rb', line 141 def self.key(host, use_ssl, port) "#{use_ssl ? 'https' : 'http'}://#{host}:#{port_or_default(port, use_ssl)}" end |
.open_timeout=(v) ⇒ Object
it really sux that plain ruby doesn’t have cattr_accessor so we have to do 30 lines of repeating ourselves!
8 9 10 |
# File 'lib/http_session.rb', line 8 def self.open_timeout=(v) @@open_timeout = v end |
.port_or_default(port, use_ssl) ⇒ Object
return the given port, or defaults for ssl setting if it’s nil
175 176 177 |
# File 'lib/http_session.rb', line 175 def self.port_or_default(port, use_ssl) port.nil? ? (use_ssl ? Net::HTTP.https_default_port : Net::HTTP.http_default_port) : port end |
.post_request_url(url, params, headers = {}) ⇒ Object
shortcut for parsing a full url and performing simple POST requests returns Net::HTTPResponse, or raises Timeout::Error, SystemCallError, OpenSSL::SSL::SSLError, EOFError, Net::ProtocolError
65 66 67 68 |
# File 'lib/http_session.rb', line 65 def self.post_request_url(url, params, headers={}) parsed = URI.parse(url) use(parsed.host, parsed.scheme == 'https', parsed.port).request(parsed.path + (parsed.query.nil? ? '' : "?#{parsed.query}"), headers, :post, params) end |
.read_timeout=(v) ⇒ Object
11 12 13 |
# File 'lib/http_session.rb', line 11 def self.read_timeout=(v) @@read_timeout = v end |
.redirect_limit=(v) ⇒ Object
14 15 16 |
# File 'lib/http_session.rb', line 14 def self.redirect_limit=(v) @@redirect_limit = v end |
.retry_limit=(v) ⇒ Object
17 18 19 |
# File 'lib/http_session.rb', line 17 def self.retry_limit=(v) @@retry_limit = v end |
.ssl_ca_file=(v) ⇒ Object
26 27 28 |
# File 'lib/http_session.rb', line 26 def self.ssl_ca_file=(v) @@ssl_ca_file = v end |
.ssl_timeout=(v) ⇒ Object
20 21 22 |
# File 'lib/http_session.rb', line 20 def self.ssl_timeout=(v) @@ssl_timeout = v end |
.ssl_verify_depth=(v) ⇒ Object
29 30 31 |
# File 'lib/http_session.rb', line 29 def self.ssl_verify_depth=(v) @@ssl_verify_depth = v end |
.ssl_verify_mode=(v) ⇒ Object
23 24 25 |
# File 'lib/http_session.rb', line 23 def self.ssl_verify_mode=(v) @@ssl_verify_mode = v end |
.use(host, use_ssl = false, port = nil) ⇒ Object
get the session for the given host and port, creating a new one if it doesn’t exist
156 157 158 159 |
# File 'lib/http_session.rb', line 156 def self.use(host, use_ssl=false, port=nil) key = key(host, use_ssl, port) @@sessions.has_key?(key) ? @@sessions[key] : (@@sessions[key] = new(host, use_ssl, port_or_default(port, use_ssl))) end |
Instance Method Details
#add_cookies(response) ⇒ Object
store the cookies from the given response into the session (ignores all host/path/expires/secure/etc cookie options!)
198 199 200 201 202 203 204 |
# File 'lib/http_session.rb', line 198 def (response) return unless response.key?('set-cookie') response.get_fields('set-cookie').each do || (key, val) = .split('; ')[0].split('=', 2) [key] = val end end |
#close ⇒ Object
done with this session, close and reset it but it still exists in the session storage in a dormant/empty state, so next request would easily reopen it
163 164 165 166 |
# File 'lib/http_session.rb', line 163 def close handle.finish if handle.started? self. = {} end |
#cookie_string ⇒ Object
return all current cookies in a comma-delimited name=value string format
193 194 195 |
# File 'lib/http_session.rb', line 193 def .collect { |name, val| "#{name}=#{val}" }.join(', ') end |
#cookies? ⇒ Boolean
check if a session has any cookies or not
188 189 190 |
# File 'lib/http_session.rb', line 188 def .length > 0 end |
#delete ⇒ Object
delete session from session storage (you should probably call close on it too, and set all references to nil so it gets garbage collected)
169 170 171 172 |
# File 'lib/http_session.rb', line 169 def delete key = self.class.key(handle.address, handle.use_ssl?, handle.port) @@sessions.delete(key) if @@sessions.has_key?(key) end |
#request(uri = '/', headers = {}, type = :get, post_params = {}, redirect_limit = @@redirect_limit, retry_limit = @@retry_limit) ⇒ Object
internally handle GET and POST requests (recursively for redirects and retries) returns Net::HTTPResponse, or raises Timeout::Error, SystemCallError, OpenSSL::SSL::SSLError, EOFError, Net::ProtocolError
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/http_session.rb', line 72 def request(uri='/', headers={}, type=:get, post_params={}, redirect_limit=@@redirect_limit, retry_limit=@@retry_limit) req = case type when :get Net::HTTP::Get.new(uri) when :post Net::HTTP::Post.new(uri) else raise ArgumentError, "bad type: #{type}" end headers.each { |k, v| req[k] = v } unless headers.empty? req['Cookie'] = if req.set_form_data(post_params) if type == :post begin handle.start unless handle.started? # may raise Timeout::Error or OpenSSL::SSL::SSLError response = handle.request(req) # may raise Errno::* (subclasses of SystemCallError) or EOFError rescue Timeout::Error, SystemCallError, EOFError handle.finish if handle.started? raise if retry_limit == 0 request(uri, headers, type, post_params, redirect_limit, retry_limit - 1) else response if response.kind_of?(Net::HTTPRedirection) raise Net::HTTPError.new('Redirection limit exceeded', response) if redirect_limit == 0 loc = URI.parse(response['location']) if loc.scheme && loc.host && loc.port self.class.use(loc.host, loc.scheme == 'https', loc.port).request(loc.path + (loc.query.nil? ? '' : "?#{loc.query}"), headers, :get, {}, redirect_limit - 1) else # only really bad web servers would ever send this... since it's not technically a valid value! request(loc.path + (loc.query.nil? ? '' : "?#{loc.query}"), headers, :get, {}, redirect_limit - 1) end else response.error! unless response.kind_of?(Net::HTTPOK) # raises Net::HTTP*Error/Exception (subclasses of Net::ProtocolError) raise Net::HTTPError.new('Document has no body', response) if response.body.nil? || response.body == '' response end end end |