Skip to content

Instantly share code, notes, and snippets.

@aportnov
Created May 13, 2009 13:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aportnov/111006 to your computer and use it in GitHub Desktop.
Save aportnov/111006 to your computer and use it in GitHub Desktop.
Ruby wrapper for Google App Engine URL Fetch service
require 'java'
module UrlFetch
module UF
import java.net.URL;
import java.net.URLEncoder;
import com.google.appengine.api.urlfetch.HTTPHeader
import com.google.appengine.api.urlfetch.HTTPMethod
import com.google.appengine.api.urlfetch.HTTPRequest
import com.google.appengine.api.urlfetch.HTTPResponse
import com.google.appengine.api.urlfetch.URLFetchService
import com.google.appengine.api.urlfetch.URLFetchServiceFactory
Service = URLFetchServiceFactory.getURLFetchService()
end
module InstanceMethods
def fetch_url(options = {})
self.class.fetch_url(options)
end
end
module ClassMethods
# = Fetch URL proxy
# === Accepted options:
# :url - request url
# :method - HTTP method ('get', 'post' ..)
# :headers - hash of request headers
# :params - request params. Only valid if the method is post
#
# === Response:
# Rack stype responce:
# [response_code, headers, body]
def fetch_url(options = {})
return nil unless (options[:url])
url = UF::URL.new(options[:url])
request = UF::HTTPRequest.new(url, UF::HTTPMethod.valueOf((options[:method] || 'get').upcase))
options[:headers].each{|name, value| request.addHeader(UF::HTTPHeader.new(name, value))} if options[:headers] && options[:headers].is_a?(Hash)
if options[:method] == 'post' && options[:params]
payload = options[:params].collect{|name, value| "#{UF::URLEncoder.encode(name, 'UTF-8')}=#{UF::URLEncoder.encode(value, 'UTF-8')}" }
request.setPayload(payload.to_java_bytes)
end
response = UF::Service.fetch(request)
[
response.getResponseCode,
response.getHeaders().inject({}){|hash, header| hash[header.name] = header.value; hash },
(String.from_java_bytes(response.getContent) if response.getContent)
]
rescue => e
[500, {}, e.to_s]
end
end
def self.included(base)
base.send :include, InstanceMethods
base.send :extend, ClassMethods
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment