File: yaml_saver.rb

package info (click to toggle)
ruby-http-cookie 1.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 280 kB
  • sloc: ruby: 3,356; makefile: 2
file content (86 lines) | stat: -rw-r--r-- 2,286 bytes parent folder | download
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
# :markup: markdown
require 'http/cookie_jar'
require 'psych' if !defined?(YAML) && RUBY_VERSION == "1.9.2"
require 'yaml'

# YAMLSaver saves and loads cookies in the YAML format.  It can load a
# YAML file saved by Mechanize, but the saving format is not
# compatible with older versions of Mechanize (< 2.7).
class HTTP::CookieJar::YAMLSaver < HTTP::CookieJar::AbstractSaver
  # :singleton-method: new
  # :call-seq:
  #   new(**options)
  #
  # There is no option keyword supported at the moment.

  ##

  def save(io, jar)
    YAML.dump(@session ? jar.to_a : jar.reject(&:session?), io)
  end

  def load(io, jar)
    begin
      data = load_yaml(io)
    rescue ArgumentError => e
      case e.message
      when %r{\Aundefined class/module Mechanize::}
        # backward compatibility with Mechanize::Cookie
        begin
          io.rewind # hopefully
          yaml = io.read
          # a gross hack
          yaml.gsub!(%r{^(    [^ ].*:) !ruby/object:Mechanize::Cookie$}, "\\1")
          data = load_yaml(yaml)
        rescue Errno::ESPIPE
          @logger.warn "could not rewind the stream for conversion" if @logger
        rescue ArgumentError
        end
      end
    end

    case data
    when Array
      data.each { |cookie|
        jar.add(cookie)
      }
    when Hash
      # backward compatibility with Mechanize::Cookie
      data.each { |domain, paths|
        paths.each { |path, names|
          names.each { |cookie_name, cookie_hash|
            if cookie_hash.respond_to?(:ivars)
              # YAML::Object of Syck
              cookie_hash = cookie_hash.ivars
            end
            cookie = HTTP::Cookie.new({}.tap { |hash|
                cookie_hash.each_pair { |key, value|
                  hash[key.to_sym] = value
                }
              })
            jar.add(cookie)
          }
        }
      }
    else
      @logger.warn "incompatible YAML cookie data discarded" if @logger
      return
    end
  end

  private

  def default_options
    {}
  end

  if YAML.name == 'Psych' && Psych::VERSION >= '3.1'
    def load_yaml(yaml)
      YAML.safe_load(yaml, :permitted_classes => %w[Time HTTP::Cookie Mechanize::Cookie DomainName], :aliases => true)
    end
  else
    def load_yaml(yaml)
      YAML.load(yaml)
    end
  end
end