Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(983)

Side by Side Diff: Tools/Scripts/webkitpy/thirdparty/mechanize/_firefox3cookiejar.py

Issue 18418010: Check in the thirdparty libs needed for webkitpy. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 """Firefox 3 "cookies.sqlite" cookie persistence.
2
3 Copyright 2008 John J Lee <jjl@pobox.com>
4
5 This code is free software; you can redistribute it and/or modify it
6 under the terms of the BSD or ZPL 2.1 licenses (see the file
7 COPYING.txt included with the distribution).
8
9 """
10
11 import logging
12 import time
13
14 from _clientcookie import CookieJar, Cookie, MappingIterator
15 from _util import isstringlike, experimental
16 debug = logging.getLogger("mechanize.cookies").debug
17
18
19 class Firefox3CookieJar(CookieJar):
20
21 """Firefox 3 cookie jar.
22
23 The cookies are stored in Firefox 3's "cookies.sqlite" format.
24
25 Constructor arguments:
26
27 filename: filename of cookies.sqlite (typically found at the top level
28 of a firefox profile directory)
29 autoconnect: as a convenience, connect to the SQLite cookies database at
30 Firefox3CookieJar construction time (default True)
31 policy: an object satisfying the mechanize.CookiePolicy interface
32
33 Note that this is NOT a FileCookieJar, and there are no .load(),
34 .save() or .restore() methods. The database is in sync with the
35 cookiejar object's state after each public method call.
36
37 Following Firefox's own behaviour, session cookies are never saved to
38 the database.
39
40 The file is created, and an sqlite database written to it, if it does
41 not already exist. The moz_cookies database table is created if it does
42 not already exist.
43 """
44
45 # XXX
46 # handle DatabaseError exceptions
47 # add a FileCookieJar (explicit .save() / .revert() / .load() methods)
48
49 def __init__(self, filename, autoconnect=True, policy=None):
50 experimental("Firefox3CookieJar is experimental code")
51 CookieJar.__init__(self, policy)
52 if filename is not None and not isstringlike(filename):
53 raise ValueError("filename must be string-like")
54 self.filename = filename
55 self._conn = None
56 if autoconnect:
57 self.connect()
58
59 def connect(self):
60 import sqlite3 # not available in Python 2.4 stdlib
61 self._conn = sqlite3.connect(self.filename)
62 self._conn.isolation_level = "DEFERRED"
63 self._create_table_if_necessary()
64
65 def close(self):
66 self._conn.close()
67
68 def _transaction(self, func):
69 try:
70 cur = self._conn.cursor()
71 try:
72 result = func(cur)
73 finally:
74 cur.close()
75 except:
76 self._conn.rollback()
77 raise
78 else:
79 self._conn.commit()
80 return result
81
82 def _execute(self, query, params=()):
83 return self._transaction(lambda cur: cur.execute(query, params))
84
85 def _query(self, query, params=()):
86 # XXX should we bother with a transaction?
87 cur = self._conn.cursor()
88 try:
89 cur.execute(query, params)
90 return cur.fetchall()
91 finally:
92 cur.close()
93
94 def _create_table_if_necessary(self):
95 self._execute("""\
96 CREATE TABLE IF NOT EXISTS moz_cookies (id INTEGER PRIMARY KEY, name TEXT,
97 value TEXT, host TEXT, path TEXT,expiry INTEGER,
98 lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)""")
99
100 def _cookie_from_row(self, row):
101 (pk, name, value, domain, path, expires,
102 last_accessed, secure, http_only) = row
103
104 version = 0
105 domain = domain.encode("ascii", "ignore")
106 path = path.encode("ascii", "ignore")
107 name = name.encode("ascii", "ignore")
108 value = value.encode("ascii", "ignore")
109 secure = bool(secure)
110
111 # last_accessed isn't a cookie attribute, so isn't added to rest
112 rest = {}
113 if http_only:
114 rest["HttpOnly"] = None
115
116 if name == "":
117 name = value
118 value = None
119
120 initial_dot = domain.startswith(".")
121 domain_specified = initial_dot
122
123 discard = False
124 if expires == "":
125 expires = None
126 discard = True
127
128 return Cookie(version, name, value,
129 None, False,
130 domain, domain_specified, initial_dot,
131 path, False,
132 secure,
133 expires,
134 discard,
135 None,
136 None,
137 rest)
138
139 def clear(self, domain=None, path=None, name=None):
140 CookieJar.clear(self, domain, path, name)
141 where_parts = []
142 sql_params = []
143 if domain is not None:
144 where_parts.append("host = ?")
145 sql_params.append(domain)
146 if path is not None:
147 where_parts.append("path = ?")
148 sql_params.append(path)
149 if name is not None:
150 where_parts.append("name = ?")
151 sql_params.append(name)
152 where = " AND ".join(where_parts)
153 if where:
154 where = " WHERE " + where
155 def clear(cur):
156 cur.execute("DELETE FROM moz_cookies%s" % where,
157 tuple(sql_params))
158 self._transaction(clear)
159
160 def _row_from_cookie(self, cookie, cur):
161 expires = cookie.expires
162 if cookie.discard:
163 expires = ""
164
165 domain = unicode(cookie.domain)
166 path = unicode(cookie.path)
167 name = unicode(cookie.name)
168 value = unicode(cookie.value)
169 secure = bool(int(cookie.secure))
170
171 if value is None:
172 value = name
173 name = ""
174
175 last_accessed = int(time.time())
176 http_only = cookie.has_nonstandard_attr("HttpOnly")
177
178 query = cur.execute("""SELECT MAX(id) + 1 from moz_cookies""")
179 pk = query.fetchone()[0]
180 if pk is None:
181 pk = 1
182
183 return (pk, name, value, domain, path, expires,
184 last_accessed, secure, http_only)
185
186 def set_cookie(self, cookie):
187 if cookie.discard:
188 CookieJar.set_cookie(self, cookie)
189 return
190
191 def set_cookie(cur):
192 # XXX
193 # is this RFC 2965-correct?
194 # could this do an UPDATE instead?
195 row = self._row_from_cookie(cookie, cur)
196 name, unused, domain, path = row[1:5]
197 cur.execute("""\
198 DELETE FROM moz_cookies WHERE host = ? AND path = ? AND name = ?""",
199 (domain, path, name))
200 cur.execute("""\
201 INSERT INTO moz_cookies VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
202 """, row)
203 self._transaction(set_cookie)
204
205 def __iter__(self):
206 # session (non-persistent) cookies
207 for cookie in MappingIterator(self._cookies):
208 yield cookie
209 # persistent cookies
210 for row in self._query("""\
211 SELECT * FROM moz_cookies ORDER BY name, path, host"""):
212 yield self._cookie_from_row(row)
213
214 def _cookies_for_request(self, request):
215 session_cookies = CookieJar._cookies_for_request(self, request)
216 def get_cookies(cur):
217 query = cur.execute("SELECT host from moz_cookies")
218 domains = [row[0] for row in query.fetchall()]
219 cookies = []
220 for domain in domains:
221 cookies += self._persistent_cookies_for_domain(domain,
222 request, cur)
223 return cookies
224 persistent_coookies = self._transaction(get_cookies)
225 return session_cookies + persistent_coookies
226
227 def _persistent_cookies_for_domain(self, domain, request, cur):
228 cookies = []
229 if not self._policy.domain_return_ok(domain, request):
230 return []
231 debug("Checking %s for cookies to return", domain)
232 query = cur.execute("""\
233 SELECT * from moz_cookies WHERE host = ? ORDER BY path""",
234 (domain,))
235 cookies = [self._cookie_from_row(row) for row in query.fetchall()]
236 last_path = None
237 r = []
238 for cookie in cookies:
239 if (cookie.path != last_path and
240 not self._policy.path_return_ok(cookie.path, request)):
241 last_path = cookie.path
242 continue
243 if not self._policy.return_ok(cookie, request):
244 debug(" not returning cookie")
245 continue
246 debug(" it's a match")
247 r.append(cookie)
248 return r
OLDNEW
« no previous file with comments | « Tools/Scripts/webkitpy/thirdparty/mechanize/_debug.py ('k') | Tools/Scripts/webkitpy/thirdparty/mechanize/_form.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698