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