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
|
# frozen_string_literal: true
require "forwardable"
module HTTPX
module Plugins
#
# This plugin implements a persistent cookie jar for the duration of a session.
#
# It also adds a *#cookies* helper, so that you can pre-fill the cookies of a session.
#
# https://gitlab.com/os85/httpx/wikis/Cookies
#
module Cookies
def self.load_dependencies(*)
require "httpx/plugins/cookies/jar"
require "httpx/plugins/cookies/cookie"
require "httpx/plugins/cookies/set_cookie_parser"
end
module InstanceMethods
extend Forwardable
def_delegator :@options, :cookies
def initialize(options = {}, &blk)
super({ cookies: Jar.new }.merge(options), &blk)
end
def wrap
return super unless block_given?
super do |session|
old_cookies_jar = @options.cookies.dup
begin
yield session
ensure
@options = @options.merge(cookies: old_cookies_jar)
end
end
end
def build_request(*)
request = super
request.headers.set_cookie(request.options.cookies[request.uri])
request
end
private
def set_request_callbacks(request)
super
request.on(:response) do |response|
next unless response && response.respond_to?(:headers) && (set_cookie = response.headers["set-cookie"])
log { "cookies: set-cookie is over #{Cookie::MAX_LENGTH}" } if set_cookie.bytesize > Cookie::MAX_LENGTH
@options.cookies.parse(set_cookie)
end
end
end
module HeadersMethods
def set_cookie(cookies)
return if cookies.empty?
header_value = cookies.sort.join("; ")
add("cookie", header_value)
end
end
# adds support for the following options:
#
# :cookies :: cookie jar for the session (can be a Hash, an Array, an instance of HTTPX::Plugins::Cookies::CookieJar)
module OptionsMethods
private
def option_headers(*)
value = super
merge_cookie_in_jar(value.delete("cookie"), @cookies) if defined?(@cookies) && value.key?("cookie")
value
end
def option_cookies(value)
jar = value.is_a?(Jar) ? value : Jar.new(value)
merge_cookie_in_jar(@headers.delete("cookie"), jar) if defined?(@headers) && @headers.key?("cookie")
jar
end
def merge_cookie_in_jar(cookies, jar)
cookies.each do |ck|
ck.split(/ *; */).each do |cookie|
name, value = cookie.split("=", 2)
jar.add(Cookie.new(name, value))
end
end
end
end
end
register_plugin :cookies, Cookies
end
end
|