Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

"""Mozilla / Netscape cookie loading / saving.""" 

 

import re, time 

 

from cookielib import (_warn_unhandled_exception, FileCookieJar, LoadError, 

                       Cookie, MISSING_FILENAME_TEXT) 

 

class MozillaCookieJar(FileCookieJar): 

    """ 

 

    WARNING: you may want to backup your browser's cookies file if you use 

    this class to save cookies.  I *think* it works, but there have been 

    bugs in the past! 

 

    This class differs from CookieJar only in the format it uses to save and 

    load cookies to and from a file.  This class uses the Mozilla/Netscape 

    `cookies.txt' format.  lynx uses this file format, too. 

 

    Don't expect cookies saved while the browser is running to be noticed by 

    the browser (in fact, Mozilla on unix will overwrite your saved cookies if 

    you change them on disk while it's running; on Windows, you probably can't 

    save at all while the browser is running). 

 

    Note that the Mozilla/Netscape format will downgrade RFC2965 cookies to 

    Netscape cookies on saving. 

 

    In particular, the cookie version and port number information is lost, 

    together with information about whether or not Path, Port and Discard were 

    specified by the Set-Cookie2 (or Set-Cookie) header, and whether or not the 

    domain as set in the HTTP header started with a dot (yes, I'm aware some 

    domains in Netscape files start with a dot and some don't -- trust me, you 

    really don't want to know any more about this). 

 

    Note that though Mozilla and Netscape use the same format, they use 

    slightly different headers.  The class saves cookies using the Netscape 

    header by default (Mozilla can cope with that). 

 

    """ 

    magic_re = "#( Netscape)? HTTP Cookie File" 

    header = """\ 

# Netscape HTTP Cookie File 

# http://curl.haxx.se/rfc/cookie_spec.html 

# This is a generated file!  Do not edit. 

 

""" 

 

    def _really_load(self, f, filename, ignore_discard, ignore_expires): 

        now = time.time() 

 

        magic = f.readline() 

        if not re.search(self.magic_re, magic): 

            f.close() 

            raise LoadError( 

                "%r does not look like a Netscape format cookies file" % 

                filename) 

 

        try: 

            while 1: 

                line = f.readline() 

                if line == "": break 

 

                # last field may be absent, so keep any trailing tab 

                if line.endswith("\n"): line = line[:-1] 

 

                # skip comments and blank lines XXX what is $ for? 

                if (line.strip().startswith(("#", "$")) or 

                    line.strip() == ""): 

                    continue 

 

                domain, domain_specified, path, secure, expires, name, value = \ 

                        line.split("\t") 

                secure = (secure == "TRUE") 

                domain_specified = (domain_specified == "TRUE") 

                if name == "": 

                    # cookies.txt regards 'Set-Cookie: foo' as a cookie 

                    # with no name, whereas cookielib regards it as a 

                    # cookie with no value. 

                    name = value 

                    value = None 

 

                initial_dot = domain.startswith(".") 

                assert domain_specified == initial_dot 

 

                discard = False 

                if expires == "": 

                    expires = None 

                    discard = True 

 

                # assume path_specified is false 

                c = Cookie(0, name, value, 

                           None, False, 

                           domain, domain_specified, initial_dot, 

                           path, False, 

                           secure, 

                           expires, 

                           discard, 

                           None, 

                           None, 

                           {}) 

                if not ignore_discard and c.discard: 

                    continue 

                if not ignore_expires and c.is_expired(now): 

                    continue 

                self.set_cookie(c) 

 

        except IOError: 

            raise 

        except Exception: 

            _warn_unhandled_exception() 

            raise LoadError("invalid Netscape format cookies file %r: %r" % 

                            (filename, line)) 

 

    def save(self, filename=None, ignore_discard=False, ignore_expires=False): 

        if filename is None: 

            if self.filename is not None: filename = self.filename 

            else: raise ValueError(MISSING_FILENAME_TEXT) 

 

        f = open(filename, "w") 

        try: 

            f.write(self.header) 

            now = time.time() 

            for cookie in self: 

                if not ignore_discard and cookie.discard: 

                    continue 

                if not ignore_expires and cookie.is_expired(now): 

                    continue 

                if cookie.secure: secure = "TRUE" 

                else: secure = "FALSE" 

                if cookie.domain.startswith("."): initial_dot = "TRUE" 

                else: initial_dot = "FALSE" 

                if cookie.expires is not None: 

                    expires = str(cookie.expires) 

                else: 

                    expires = "" 

                if cookie.value is None: 

                    # cookies.txt regards 'Set-Cookie: foo' as a cookie 

                    # with no name, whereas cookielib regards it as a 

                    # cookie with no value. 

                    name = "" 

                    value = cookie.name 

                else: 

                    name = cookie.name 

                    value = cookie.value 

                f.write( 

                    "\t".join([cookie.domain, initial_dot, cookie.path, 

                               secure, expires, name, value])+ 

                    "\n") 

        finally: 

            f.close()