Class: SimpleHttp

Inherits:
Object show all
Defined in:
lib/ramaze/spec/helper/simple_http.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.1'
RESPONSE_HANDLERS =
{
  Net::HTTPResponse => lambda { |request, response, http|
    response.each_header {|key, value|
      http.response_headers[key]=value
    }
    raise response.to_s
  },
  Net::HTTPSuccess => lambda { |request, response, http|
    response.each_header {|key, value|
      http.response_headers[key]=value
    }
    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.
    sh = SimpleHttp.new response['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

     # 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 of HEAD, so we complain in case
    # we get them in response to a POST request. (Or
    # anything other than GET, for that matter.)

     case request
     when Net::HTTP::Get
       sh.get
     when Net::HTTP::Post
       sh.post
    else
      raise "Not a valid HTTP method for redirection: #{request.class}"
    end
  }

}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

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

Parameters:

  • may

    be a URI or a String.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/ramaze/spec/helper/simple_http.rb', line 169

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=3

  if @uri.user
    basic_authentication @uri.user, @uri.password
  end

end

Instance Attribute Details

#follow_num_redirectsObject

Returns the value of attribute follow_num_redirects.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

def follow_num_redirects
  @follow_num_redirects
end

#proxy_hostObject

Returns the value of attribute proxy_host.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

def proxy_host
  @proxy_host
end

#proxy_portObject

Returns the value of attribute proxy_port.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

def proxy_port
  @proxy_port
end

#proxy_pwdObject

Returns the value of attribute proxy_pwd.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

def proxy_pwd
  @proxy_pwd
end

#proxy_userObject

Returns the value of attribute proxy_user.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

def proxy_user
  @proxy_user
end

#request_headersObject

Returns the value of attribute request_headers.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

def request_headers
  @request_headers
end

#response_handlersObject

Returns the value of attribute response_handlers.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

def response_handlers
  @response_handlers
end

#response_headersObject

Returns the value of attribute response_headers.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

def response_headers
  @response_headers
end

#uriObject

Returns the value of attribute uri.



106
107
108
# File 'lib/ramaze/spec/helper/simple_http.rb', line 106

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”))



364
365
366
367
# File 'lib/ramaze/spec/helper/simple_http.rb', line 364

def self.get uri, query=nil
  http = SimpleHttp.new uri
  http.get query
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”)



379
380
381
382
# File 'lib/ramaze/spec/helper/simple_http.rb', line 379

def self.post uri, query=nil, content_type='application/x-www-form-urlencoded'
  http = SimpleHttp.new uri
  http.post query, content_type
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]/



204
205
206
207
208
# File 'lib/ramaze/spec/helper/simple_http.rb', line 204

def basic_authentication usr, pwd
  str = ["#{usr}:#{pwd}"].pack("*m")
  str = "Basic #{str}"
  @request_headers["Authorization"]=str
end

#do_http(request) ⇒ Object

internal



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/ramaze/spec/helper/simple_http.rb', line 336

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.comhttp.request_headers=“whatever” str = http.get



391
392
393
394
395
396
397
398
399
400
# File 'lib/ramaze/spec/helper/simple_http.rb', line 391

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.



315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/ramaze/spec/helper/simple_http.rb', line 315

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]
      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



353
354
355
356
357
358
# File 'lib/ramaze/spec/helper/simple_http.rb', line 353

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

#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.



411
412
413
414
415
416
417
418
419
# File 'lib/ramaze/spec/helper/simple_http.rb', line 411

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 }



240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/ramaze/spec/helper/simple_http.rb', line 240

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



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/ramaze/spec/helper/simple_http.rb', line 276

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