Module: Koala::NetHTTPService

Defined in:
lib/koala/http_services.rb

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object

this service uses Net::HTTP to send requests to the graph



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/koala/http_services.rb', line 13

def self.included(base)
  base.class_eval do
    require 'net/http' unless defined?(Net::HTTP)
    require 'net/https'
    require 'net/http_multipart_post'

    def self.make_request(path, args, verb, options = {})
      # We translate args to a valid query string. If post is specified,
      # we send a POST request to the given path with the given arguments.

      # if the verb isn't get or post, send it as a post argument
      args.merge!({:method => verb}) && verb = "post" if verb != "get" && verb != "post"

      server = options[:rest_api] ? Facebook::REST_SERVER : Facebook::GRAPH_SERVER
      http = Net::HTTP.new(server, 443)
      http.use_ssl = true
      # we turn off certificate validation to avoid the 
      # "warning: peer certificate won't be verified in this SSL session" warning
      # not sure if this is the right way to handle it
      # see http://redcorundum.blogspot.com/2008/03/ssl-certificates-and-nethttps.html
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      result = http.start { |http|
        response, body = if (verb == "post")
          if has_multipart_files?(args)
            req = Net::HTTP::MultipartPost.new(URI.parse("https://#{server}/#{path}"), args)
            req.post
          else
            http.post(path, encode_params(args))
          end
        else 
          http.get("#{path}?#{encode_params(args)}")
        end
        Koala::Response.new(response.code.to_i, body, response)
      }
    end

    protected
    def self.has_multipart_files?(param_hash)
      (param_hash || {}).values.select {|x| x.is_a?(Net::HTTP::MultipartPostFile)}.any?
    end
    
    def self.encode_params(param_hash)
      # TODO investigating whether a built-in method handles this
      # if no hash (e.g. no auth token) return empty string
      ((param_hash || {}).collect do |key_and_value| 
        key_and_value[1] = key_and_value[1].to_json if key_and_value[1].class != String
        "#{key_and_value[0].to_s}=#{CGI.escape key_and_value[1]}"
      end).join("&")
    end
  end
end