File: cookie.rb

package info (click to toggle)
ruby-httpclient 2.8.3%2Bgit20211122.4658227-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 1,908 kB
  • sloc: ruby: 9,963; makefile: 10; sh: 2
file content (220 lines) | stat: -rw-r--r-- 5,073 bytes parent folder | download | duplicates (4)
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# do not override if httpclient/webagent-cookie is loaded already
unless defined?(HTTPClient::CookieManager)
begin # for catching LoadError and load webagent-cookie instead

require 'http-cookie'
require 'httpclient/util'

class HTTPClient
  class CookieManager
    include HTTPClient::Util

    attr_reader :format, :jar
    attr_accessor :cookies_file

    def initialize(cookies_file = nil, format = WebAgentSaver, jar = HTTP::CookieJar.new)
      @cookies_file = cookies_file
      @format = format
      @jar = jar
      load_cookies if @cookies_file
    end

    def load_cookies
      check_cookies_file
      @jar.clear
      @jar.load(@cookies_file, :format => @format)
    end

    def save_cookies(session = false)
      check_cookies_file
      @jar.save(@cookies_file, :format => @format, :session => session)
    end

    def cookies(uri = nil)
      cookies = @jar.cookies(uri)
      # TODO: return HTTP::Cookie in the future
      cookies.map { |cookie|
        WebAgent::Cookie.new(
          :name => cookie.name,
          :value => cookie.value,
          :domain => cookie.domain,
          :path => cookie.path,
          :origin => cookie.origin,
          :for_domain => cookie.for_domain,
          :expires => cookie.expires,
          :httponly => cookie.httponly,
          :secure => cookie.secure
        )
      }
    end

    def cookie_value(uri)
      cookies = self.cookies(uri)
      unless cookies.empty?
        HTTP::Cookie.cookie_value(cookies)
      end
    end

    def parse(value, uri)
      @jar.parse(value, uri)
    end

    def cookies=(cookies)
      @jar.clear
      cookies.each do |cookie|
        add(cookie)
      end
    end

    def add(cookie)
      @jar.add(cookie)
    end

    def find(uri)
      warning('CookieManager#find is deprecated and will be removed in near future. Use HTTP::Cookie.cookie_value(CookieManager#cookies) instead')
      if cookie = cookies(uri)
        HTTP::Cookie.cookie_value(cookie)
      end
    end

  private

    def check_cookies_file
      unless @cookies_file
        raise ArgumentError.new('Cookies file not specified')
      end
    end
  end

  class WebAgentSaver < HTTP::CookieJar::AbstractSaver
    # no option
    def default_options
      {}
    end

    # same as HTTP::CookieJar::CookiestxtSaver
    def save(io, jar)
      jar.each { |cookie|
        next if !@session && cookie.session?
        io.print cookie_to_record(cookie)
      }
    end

    # same as HTTP::CookieJar::CookiestxtSaver
    def load(io, jar)
      io.each_line { |line|
        cookie = parse_record(line) and jar.add(cookie)
      }
    end

  private

    def cookie_to_record(cookie)
      [
        cookie.origin,
        cookie.name, 
        cookie.value,
        cookie.expires.to_i,
        cookie.dot_domain,
        cookie.path,
        self.class.flag(cookie)
      ].join("\t") + "\n"
    end

    def parse_record(line)
      return nil if /\A#/ =~ line
      col = line.chomp.split(/\t/)

      origin = col[0]
      name = col[1]
      value = col[2]
      value.chomp!
      if col[3].empty? or col[3] == '0'
        expires = nil
      else
        expires = Time.at(col[3].to_i)
        return nil if expires < Time.now
      end
      domain = col[4]
      path = col[5]

      cookie = WebAgent::Cookie.new(name, value,
        :origin => origin,
        :domain => domain,
        :path => path,
        :expires => expires
      )
      self.class.set_flag(cookie, col[6].to_i)
      cookie
    end

    USE = 1
    SECURE = 2
    DOMAIN = 4
    PATH = 8
    HTTP_ONLY = 64

    def self.flag(cookie)
      flg = 0
      flg += USE # not used
      flg += SECURE  if cookie.secure?
      flg += DOMAIN  if cookie.for_domain?
      flg += HTTP_ONLY  if cookie.httponly?
      flg += PATH  if cookie.path # not used
      flg
    end

    def self.set_flag(cookie, flag)
      cookie.secure = true if flag & SECURE > 0
      cookie.for_domain = true if flag & DOMAIN > 0
      cookie.httponly = true if flag & HTTP_ONLY > 0
    end
  end
end

# for backward compatibility
class WebAgent
  CookieManager = ::HTTPClient::CookieManager

  class Cookie < HTTP::Cookie
    include HTTPClient::Util

    def url
      deprecated('url', 'origin')
      self.origin
    end

    def url=(url)
      deprecated('url=', 'origin=')
      self.origin = url
    end

    def http_only?
      deprecated('http_only?', 'httponly?')
      self.httponly?
    end

    alias original_domain domain

    def domain
      warning('Cookie#domain returns dot-less domain name now. Use Cookie#dot_domain if you need "." at the beginning.')
      self.original_domain
    end

    def flag
      deprecated('flag', 'secure, for_domain, etc.')
      HTTPClient::WebAgentSaver.flag(self)
    end

  private

    def deprecated(old, new)
      warning("WebAgent::Cookie is deprecated and will be replaced with HTTP::Cookie in the near future. Please use Cookie##{new} instead of Cookie##{old} for the replacement.")
    end
  end
end

rescue LoadError
  require 'httpclient/webagent-cookie'
end
end