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
Hashof headers that will be sent in the request. -
#response_handlers ⇒ Object
A
Hashof handlers for each class of HTTPResponse. -
#response_headers ⇒ Object
Hashof headers that were set in the response. -
#uri ⇒ Object
readonly
The
URIobject 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
HEADrequest. -
.options(uri) ⇒ Object
Make a simple
OPTIONSrequest. -
.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
TRACErequest.
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
getmethod 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
headmethod as an instance method. -
#initialize(uri) ⇒ SimpleHttp
constructor
SimpleHttp can either be used directly through the
getandpostclass methods or be instantiated, in case you need to to add custom behaviour to the requests. -
#options ⇒ Object
Call http
optionsmethod. -
#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
tracemethod.
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
URIor aString query-
the query part of the
get, may be aStringorHash
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 |