lib/rmega/session.rb in rmega-0.1.5 vs lib/rmega/session.rb in rmega-0.1.6
- old
+ new
@@ -1,7 +1,7 @@
require 'rmega/storage'
-require 'rmega/request_error'
+require 'rmega/errors'
require 'rmega/crypto/crypto'
require 'rmega/utils'
module Rmega
def self.login(email, password)
@@ -9,24 +9,26 @@
end
class Session
include Loggable
- attr_reader :email, :request_id, :sid, :master_key
+ attr_reader :email, :request_id, :sid, :master_key, :shared_keys, :rsa_privk
def initialize(email, password)
@email = email
@request_id = random_request_id
+ @shared_keys = {}
login(password)
end
def options
Rmega.options
end
delegate :api_url, :api_request_timeout, to: :options
+ delegate :max_retries, :retry_interval, to: :options
def storage
@storage ||= Storage.new(self)
end
@@ -37,11 +39,12 @@
# Decrypts the master key
encrypted_key = Crypto.prepare_key_pw(password)
@master_key = Crypto.decrypt_key(encrypted_key, Utils.base64_to_a32(resp['k']))
# Generates the session id
- @sid = Crypto.decrypt_sid(@master_key, resp['csid'], resp['privk'])
+ @rsa_privk = Crypto.decrypt_rsa_privk(@master_key, resp['privk'])
+ @sid = Crypto.decrypt_sid(@rsa_privk, resp['csid'])
end
def random_request_id
rand(1E7..1E9).to_i
end
@@ -50,16 +53,30 @@
"#{api_url}?id=#{@request_id}".tap do |url|
url << "&sid=#{@sid}" if @sid
end
end
- def request(body)
+ def request(content, retries = max_retries)
@request_id += 1
- logger.debug "POST #{request_url}\n#{body.inspect}"
- response = HTTPClient.new.post(request_url, [body].to_json, timeout: api_request_timeout)
- logger.debug "#{response.code}\n#{response.body}"
- resp = JSON.parse(response.body).first
- raise RequestError.new(resp) if RequestError.error_code?(resp)
- resp
+ logger.debug "POST #{request_url} #{content.inspect}"
+
+ response = HTTPClient.new.post(request_url, [content].to_json, timeout: api_request_timeout)
+ code, body = response.code.to_i, response.body
+
+ logger.debug("#{code} #{body}")
+
+ if code == 500 && body.to_s.empty?
+ raise Errors::ServerError.new("Server too busy", temporary: true)
+ else
+ json = JSON.parse(body).first
+ raise Errors::ServerError.new(json) if json.to_s =~ /\A\-\d+\z/
+ json
+ end
+ rescue SocketError, Errors::ServerError => error
+ raise(error) if retries < 0
+ raise(error) if error.respond_to?(:temporary?) && !error.temporary?
+ retries -= 1
+ sleep(retry_interval)
+ retry
end
end
end