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 “www.example.com/index.html” sh = SimpleHttp uri sh.set_proxy “my.proxy”, “8080” sh.post => “query_data”
# POST using class methods. binaryData = getImage SimpleData.post binaryData, “image/png”
# GET requst with a custom request_header sh = SimpleHttp.new “www.example.com” sh.request_headers= ‘X-Special-Http-Header’=>‘my-value’ sh.get
Constant Summary collapse
- VERSION =
'0.1.3'- RESPONSE_HANDLERS =
{ Net::HTTPResponse => lambda { |request, response, http| response.each_header {|key, value| http.response_headers[key]=value } raise "#{response.to_s} : #{response.code} : #{http.uri}" }, Net::HTTPSuccess => lambda { |request, response, http| response.each_header {|key, value| http.response_headers[key]=value } #http.cookies += response.cookies if request.class == Net::HTTP::Head || request.class == Net::HTTP::Options return http.response_headers end return response.body }, 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
Returns the value of attribute follow_num_redirects.
-
#proxy_host ⇒ Object
Returns the value of attribute proxy_host.
-
#proxy_port ⇒ Object
Returns the value of attribute proxy_port.
-
#proxy_pwd ⇒ Object
Returns the value of attribute proxy_pwd.
-
#proxy_user ⇒ Object
Returns the value of attribute proxy_user.
-
#request_headers ⇒ Object
Returns the value of attribute request_headers.
-
#response_handlers ⇒ Object
Returns the value of attribute response_handlers.
-
#response_headers ⇒ Object
Returns the value of attribute response_headers.
-
#uri ⇒ Object
Returns the value of attribute uri.
Class Method Summary collapse
-
.get(uri, query = nil) ⇒ Object
Make a simple GET request to the provided URI.
- .head(uri, query = nil) ⇒ Object
- .options(uri) ⇒ Object
-
.post(uri, query = nil, content_type = 'application/x-www-form-urlencoded') ⇒ Object
Make a POST request to the provided URI.
- .trace(uri) ⇒ Object
Instance Method Summary collapse
-
#basic_authentication(usr, pwd) ⇒ Object
Provides facilities to perform http basic authentication.
-
#do_http(request) ⇒ Object
internal.
-
#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:. -
#handle_response(http_request, http_response) ⇒ Object
interal Takes a HTTPResponse (or subclass) and determines how to handle the response.
-
#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. -
#make_query(query) ⇒ Object
internal.
-
#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
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(“www.example.com”)) http = SimpleHttp.new “www.example.com” http = SimpleHttp.new “usr:[email protected]:1234”
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/simplehttp.rb', line 140 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={} =[] @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
Returns the value of attribute follow_num_redirects.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def follow_num_redirects @follow_num_redirects end |
#proxy_host ⇒ Object
Returns the value of attribute proxy_host.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def proxy_host @proxy_host end |
#proxy_port ⇒ Object
Returns the value of attribute proxy_port.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def proxy_port @proxy_port end |
#proxy_pwd ⇒ Object
Returns the value of attribute proxy_pwd.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def proxy_pwd @proxy_pwd end |
#proxy_user ⇒ Object
Returns the value of attribute proxy_user.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def proxy_user @proxy_user end |
#request_headers ⇒ Object
Returns the value of attribute request_headers.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def request_headers @request_headers end |
#response_handlers ⇒ Object
Returns the value of attribute response_handlers.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def response_handlers @response_handlers end |
#response_headers ⇒ Object
Returns the value of attribute response_headers.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def response_headers @response_headers end |
#uri ⇒ Object
Returns the value of attribute uri.
51 52 53 |
# File 'lib/simplehttp.rb', line 51 def uri @uri end |
Class Method Details
.get(uri, query = nil) ⇒ Object
Make a simple GET request to the provided URI.
Example: puts(SimpleHttp.get(“www.example.com”))
338 339 340 341 |
# File 'lib/simplehttp.rb', line 338 def self.get uri, query=nil http = SimpleHttp.new uri http.get query end |
.head(uri, query = nil) ⇒ Object
343 344 345 346 |
# File 'lib/simplehttp.rb', line 343 def self.head uri, query=nil http = SimpleHttp.new uri http.head query end |
.options(uri) ⇒ Object
348 349 350 351 |
# File 'lib/simplehttp.rb', line 348 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, you can post any sort of data, but will have to set the appriate content_type:
SimpleHttp.post(“www.example.com/”, binary_data, “img/png”)
368 369 370 371 |
# File 'lib/simplehttp.rb', line 368 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
353 354 355 356 |
# File 'lib/simplehttp.rb', line 353 def self.trace uri http = SimpleHttp.new uri http.trace end |
Instance Method Details
#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]/
176 177 178 179 180 |
# File 'lib/simplehttp.rb', line 176 def basic_authentication usr, pwd str = Base64.encode64("#{usr}:#{pwd}") str = "Basic #{str}" @request_headers["Authorization"]=str end |
#do_http(request) ⇒ Object
internal
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/simplehttp.rb', line 310 def do_http request response = nil http = Net::HTTP.new(@uri.host, @uri.port, @proxy_host, @proxy_port, @proxy_user, @proxy_pwd) http.use_ssl = @uri.scheme == 'https' # add custom request headers. @request_headers.each {|key,value| request[key]=value; } handle_response(request, http.request(request)); 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=“whatever” str = http.get
380 381 382 383 384 385 386 387 388 389 |
# File 'lib/simplehttp.rb', line 380 def get query = nil if (query = make_query query) @uri.query = @uri.query ? @uri.query+"&"+query : query end full_path = @uri.path + (@uri.query ? "?#{@uri.query}" : "") req = Net::HTTP::Get.new(full_path) # puts Net::HTTP::Proxy(@proxy_host, @proxy_port, @proxy_user, @proxy_pwd).get(@uri) do_http req end |
#handle_response(http_request, http_response) ⇒ Object
interal 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.
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/simplehttp.rb', line 287 def handle_response http_request, http_response raise "Not a Net::HTTPResponse" unless http_response.is_a? Net::HTTPResponse c = http_response.class while c!=Object # the response_handlers hash contains a handler # for the specific response class. if @response_handlers[c] #STDERR.puts "!#{http_response.class}" #STDERR.puts "!#{@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 |
#head(query = nil) ⇒ Object
Call the head method as an instance method.
393 394 395 396 397 398 399 400 401 402 |
# File 'lib/simplehttp.rb', line 393 def head query = nil if (query = make_query query) @uri.query = @uri.query ? @uri.query+"&"+query : query end full_path = @uri.path + (@uri.query ? "?#{@uri.query}" : "") req = Net::HTTP::Head.new(full_path) # puts Net::HTTP::Proxy(@proxy_host, @proxy_port, @proxy_user, @proxy_pwd).get(@uri) do_http req end |
#make_query(query) ⇒ Object
internal
327 328 329 330 331 332 |
# File 'lib/simplehttp.rb', line 327 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 |
#options ⇒ Object
Call http options method. Returns the response
405 406 407 408 409 |
# File 'lib/simplehttp.rb', line 405 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.
426 427 428 429 430 431 432 433 434 |
# File 'lib/simplehttp.rb', line 426 def post query=nil, content_type='application/x-www-form-urlencoded' req = Net::HTTP::Post.new(@uri.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 : return the body of the response HTTPRedirection : follow the redirection until success Others : raise an exception
clazz is the subclass of HTTPResponse (or HTTPResponse in case you want to define “default” behaviour) that you are registering the handler for.
block is the handler itself, if a response of the appropriate class is received, block is called with three parameters: the the 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 }
212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/simplehttp.rb', line 212 def register_response_handler clazz, &block c = clazz while c != Object # completely unnecessary sanity check to make sure parameter # `clazz` is in fact a HTTPResponse ... if c == Net::HTTPResponse @response_handlers[clazz]=block return end c = c.superclass end raise "Trying to register a response handler for non-response class: #{clazz}" end |
#set_proxy(proxy, port = nil, user = nil, pwd = nil) ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/simplehttp.rb', line 248 def set_proxy proxy, port=nil, user=nil, pwd=nil if !proxy @proxy_host=@proxy_port=@proxy_user=@proxy_pwd=nil return end if proxy.class == String if !port && !user && !pwd proxy = URI.parse(proxy) else @proxy_host= host @proxy_port= port @proxy_user= user @proxy_pwd = pwd end end if proxy.class == URI::HTTP @proxy_host= proxy.host @proxy_port= proxy.port @proxy_user= proxy.user @proxy_pwd = proxy.password end end |
#trace ⇒ Object
411 412 413 414 415 |
# File 'lib/simplehttp.rb', line 411 def trace # payload? req = Net::HTTP::Trace.new(@uri.path) do_http req end |