mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-10-09 00:02:50 -04:00
Merge branch 'fix-cookies' into 'master'
Fix cookies See merge request honeyryderchuck/httpx!36
This commit is contained in:
commit
c1d592433f
@ -3,20 +3,82 @@
|
|||||||
module HTTPX
|
module HTTPX
|
||||||
module Plugins
|
module Plugins
|
||||||
module Cookies
|
module Cookies
|
||||||
|
using URIExtensions
|
||||||
|
|
||||||
|
class Store
|
||||||
|
def initialize(cookies = nil)
|
||||||
|
@store = Hash.new { |hash, origin| hash[origin] = HTTP::CookieJar.new }
|
||||||
|
return unless cookies
|
||||||
|
|
||||||
|
cookies = cookies.split(/ *; */) if cookies.is_a?(String)
|
||||||
|
@default_cookies = cookies.map do |cookie, v|
|
||||||
|
if cookie.is_a?(HTTP::Cookie)
|
||||||
|
cookie
|
||||||
|
else
|
||||||
|
HTTP::Cookie.new(cookie.to_s, v.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set(origin, cookies)
|
||||||
|
return unless cookies
|
||||||
|
|
||||||
|
@store[origin].parse(cookies, origin)
|
||||||
|
end
|
||||||
|
|
||||||
|
def [](uri)
|
||||||
|
store = @store[uri.origin]
|
||||||
|
@default_cookies.each do |cookie|
|
||||||
|
c = cookie.dup
|
||||||
|
c.domain ||= uri.authority
|
||||||
|
c.path ||= uri.path
|
||||||
|
store.add(c)
|
||||||
|
end if @default_cookies
|
||||||
|
store
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def self.load_dependencies(*)
|
def self.load_dependencies(*)
|
||||||
require "http/cookie"
|
require "http/cookie"
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
def cookies(cookies)
|
attr_reader :cookies_store
|
||||||
|
|
||||||
|
def initialize(*)
|
||||||
|
super
|
||||||
|
@cookies_store = @options.cookies || Store.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def with_cookies(cookies)
|
||||||
branch(default_options.with_cookies(cookies))
|
branch(default_options.with_cookies(cookies))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def wrap
|
||||||
|
return unless block_given?
|
||||||
|
|
||||||
|
super do |client|
|
||||||
|
old_cookies_store = @cookies_store
|
||||||
|
@cookies_store = old_cookies_store.dup
|
||||||
|
begin
|
||||||
|
yield client
|
||||||
|
ensure
|
||||||
|
@cookies_store = old_cookies_store
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module RequestMethods
|
private
|
||||||
def initialize(*)
|
|
||||||
|
def on_response(request, response)
|
||||||
|
@cookies_store.set(request.origin, response.headers["set-cookie"])
|
||||||
super
|
super
|
||||||
@headers.cookies(@options.cookies, self)
|
end
|
||||||
|
|
||||||
|
def __build_req(*)
|
||||||
|
request = super
|
||||||
|
request.headers.cookies(@cookies_store[request.uri], request)
|
||||||
|
request
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -24,38 +86,20 @@ module HTTPX
|
|||||||
def cookies(jar, request)
|
def cookies(jar, request)
|
||||||
return unless jar
|
return unless jar
|
||||||
|
|
||||||
unless jar.is_a?(HTTP::CookieJar)
|
cookie_value = HTTP::Cookie.cookie_value(jar.cookies(request.uri))
|
||||||
jar = jar.each_with_object(HTTP::CookieJar.new) do |(k, v), j|
|
return if cookie_value.empty?
|
||||||
cookie = k.is_a?(HTTP::Cookie) ? v : HTTP::Cookie.new(k.to_s, v.to_s)
|
|
||||||
cookie.domain = request.authority
|
|
||||||
cookie.path = request.path
|
|
||||||
j.add(cookie)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self["cookie"] = HTTP::Cookie.cookie_value(jar.cookies)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module ResponseMethods
|
add("cookie", cookie_value)
|
||||||
def cookie_jar
|
|
||||||
return @cookie_jar if defined?(@cookie_jar)
|
|
||||||
return nil unless headers.key?("set-cookie")
|
|
||||||
|
|
||||||
@cookie_jar ||= begin
|
|
||||||
jar = HTTP::CookieJar.new
|
|
||||||
jar.parse(headers["set-cookie"], @request.uri)
|
|
||||||
jar
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias_method :cookies, :cookie_jar
|
|
||||||
end
|
|
||||||
|
|
||||||
module OptionsMethods
|
module OptionsMethods
|
||||||
def self.included(klass)
|
def self.included(klass)
|
||||||
super
|
super
|
||||||
klass.def_option(:cookies) do |cookies|
|
klass.def_option(:cookies) do |cookies|
|
||||||
cookies.split(/ *; */) if cookies.is_a?(String)
|
return cookies if cookies.is_a?(Store)
|
||||||
cookies
|
|
||||||
|
Store.new(cookies)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -5,14 +5,12 @@ module Requests
|
|||||||
module Cookies
|
module Cookies
|
||||||
def test_plugin_cookies_get
|
def test_plugin_cookies_get
|
||||||
client = HTTPX.plugin(:cookies)
|
client = HTTPX.plugin(:cookies)
|
||||||
assert client.respond_to?(:cookies), "client should be cookie-enabled"
|
|
||||||
response = client.get(cookies_uri)
|
response = client.get(cookies_uri)
|
||||||
assert response.respond_to?(:cookies), "response should have cookies"
|
|
||||||
body = json_body(response)
|
body = json_body(response)
|
||||||
assert body.key?("cookies")
|
assert body.key?("cookies")
|
||||||
assert body["cookies"].empty?
|
assert body["cookies"].empty?
|
||||||
|
|
||||||
session_response = client.cookies("abc" => "def").get(cookies_uri)
|
session_response = client.with_cookies("abc" => "def").get(cookies_uri)
|
||||||
body = json_body(session_response)
|
body = json_body(session_response)
|
||||||
assert body.key?("cookies")
|
assert body.key?("cookies")
|
||||||
assert body["cookies"]["abc"] == "def", "abc wasn't properly set"
|
assert body["cookies"]["abc"] == "def", "abc wasn't properly set"
|
||||||
@ -22,21 +20,39 @@ module Requests
|
|||||||
client = HTTPX.plugin(:cookies)
|
client = HTTPX.plugin(:cookies)
|
||||||
session_cookies = { "a" => "b", "c" => "d" }
|
session_cookies = { "a" => "b", "c" => "d" }
|
||||||
session_uri = cookies_set_uri(session_cookies)
|
session_uri = cookies_set_uri(session_cookies)
|
||||||
session_response = client.get(cookies_set_uri(session_cookies))
|
session_response = client.get(session_uri)
|
||||||
assert session_response.status == 302, "response should redirect"
|
verify_status(session_response, 302)
|
||||||
|
verify_cookies(client.cookies_store[URI(session_uri)], session_cookies)
|
||||||
|
|
||||||
assert !session_response.cookies.nil?, "there should be cookies in the response"
|
# first request sets the session
|
||||||
response_cookies = session_response.cookie_jar
|
response = client.get(cookies_uri)
|
||||||
assert !response_cookies.empty?
|
|
||||||
response_cookies.cookies(session_uri).each do |cookie|
|
|
||||||
assert(session_cookies.one? { |k, v| k == cookie.name && v == cookie.value })
|
|
||||||
end
|
|
||||||
|
|
||||||
response = client.cookies(response_cookies).get(cookies_uri)
|
|
||||||
body = json_body(response)
|
body = json_body(response)
|
||||||
assert body.key?("cookies")
|
assert body.key?("cookies")
|
||||||
assert body["cookies"]["a"] == "b"
|
verify_cookies(body["cookies"], session_cookies)
|
||||||
assert body["cookies"]["c"] == "d"
|
|
||||||
|
# second request reuses the session
|
||||||
|
extra_cookie_response = client.with_cookies("e" => "f").get(cookies_uri)
|
||||||
|
body = json_body(extra_cookie_response)
|
||||||
|
assert body.key?("cookies")
|
||||||
|
verify_cookies(body["cookies"], session_cookies.merge("e" => "f"))
|
||||||
|
|
||||||
|
# redirect to a different origin only uses the option cookies
|
||||||
|
other_origin_response = client.with_cookies("e" => "f").get(redirect_uri(origin("google.com")))
|
||||||
|
verify_status(other_origin_response, 302)
|
||||||
|
assert !other_origin_response.headers.key?("set-cookie"), "cookies should not transition to next origin"
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_plugin_cookies_follow
|
||||||
|
client = HTTPX.plugins(:follow_redirects, :cookies)
|
||||||
|
session_cookies = { "a" => "b", "c" => "d" }
|
||||||
|
session_uri = cookies_set_uri(session_cookies)
|
||||||
|
|
||||||
|
response = client.get(session_uri)
|
||||||
|
verify_status(response, 200)
|
||||||
|
assert response.uri.to_s == cookies_uri
|
||||||
|
body = json_body(response)
|
||||||
|
assert body.key?("cookies")
|
||||||
|
verify_cookies(body["cookies"], session_cookies)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -48,6 +64,19 @@ module Requests
|
|||||||
def cookies_set_uri(cookies)
|
def cookies_set_uri(cookies)
|
||||||
build_uri("/cookies/set?" + URI.encode_www_form(cookies))
|
build_uri("/cookies/set?" + URI.encode_www_form(cookies))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def verify_cookies(jar, cookies)
|
||||||
|
assert !jar.nil? && !jar.empty?, "there should be cookies in the response"
|
||||||
|
assert jar.all? { |cookie|
|
||||||
|
case cookie
|
||||||
|
when HTTP::Cookie
|
||||||
|
cookies.one? { |k, v| k == cookie.name && v == cookie.value }
|
||||||
|
else
|
||||||
|
cookie_name, cookie_value = cookie
|
||||||
|
cookies.one? { |k, v| k == cookie_name && v == cookie_value }
|
||||||
|
end
|
||||||
|
}, "jar should contain all expected cookies"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,8 +52,8 @@ module Requests
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def redirect_uri
|
def redirect_uri(redirect_uri = redirect_location)
|
||||||
build_uri("/redirect-to?url=" + redirect_location)
|
build_uri("/redirect-to?url=" + redirect_uri)
|
||||||
end
|
end
|
||||||
|
|
||||||
def max_redirect_uri(n)
|
def max_redirect_uri(n)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user