Class: SimpleHttp
- Inherits:
-
Object
- Object
- SimpleHttp
- Defined in:
- lib/simplehttp.rb
Overview
Wrapper around ruby’s standard net/http classes. Currently, only GET and POST https methods are supported. ‘SimpleHttp` provides class methods `get` and `post` to handle basic functionality. In case more complicated requests need to be made or default settings need to be overriden, it’s possible to instantiate ‘SimpleHttp` and use instance methods `get` and `put`.
Features:
-
Handles Redirects automatically
-
Proxy used transparently if http_proxy environment variable is set.
-
SSL handled automatically
-
fault tolerant uri, e.g. all of these would work: “www.example.com”, “www.example.com/”, “www.example.com”
Some usage examples:
# plain GET (using class methods)
SimpleHttp.get "www.example.com"
# POST using the instance methods
uri = URI.parse "https://www.example.com/index.html"
sh = SimpleHttp uri
sh.set_proxy "my.proxy", "8080"
sh.post {"query" => "query_data"}
# POST using class methods.
binaryData = getImage
SimpleData.post binaryData, "image/png"
# GET requst with a custom request_header
sh = SimpleHttp.new "http://www.example.com"
sh.request_headers= {'X-Special-Http-Header'=>'my-value'}
sh.get
Constant Summary collapse
- VERSION =
'0.1.5'
- RESPONSE_HANDLERS =
{ Net::HTTPResponse => lambda { |request, response, http| http._update_response_headers(response) raise "#{response.to_s} : #{response.code} : #{http.uri}" }, Net::HTTPSuccess => lambda { |request, response, http| http._update_response_headers(response) #http.cookies += response.cookies case request when Net::HTTP::Head, Net::HTTP::Options http.response_headers else response.body end }, Net::HTTPRedirection => lambda { |request, response, http| raise "too many redirects!" unless http.follow_num_redirects > 0 # create a new SimpleHttp for the location # refered to decreasing the remaining redirects # by one. if (location = response['location']) !~ /^https?:\/\// new_location = "#{http.uri.scheme}://#{http.uri.host}" if location =~ /^\// new_location += location else new_location += "/#{http.uri.path}/#{location}" end location = new_location end sh = SimpleHttp.new location #STDERR.puts location sh.follow_num_redirects = http.follow_num_redirects-1 # copy the response handlers used in the current # request in case they were non standard. sh.response_handlers = http.response_handlers # copy the request headers sh.request_headers=http.request_headers sh.response_headers=http.response_headers #sh.cookies+=http.cookies # copy host and port sh.uri.host = http.uri.host sh.uri.port = http.uri.port # HTTP doesn't permit redirects for methods other than # GET or HEAD. The exception is 303 redirects, which # should automatically follow the redirect URI using a # GET method regardless of the initial method. For # other classes of redirection, the client is required # to prompt the user before redirection occurs. Because # that's not a feasible action for this library, all # 3xx redirect URIs are followed using a GET method. # # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html case request when Net::HTTP::Get, Net::HTTP::Head, Net::HTTP::Options sh.get when Net::HTTP::Post sh.request_headers['content-length']=nil sh.get else raise "Not a valid HTTP method for redirection: #{request.class}" end } }
Instance Attribute Summary collapse
-
#follow_num_redirects ⇒ Object
The number of redirects we should follow.
-
#proxy_host ⇒ Object
Host component of proxy uri.
-
#proxy_port ⇒ Object
Port component of proxy uri.
-
#proxy_pwd ⇒ Object
Proxy Password.
-
#proxy_user ⇒ Object
Proxy User.
-
#request_headers ⇒ Object
Hash
of headers that will be sent in the request. -
#response_handlers ⇒ Object
A
Hash
of handlers for each class of HTTPResponse. -
#response_headers ⇒ Object
Hash
of headers that were set in the response. -
#uri ⇒ Object
readonly
The
URI
object to connect to.
Class Method Summary collapse
-
.get(uri, query = nil) ⇒ Object
Make a simple GET request to the provided URI.
-
.head(uri, query = nil) ⇒ Object
Make a simple
HEAD
request. -
.options(uri) ⇒ Object
Make a simple
OPTIONS
request. -
.post(uri, query = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Make a POST request to the provided URI.
-
.trace(uri) ⇒ Object
Make a simple
TRACE
request.
Instance Method Summary collapse
-
#_do_http(request) ⇒ Object
Internal.
- #_handle_path(query = nil) ⇒ Object
-
#_handle_response(http_request, http_response) ⇒ Object
Internal Takes a HTTPResponse (or subclass) and determines how to handle the response.
-
#_make_query(query) ⇒ Object
Internal.
-
#_update_response_headers(http_response) ⇒ Object
Internal Used in the response handler to set the value of the response header fields.
-
#basic_authentication(usr, pwd) ⇒ Object
Provides facilities to perform http basic authentication.
-
#get(query = nil) ⇒ Object
Call the
get
method as an instance method if you need to modify the default behaviour of the library, or set special headers:. -
#head(query = nil) ⇒ Object
Call the
head
method as an instance method. -
#initialize(uri) ⇒ SimpleHttp
constructor
SimpleHttp can either be used directly through the
get
andpost
class methods or be instantiated, in case you need to to add custom behaviour to the requests. -
#options ⇒ Object
Call http
options
method. -
#post(query = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Post the query data to the url.
-
#register_response_handler(clazz, &block) ⇒ Object
This method can be used to register response handlers for specific http responses in case you need to override the default behaviour.
- #set_proxy(proxy, port = nil, user = nil, pwd = nil) ⇒ Object
-
#trace ⇒ Object
Call http
trace
method.
Constructor Details
#initialize(uri) ⇒ SimpleHttp
SimpleHttp can either be used directly through the get
and post
class methods or be instantiated, in case you need to to add custom behaviour to the requests.
Example:
http = SimpleHttp.new(URI.parse("http://www.example.com"))
http = SimpleHttp.new "www.example.com"
http = SimpleHttp.new "http://usr:[email protected]:1234"
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/simplehttp.rb', line 156 def initialize uri set_proxy ENV['http_proxy'] if ENV['http_proxy'] if uri.class == String unless uri =~ /^https?:\/\// uri = "http://#{uri}" end uri = URI.parse uri end @uri = uri if !@uri.path || "" == @uri.path.strip @uri.path="/" end @request_headers={} @response_headers={} @cookies=[] @response_handlers=RESPONSE_HANDLERS.clone @follow_num_redirects=5 if @uri.user basic_authentication @uri.user, @uri.password end end |
Instance Attribute Details
#follow_num_redirects ⇒ Object
The number of redirects we should follow. Default 5. An exception gets raised after the fifth redirect.
69 70 71 |
# File 'lib/simplehttp.rb', line 69 def follow_num_redirects @follow_num_redirects end |
#proxy_host ⇒ Object
Host component of proxy uri
52 53 54 |
# File 'lib/simplehttp.rb', line 52 def proxy_host @proxy_host end |
#proxy_port ⇒ Object
Port component of proxy uri
54 55 56 |
# File 'lib/simplehttp.rb', line 54 def proxy_port @proxy_port end |
#proxy_pwd ⇒ Object
Proxy Password
58 59 60 |
# File 'lib/simplehttp.rb', line 58 def proxy_pwd @proxy_pwd end |
#proxy_user ⇒ Object
Proxy User
56 57 58 |
# File 'lib/simplehttp.rb', line 56 def proxy_user @proxy_user end |
#request_headers ⇒ Object
Hash
of headers that will be sent in the request.
62 63 64 |
# File 'lib/simplehttp.rb', line 62 def request_headers @request_headers end |
#response_handlers ⇒ Object
A Hash
of handlers for each class of HTTPResponse.
66 67 68 |
# File 'lib/simplehttp.rb', line 66 def response_handlers @response_handlers end |
#response_headers ⇒ Object
Hash
of headers that were set in the response.
64 65 66 |
# File 'lib/simplehttp.rb', line 64 def response_headers @response_headers end |
#uri ⇒ Object (readonly)
The URI
object to connect to
60 61 62 |
# File 'lib/simplehttp.rb', line 60 def uri @uri end |
Class Method Details
.get(uri, query = nil) ⇒ Object
Make a simple GET request to the provided URI.
Parameter
uri
-
the uri to connect to, may be a
URI
or aString
query
-
the query part of the
get
, may be aString
orHash
Usage:
puts(SimpleHttp.get("www.example.com"))
puts(SimpleHttp.get("www.example.com", "param"=>"value")
363 364 365 366 |
# File 'lib/simplehttp.rb', line 363 def self.get uri, query=nil http = SimpleHttp.new uri http.get query end |
.head(uri, query = nil) ⇒ Object
Make a simple HEAD
request
Parameter
see get
372 373 374 375 |
# File 'lib/simplehttp.rb', line 372 def self.head uri, query=nil http = SimpleHttp.new uri http.head query end |
.options(uri) ⇒ Object
Make a simple OPTIONS
request
378 379 380 381 |
# File 'lib/simplehttp.rb', line 378 def self. uri http = SimpleHttp.new uri http. end |
.post(uri, query = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Make a POST request to the provided URI.
Example:
puts(SimpleHttp.post("www.example.com", "query"=>"my_query"))
Alternatively, to post arbitrary data, all you need to do is set the appriate content_type
:
SimpleHttp.post("http://www.example.com/", binary_data, "img/png")
399 400 401 402 |
# File 'lib/simplehttp.rb', line 399 def self.post uri, query=nil, content_type='application/x-www-form-urlencoded' http = SimpleHttp.new uri http.post query, content_type end |
.trace(uri) ⇒ Object
Make a simple TRACE
request
384 385 386 387 |
# File 'lib/simplehttp.rb', line 384 def self.trace uri http = SimpleHttp.new uri http.trace end |
Instance Method Details
#_do_http(request) ⇒ Object
Internal
Parameter
request
the Net::HTTPRequest
to process.
329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'lib/simplehttp.rb', line 329 def _do_http request http = Net::HTTP.new(@uri.host, @uri.port, @proxy_host, @proxy_port, @proxy_user, @proxy_pwd) http.use_ssl = @uri.scheme == 'https' request.basic_auth(@basic_auth[0], @basic_auth[1]) if @basic_auth # add custom request headers. @request_headers.each {|key,value| request[key]=value; } response = http.request(request) _handle_response(request, response); end |
#_handle_path(query = nil) ⇒ Object
463 464 465 466 467 468 |
# File 'lib/simplehttp.rb', line 463 def _handle_path query=nil if (query = _make_query query) @uri.query = @uri.query ? @uri.query+"&"+query : query end path = @uri.query ? "#{uri.path}?#{@uri.query}" : @uri.path end |
#_handle_response(http_request, http_response) ⇒ Object
Internal
Takes a HTTPResponse (or subclass) and determines how to handle the response. Default behaviour is:
HTTPSuccess : return the body of the response
HTTPRedirection : follow the redirect until success.
default : raise the HTTPResponse.
the default behaviour can be overidden by registering a response handler using the ‘register_response_handler` method.
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/simplehttp.rb', line 304 def _handle_response http_request, http_response raise "Not a Net::HTTPResponse" unless http_response.is_a? Net::HTTPResponse c = http_response.class # Go up the inheritance chain to find the most specific handler # for the class of response we received. while c!=Object # the response_handlers hash contains a handler # for the specific response class. if @response_handlers[c] return @response_handlers[c].call(http_request, http_response, self) end c=c.superclass end # if we reached this place, no handler was registered # for this response. default is to return the response. return http_response end |
#_make_query(query) ⇒ Object
Internal
345 346 347 348 349 350 |
# File 'lib/simplehttp.rb', line 345 def _make_query query return query unless query && query.class == Hash query.inject([]) do |s, (key, value)| s << CGI::escape(key) + "=" + CGI::escape(value) end.join('&') end |
#_update_response_headers(http_response) ⇒ Object
Internal
Used in the response handler to set the value of the response header fields.
473 474 475 476 477 |
# File 'lib/simplehttp.rb', line 473 def _update_response_headers http_response http_response.each_header {|key, value| self.response_headers[key]=value } end |
#basic_authentication(usr, pwd) ⇒ Object
Provides facilities to perform http basic authentication. You don’t need to provide usr
and pwd
if they are already included in the uri, i.e. user:[email protected]/
Usage:
sh = SimpleHttp.new "www.example.com/password_protected_resource"
sh.basic_authentication "user_name", "secret_password"
sh.get
194 195 196 |
# File 'lib/simplehttp.rb', line 194 def basic_authentication usr, pwd @basic_auth = [usr, pwd] end |
#get(query = nil) ⇒ Object
Call the get
method as an instance method if you need to modify the default behaviour of the library, or set special headers:
http = SimpleHttp.new "www.example.com"
http.request_headers["X-Special"]="whatever"
str = http.get
411 412 413 414 415 |
# File 'lib/simplehttp.rb', line 411 def get query = nil req = Net::HTTP::Get.new( _handle_path(query) ) # puts Net::HTTP::Proxy(@proxy_host, @proxy_port, @proxy_user, @proxy_pwd).get(@uri) _do_http req end |
#head(query = nil) ⇒ Object
Call the head
method as an instance method. see head
420 421 422 423 424 |
# File 'lib/simplehttp.rb', line 420 def head query = nil req = Net::HTTP::Head.new( _handle_path(query) ) # puts Net::HTTP::Proxy(@proxy_host, @proxy_port, @proxy_user, @proxy_pwd).get(@uri) _do_http req end |
#options ⇒ Object
Call http options
method. Returns the response see options
428 429 430 431 432 |
# File 'lib/simplehttp.rb', line 428 def # we don't support sending a payload in options' body. req = Net::HTTP::Options.new(@uri.path) _do_http req end |
#post(query = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Post the query data to the url.
The body of the request remains empty if query=nil.
In case +query+ is a +Hash+, it's assumed that we are
sending a form.
In case +query+ is a +String+, it's also assumed that a
form is being sent, UNLESS the +content_type+ parameter
is set.
454 455 456 457 458 459 460 461 |
# File 'lib/simplehttp.rb', line 454 def post query=nil, content_type='application/x-www-form-urlencoded' req = Net::HTTP::Post.new( _handle_path() ) req.body= _make_query query if query req.content_type=content_type if query req.content_length=query ? req.body.length : 0 _do_http req end |
#register_response_handler(clazz, &block) ⇒ Object
This method can be used to register response handlers for specific http responses in case you need to override the default behaviour. Defaults are:
- HTTPSuccess (200-206)
-
return the body of the response
- HTTPRedirection (300-307)
-
follow the redirection until success
- Others
-
raise an exception
Parameters:
clazz
is the subclass of Net::HTTPResponse
(or HTTPResponse
in case you want to define “default” behaviour) that you are registering the handler for. E.g. to register a handler for a HTTP 303 response, clazz
needs to be HTTPSeeOther
.
block
is the handler itself. When a response of the appropriate class is received by the library, block
is called with three parameters: the ‘raw’ Net::HTTPRequest
, the actual HTTPResponse
object that was received and a reference to the instance of SimpleHttp
that is executing the call.
Example:
# to override the default action of following a HTTP
# redirect, you could register the folllowing handler:
sh = SimpleHttp "www.example.com"
sh.register_response_handler Net::HTTPRedirection {|request, response, shttp|
response['location']
}
231 232 233 234 235 236 237 238 239 |
# File 'lib/simplehttp.rb', line 231 def register_response_handler clazz, &block # completely unnecessary sanity check to make sure parameter # `clazz` is in fact a HTTPResponse ... unless clazz.ancestors.include? Net::HTTPResponse raise "Trying to register a response handler for non-response class: #{clazz}" end @response_handlers[clazz]=block end |
#set_proxy(proxy, port = nil, user = nil, pwd = nil) ⇒ Object
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/simplehttp.rb', line 265 def set_proxy proxy, port=nil, user=nil, pwd=nil if !proxy @proxy_host=@proxy_port=@proxy_user=@proxy_pwd=nil return end if String === proxy if !port && !user && !pwd proxy = URI.parse(proxy) else @proxy_host= host @proxy_port= port @proxy_user= user @proxy_pwd = pwd end end if URI::HTTP === proxy @proxy_host= proxy.host @proxy_port= proxy.port @proxy_user= proxy.user @proxy_pwd = proxy.password end end |
#trace ⇒ Object
Call http trace
method. Returns the response see trace
436 437 438 439 440 |
# File 'lib/simplehttp.rb', line 436 def trace # payload? req = Net::HTTP::Trace.new(@uri.path) _do_http req end |