Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

making parse-ruby-client available for jruby #107

Merged
merged 1 commit into from

2 participants

ANDO Yasushi Alan deLevie
ANDO Yasushi

The current version of parse-ruby-client can not be used for JRuby because it is using a c-extension included in the patron library. I separated http_client from the parse client class and made the Net::HTTP the default http client for JRuby. I'm glad if you kindly accept this patch. Thanks.

Alan deLevie adelevie merged commit 68a2c98 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 7, 2013
  1. ANDO Yasushi
This page is out of date. Refresh to see the latest.
5 Gemfile
View
@@ -11,5 +11,8 @@ group :development do
gem 'vcr'
end
-gem 'patron'
+platforms :ruby do
+ gem 'patron' # skip patron for jruby
+end
+
gem 'iron_mq'
9 lib/parse-ruby-client.rb
View
@@ -9,9 +9,14 @@
require "bundler/setup"
require 'json'
-require 'patron'
require 'date'
require 'cgi'
+if defined?(JRUBY_VERSION)
+ require 'net/http'
+ require 'net/https'
+else
+ require 'patron'
+end
cwd = Pathname(__FILE__).dirname
$:.unshift(cwd.to_s) unless $:.include?(cwd.to_s) || $:.include?(cwd.expand_path.to_s)
@@ -25,4 +30,4 @@
require 'parse/push'
require 'parse/cloud'
require 'parse/model'
-require 'parse/batch'
+require 'parse/batch'
17 lib/parse/client.rb
View
@@ -1,6 +1,7 @@
require 'parse/protocol'
require 'parse/error'
require 'parse/util'
+require 'parse/http_client'
require 'logger'
@@ -9,8 +10,7 @@
module Parse
# A class which encapsulates the HTTPS communication with the Parse
- # API server. Currently uses the Patron library for low-level HTTP
- # communication.
+ # API server.
class Client
attr_accessor :host
attr_accessor :application_id
@@ -29,10 +29,7 @@ def initialize(data = {})
@session_token = data[:session_token]
@max_retries = data[:max_retries] || 3
@logger = data[:logger] || Logger.new(STDERR).tap{|l| l.level = Logger::INFO}
-
- @session = Patron::Session.new
- @session.timeout = 30
- @session.connect_timeout = 30
+ @session = data[:http_client] || Parse::DEFAULT_HTTP_CLIENT.new
if data[:ironio_project_id] && data[:ironio_token]
@@ -63,16 +60,16 @@ def request(uri, method = :get, body = nil, query = nil, content_type = nil)
options = {}
headers = {}
- headers[Protocol::HEADER_MASTER_KEY] = @master_key
+ headers[Protocol::HEADER_MASTER_KEY] = @master_key if @master_key
headers[Protocol::HEADER_API_KEY] = @api_key
headers[Protocol::HEADER_APP_ID] = @application_id
- headers[Protocol::HEADER_SESSION_TOKEN] = @session_token
+ headers[Protocol::HEADER_SESSION_TOKEN] = @session_token if @session_token
if body
options[:data] = body
end
if query
- options[:query] = Patron::Util.build_query_pairs_from_hash(query).join('&')
+ options[:query] = @session.build_query(query)
# Avoid 502 or 414 when sending a large querystring. See https://parse.com/questions/502-error-when-query-with-huge-contains
if options[:query].size > 2000 && method == :get && !body && !content_type
@@ -128,7 +125,7 @@ def request(uri, method = :get, body = nil, query = nil, content_type = nil)
retry
end
raise
- rescue Patron::TimeoutError => e
+ rescue HttpClient::TimeoutError => e
if num_tries <= max_retries
log_retry(e, uri, query, body, response)
retry
84 lib/parse/http_client.rb
View
@@ -0,0 +1,84 @@
+module Parse
+ class HttpClient
+ class TimeoutError < StandardError; end
+
+ attr_accessor :base_url, :headers
+
+ def initialize(base_url=nil, headers = {})
+ @base_url = base_url
+ @headers = headers
+ end
+
+ def build_query(hash)
+ hash.to_a.map{|k, v| "#{k}=#{v}"}.join('&')
+ end
+
+ def request(method, uri, headers, options)
+ NotImplementedError.new("Subclass responsibility")
+ end
+ end
+
+ class NetHttpClient < HttpClient
+ class NetHttpResponseWrapper
+ def initialize(response) @response = response end
+ def status() @response.code.to_i end
+ def body() @response.read_body end
+ end
+
+ def request(method, uri, headers, options)
+ request_class = eval("Net::HTTP::#{method.to_s.capitalize}")
+ uri = "#{uri}?#{options[:query]}" if options[:query]
+ request = request_class.new(uri, @headers.dup.update(headers))
+ request.body = options[:data] if options.has_key?(:data)
+ NetHttpResponseWrapper.new(
+ @client.start do
+ @client.request(request)
+ end
+ )
+ end
+
+ def base_url=(url)
+ @base_url = url
+ @client = Net::HTTP.new(@base_url.sub('https://', ''), 443)
+ @client.use_ssl = true
+ end
+ end
+
+ class PatronHttpClient < HttpClient
+ def initialize(base_url=nil, headers = {})
+ super
+ @session = Patron::Session.new
+ @session.timeout = 30
+ @session.connect_timeout = 30
+ @session.headers.update(@headers)
+ end
+
+ def build_query(hash)
+ Patron::Util.build_query_pairs_from_hash(hash).join('&')
+ end
+
+ def request(method, uri, headers, options)
+ @session.request(method, uri, headers, options)
+ rescue Patron::TimeoutError => e
+ raise HttpClient::TimeoutError.new(e)
+ end
+
+ def base_url
+ @session.base_url
+ end
+
+ def base_url=(url)
+ @session.base_url = url
+ end
+
+ def headers
+ @session.headers
+ end
+
+ def headers=(hash)
+ @session.headers = hash
+ end
+ end
+
+ DEFAULT_HTTP_CLIENT = defined?(JRUBY_VERSION) ? NetHttpClient : PatronHttpClient
+end
Something went wrong with that request. Please try again.