Open 2d426258-7f6b-45ab-bd06-a8d8e1c32ffb opened 16 years ago
cookielib has no FileCookieJar class for Safari, Apple's standard and default browser for OS X.
I have code to read Safari cookies, but no code to write them. I'll have to look at the FileCookieJar interface.
would you mind posting the read code you have? I would really like to at least be able to import Safari cookies in an app or two I have lying around..
I found a solution for reading Safari cookies, but struggling around with hg diff. Because always when i typ hg diff Lib/http/cookiejar.py it returns me the complete file not only my changes..
Ok, i've got it.
--- a/Lib/http/cookiejar.py Wed Dec 18 15:37:03 2013 -0600
+++ b/Lib/http/cookiejar.py Sat Feb 01 15:12:01 2014 +0100
@@ -11,17 +11,17 @@
distributed with the Python standard library, but are available from
http://wwwsearch.sf.net/):
- CookieJar____
- / \ \
- FileCookieJar \ \
- / | \ \ \
- MozillaCookieJar | LWPCookieJar \ \
- | | \
- | ---MSIEBase | \
- | / | | \
- | / MSIEDBCookieJar BSDDBCookieJar
- |/
- MSIECookieJar
+ CookieJar____
+ / \ \
+ FileCookieJar \ \
+ / / | \ \ \
+ SafariCookieJar / | LWPCookieJar \ \
+ / | | \
+ MozillaCookieJar | ---MSIEBase | \
+ | / | | \
+ | / MSIEDBCookieJar BSDDBCookieJar
+ |/
+ MSIECookieJar
"""
@@ -31,8 +31,11 @@
import copy
import datetime
import re
+import getpass
import time
import urllib.parse, urllib.request
+import struct
+import io
try:
import threading as _threading
except ImportError:
@@ -40,6 +43,9 @@
import http.client # only for the default HTTP port
from calendar import timegm
+import difflib
+#from difflib_data import *
+
debug = False # set to True to enable debugging via the logging module
logger = None
@@ -1938,6 +1944,109 @@
raise LoadError("invalid Set-Cookie3 format file %r: %r" %
(filename, line))
+class SafariCookieJar(FileCookieJar):
+ """
+ Read Cookies from Safari
+
+ """
+ def load(self, filename=None):
+ if filename == None:
+ username = getpass.getuser()
+ path = '/Users/' + username + '/Library/Cookies/Cookies.binarycookies'
+ else:
+ path = filename
+
+ bf=open(path,mode='rb')
+ scook = bf.read(4).decode("UTF-8")
+ if scook == 'cook':
+ NumberOfPages=struct.unpack('>i',bf.read(4))[0]
+ page_sizes=[]
+ for np in range(NumberOfPages):
+ page_sizes.append(struct.unpack('>i',bf.read(4))[0])
+ pages=[]
+ for ps in page_sizes:
+ pages.append(bf.read(ps))
+
+ for page in pages:
+ page=io.BytesIO(page)
+ page.read(4)
+ num_cookies=struct.unpack('<i',page.read(4))[0]
+ cookie_offsets=[]
+ for nc in range(num_cookies):
+ cookie_offsets.append(struct.unpack('<i',page.read(4))[0])
+
+ page.read(4)
+
+ cookie=''
+ for offset in cookie_offsets:
+ page.seek(offset)
+ cookiesize=struct.unpack('<i',page.read(4))[0]
+ cookie=io.BytesIO(page.read(cookiesize))
+
+ cookie.read(4)
+
+ flags=struct.unpack('<i',cookie.read(4))[0]
+ cookie_flags=''
+ if flags==0:
+ cookie_flags=''
+ elif flags==1:
+ cookie_flags='Secure'
+ elif flags==4:
+ cookie_flags='HttpOnly'
+ elif flags==5:
+ cookie_flags='Secure; HttpOnly'
+ else:
+ cookie_flags='Unknown'
+
+ cookie.read(4)
+
+ urloffset=struct.unpack('<i',cookie.read(4))[0]
+ nameoffset=struct.unpack('<i',cookie.read(4))[0]
+ pathoffset=struct.unpack('<i',cookie.read(4))[0]
+ valueoffset=struct.unpack('<i',cookie.read(4))[0]
+
+ endofcookie=cookie.read(8)
+
+ expiry_date_epoch= struct.unpack('<d',cookie.read(8))[0]+978307200
+ expiry_date=time.strftime("%a, %d %b %Y ",time.gmtime(expiry_date_epoch))[:-1]
+
+ create_date_epoch=struct.unpack('<d',cookie.read(8))[0]+978307200
+ create_date=time.strftime("%a, %d %b %Y ",time.gmtime(create_date_epoch))[:-1]
+
+ cookie.seek(urloffset-4)
+ url=''
+ u=cookie.read(1)
+ while struct.unpack('<b',u)[0]!=0:
+ url=url+u.decode('UTF-8')
+ u=cookie.read(1)
+
+ cookie.seek(nameoffset-4)
+ name=''
+ n=cookie.read(1)
+ while struct.unpack('<b',n)[0]!=0:
+ name=name+n.decode('UTF-8')
+ n=cookie.read(1)
+
+ cookie.seek(pathoffset-4)
+ path=''
+ pa=cookie.read(1)
+ while struct.unpack('<b',pa)[0]!=0:
+ path=path+pa.decode('UTF-8')
+ pa=cookie.read(1)
+
+ cookie.seek(valueoffset-4)
+ value=''
+ va=cookie.read(1)
+ while struct.unpack('<b',va)[0]!=0:
+ value=value+va.decode('UTF-8')
+ va=cookie.read(1)
+
+ print ('Cookie : '+name+'='+value+'; domain='+url+'; path='+path+'; '+'expires='+expiry_date+'; '+cookie_flags)
+
+ bf.close()
+ else:
+ bf.close()
+ raise LoadError("This is not an cookiefile!")
class MozillaCookieJar(FileCookieJar):
"""
@@ -1979,6 +2088,7 @@
"""
def _really_load(self, f, filename, ignore_discard, ignore_expires):
+
now = time.time()
magic = f.readline()
this solutions based on code from http://securitylearn.net/wp-content/uploads/tools/iOS/BinaryCookieReader.py
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields: ```python assignee = 'https://github.com/loewis' closed_at = None created_at =
labels = ['type-feature', 'library']
title = 'cookielib lacks FileCookieJar class for Safari'
updated_at =
user = 'https://bugs.python.org/janssen'
```
bugs.python.org fields:
```python
activity =
actor = 'berker.peksag'
assignee = 'loewis'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation =
creator = 'janssen'
dependencies = []
files = ['33921', '33922']
hgrepos = []
issue_num = 2008
keywords = ['patch']
message_count = 5.0
messages = ['62047', '62048', '65544', '209892', '209971']
nosy_count = 4.0
nosy_names = ['loewis', 'janssen', 'sams.james', 'Hendrik']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue2008'
versions = ['Python 3.4']
```