diff options
| -rw-r--r-- | client/changes/bug_reuse-http-connection | 2 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/__init__.py | 2 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/sqlcipher.py | 59 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/target.py | 1 | 
4 files changed, 52 insertions, 12 deletions
| diff --git a/client/changes/bug_reuse-http-connection b/client/changes/bug_reuse-http-connection new file mode 100644 index 00000000..c6cdd9b4 --- /dev/null +++ b/client/changes/bug_reuse-http-connection @@ -0,0 +1,2 @@ +  o Fix a bug in soledad.client.sqlcipher by which we were creating +    a new connection for each sync. diff --git a/client/src/leap/soledad/client/__init__.py b/client/src/leap/soledad/client/__init__.py index 61337680..a0b3f45a 100644 --- a/client/src/leap/soledad/client/__init__.py +++ b/client/src/leap/soledad/client/__init__.py @@ -1283,7 +1283,7 @@ class Soledad(object):  #-----------------------------------------------------------------------------  # We need a more reasonable timeout (in seconds) -SOLEDAD_TIMEOUT = 10 +SOLEDAD_TIMEOUT = 120  class VerifiedHTTPSConnection(httplib.HTTPSConnection): diff --git a/client/src/leap/soledad/client/sqlcipher.py b/client/src/leap/soledad/client/sqlcipher.py index c7aebbe6..43c871c3 100644 --- a/client/src/leap/soledad/client/sqlcipher.py +++ b/client/src/leap/soledad/client/sqlcipher.py @@ -43,16 +43,19 @@ So, as the statements above were introduced for backwards compatibility with  SLCipher 1.1 databases, we do not implement them as all SQLCipher databases  handled by Soledad should be created by SQLCipher >= 2.0.  """ +import httplib  import logging  import os -import time  import string  import threading +import time -from u1db.backends import sqlite_backend -from u1db import errors  from pysqlcipher import dbapi2 +from u1db.backends import sqlite_backend +from u1db.sync import Synchronizer  from u1db import errors as u1db_errors + +from leap.soledad.client.target import SoledadSyncTarget  from leap.soledad.common.document import SoledadDocument  logger = logging.getLogger(__name__) @@ -144,6 +147,7 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):      _index_storage_value = 'expand referenced encrypted'      k_lock = threading.Lock() +    _syncer = None      def __init__(self, sqlcipher_file, password, document_factory=None,                   crypto=None, raw_key=False, cipher='aes-256-cbc', @@ -336,13 +340,46 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          :return: The local generation before the synchronisation was performed.          :rtype: int          """ -        from u1db.sync import Synchronizer -        from leap.soledad.client.target import SoledadSyncTarget -        return Synchronizer( -            self, -            SoledadSyncTarget(url, -                              creds=creds, -                              crypto=self._crypto)).sync(autocreate=autocreate) +        if not self.syncer: +            self._create_syncer(url, creds=creds) + +        try: +            res = self.syncer.sync(autocreate=autocreate) +        except httplib.CannotSendRequest: +            # raised when you reuse httplib.HTTP object for new request +            # while you havn't called its getresponse() +            # this catch works for the current connclass used +            # by our HTTPClientBase, since it uses httplib. +            # we will have to replace it if it changes. +            logger.info("Replacing connection and trying again...") +            self._syncer = None +            self._create_syncer(url, creds=creds) +            res = self.syncer.sync(autocreate=autocreate) +        return res + +    @property +    def syncer(self): +        """ +        Accesor for synchronizer. +        """ +        return self._syncer + +    def _create_syncer(self, url, creds=None): +        """ +        Creates a synchronizer + +        :param url: The url of the target replica to sync with. +        :type url: str +        :param creds: optional dictionary giving credentials. +            to authorize the operation with the server. +        :type creds: dict +        """ +        if self._syncer is None: +            self._syncer = Synchronizer( +                self, +                SoledadSyncTarget(url, +                                  creds=creds, +                                  crypto=self._crypto))      def _extra_schema_init(self, c):          """ @@ -719,7 +756,7 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          definition = self._get_index_definition(index_name)          if len(key_values) != len(definition): -            raise errors.InvalidValueForIndex() +            raise u1db_errors.InvalidValueForIndex()          tables = ["document_fields d%d" % i for i in range(len(definition))]          novalue_where = ["d.doc_id = d%d.doc_id"                           " AND d%d.field_name = ?" diff --git a/client/src/leap/soledad/client/target.py b/client/src/leap/soledad/client/target.py index 73f719fb..3b3d6870 100644 --- a/client/src/leap/soledad/client/target.py +++ b/client/src/leap/soledad/client/target.py @@ -63,6 +63,7 @@ logger = logging.getLogger(__name__)  # Exceptions  # +  class DocumentNotEncrypted(Exception):      """      Raised for failures in document encryption. | 
