summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2009-04-25 14:09:52 -0400
committerOwen W. Taylor <otaylor@fishsoup.net>2009-04-25 14:09:52 -0400
commitcdb5d340e63094817e4eac9c3eb6fb19cf3cd595 (patch)
tree4ae23331d6479607552b2af9420282ce9fcdeed6
parent721b1174e58e7386d1eaa113cdb3bf20d6c06c04 (diff)
Work around Firefox-3.5 locking problems with a copy
Firefox-3.5 seems to always hold cookies.sqlite locked while the browser is open. Work around this by, when we hit a lock error, making a copy and reading from that. Not 100% reliable, but should work much of the time.
-rwxr-xr-xgit-bz50
1 files changed, 40 insertions, 10 deletions
diff --git a/git-bz b/git-bz
index 81918a5..5f8bce3 100755
--- a/git-bz
+++ b/git-bz
@@ -207,6 +207,7 @@ from pysqlite2 import dbapi2 as sqlite
import re
from StringIO import StringIO
from subprocess import Popen, CalledProcessError, PIPE
+import shutil
import sys
import tempfile
import time
@@ -477,19 +478,48 @@ def resolve_bug_reference(bug_reference):
class CookieError(Exception):
pass
-def get_cookies_from_sqlite(host, cookies_sqlite, browser):
+def do_get_cookies_from_sqlite(host, cookies_sqlite, browser):
result = {}
+ # We use a timeout of 0 since we expect to hit the browser holding
+ # the lock often and we need to fall back to making a copy without a delay
+ connection = sqlite.connect(cookies_sqlite, timeout=0)
- connection = sqlite.connect(cookies_sqlite)
- cursor = connection.cursor()
- cursor.execute("select name,value,path,expiry from moz_cookies where host = :host", { 'host': host })
+ try:
+ cursor = connection.cursor()
+ cursor.execute("select name,value,path,expiry from moz_cookies where host = :host", { 'host': host })
+
+ now = time.time()
+ for name,value,path,expiry in cursor.fetchall():
+ # Excessive caution: toss out values that need to be quoted in a cookie header
+ if float(expiry) > now and not re.search(r'[()<>@,;:\\"/\[\]?={} \t]', value):
+ result[name] = value
+
+ return result
+ finally:
+ connection.close()
+
+# Firefox 3.5 keeps the cookies database permamently locked; as a workaround
+# hack, we make a copy, read from that, then delete the copy. Of course,
+# we may hit an inconsistent state of the database
+def get_cookies_from_sqlite_with_copy(host, cookies_sqlite, browser):
+ db_copy = cookies_sqlite + ".git-bz-temp"
+ shutil.copyfile(cookies_sqlite, db_copy)
+ try:
+ return do_get_cookies_from_sqlite(host, db_copy, browser)
+ except sqlite.OperationalError, e:
+ raise CookieError("Cookie database was locked; temporary copy didn't work")
+ finally:
+ os.remove(db_copy)
- now = time.time()
- for name,value,path,expiry in cursor.fetchall():
- # Excessive caution: toss out values that need to be quoted in a cookie header
- if float(expiry) > now and not re.search(r'[()<>@,;:\\"/\[\]?={} \t]', value):
- result[name] = value
- connection.close()
+def get_cookies_from_sqlite(host, cookies_sqlite, browser):
+ try:
+ result = do_get_cookies_from_sqlite(host, cookies_sqlite, browser)
+ except sqlite.OperationalError, e:
+ if "database is locked" in str(e):
+ # Try making a temporary copy
+ result = get_cookies_from_sqlite_with_copy(host, cookies_sqlite, browser)
+ else:
+ raise
if not ('Bugzilla_login' in result and 'Bugzilla_logincookie' in result):
raise CookieError("You don't appear to be signed into %s; please log in with %s")