httpi 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/lib/httpi/cookie.rb +35 -0
- data/lib/httpi/cookie_store.rb +34 -0
- data/lib/httpi/request.rb +12 -0
- data/lib/httpi/response.rb +6 -0
- data/lib/httpi/version.rb +1 -1
- data/spec/httpi/cookie_spec.rb +36 -0
- data/spec/httpi/cookie_store_spec.rb +26 -0
- data/spec/httpi/request_spec.rb +23 -0
- data/spec/httpi/response_spec.rb +17 -0
- metadata +8 -4
data/CHANGELOG.md
CHANGED
data/lib/httpi/cookie.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module HTTPI
|
2
|
+
|
3
|
+
# = HTTPI::Cookie
|
4
|
+
#
|
5
|
+
# Represents a single delicious cookie.
|
6
|
+
#
|
7
|
+
# == Examples
|
8
|
+
#
|
9
|
+
# cookie = HTTPI::Cookie.new("token=choc-choc-chip; Path=/; HttpOnly")
|
10
|
+
#
|
11
|
+
# cookie.name # "token"
|
12
|
+
# cookie.name_and_value # "token=choc-choc-chip"
|
13
|
+
class Cookie
|
14
|
+
|
15
|
+
# Returns a list of cookies from a Hash of +headers+.
|
16
|
+
def self.list_from_headers(headers)
|
17
|
+
Array(headers["Set-Cookie"]).map { |cookie| new(cookie) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(cookie)
|
21
|
+
@cookie = cookie
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the name of the cookie.
|
25
|
+
def name
|
26
|
+
@cookie.split("=").first
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the name and value of the cookie.
|
30
|
+
def name_and_value
|
31
|
+
@cookie.split(";").first
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module HTTPI
|
2
|
+
|
3
|
+
# = HTTPI::CookieStore
|
4
|
+
#
|
5
|
+
# Stores a unique list of cookies for future requests.
|
6
|
+
#
|
7
|
+
# == Examples
|
8
|
+
#
|
9
|
+
# # Add one or more cookies to the store
|
10
|
+
# cookie_store = HTTPI::CookieStore.new
|
11
|
+
# cookie_store.add HTTPI::Cookie.new("token=choc-choc-chip; Path=/; HttpOnly")
|
12
|
+
#
|
13
|
+
# # Fetch the names and values for the "Cookie" header
|
14
|
+
# cookie_store.fetch # => "token=choc-choc-chip"
|
15
|
+
class CookieStore
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@cookies = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Adds one or more cookies to the store.
|
22
|
+
def add(*cookies)
|
23
|
+
cookies.each do |cookie|
|
24
|
+
@cookies[cookie.name] = cookie.name_and_value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the names and values for the "Cookie" header.
|
29
|
+
def fetch
|
30
|
+
@cookies.values.join(";") unless @cookies.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/httpi/request.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "uri"
|
2
|
+
require "httpi/cookie_store"
|
2
3
|
require "httpi/auth/config"
|
3
4
|
require "rack/utils"
|
4
5
|
|
@@ -62,6 +63,12 @@ module HTTPI
|
|
62
63
|
headers["Accept-Encoding"] = "gzip,deflate"
|
63
64
|
end
|
64
65
|
|
66
|
+
# Sets the cookies from a given +http_response+.
|
67
|
+
def set_cookies(http_response)
|
68
|
+
cookie_store.add *http_response.cookies
|
69
|
+
headers["Cookie"] = cookie_store.fetch
|
70
|
+
end
|
71
|
+
|
65
72
|
attr_accessor :open_timeout, :read_timeout
|
66
73
|
attr_reader :body
|
67
74
|
|
@@ -87,6 +94,11 @@ module HTTPI
|
|
87
94
|
|
88
95
|
private
|
89
96
|
|
97
|
+
# Stores the cookies from past requests.
|
98
|
+
def cookie_store
|
99
|
+
@cookie_store ||= CookieStore.new
|
100
|
+
end
|
101
|
+
|
90
102
|
# Expects a +url+, validates its validity and returns a +URI+ object.
|
91
103
|
def normalize_url!(url)
|
92
104
|
raise ArgumentError, "Invalid URL: #{url}" unless url.to_s =~ /^http/
|
data/lib/httpi/response.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "zlib"
|
2
2
|
require "stringio"
|
3
3
|
require "httpi/dime"
|
4
|
+
require "httpi/cookie"
|
4
5
|
require "rack/utils"
|
5
6
|
|
6
7
|
module HTTPI
|
@@ -32,6 +33,11 @@ module HTTPI
|
|
32
33
|
!!(headers["Content-Type"] =~ /^multipart/i)
|
33
34
|
end
|
34
35
|
|
36
|
+
# Returns a list of cookies from the response.
|
37
|
+
def cookies
|
38
|
+
@cookies ||= Cookie.list_from_headers(headers)
|
39
|
+
end
|
40
|
+
|
35
41
|
# Returns any DIME attachments.
|
36
42
|
def attachments
|
37
43
|
decode_body unless @body
|
data/lib/httpi/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi"
|
3
|
+
|
4
|
+
describe HTTPI::Cookie do
|
5
|
+
|
6
|
+
let(:cookie) { HTTPI::Cookie.new("token=choc-choc-chip; Path=/; HttpOnly") }
|
7
|
+
|
8
|
+
describe ".list_from_headers" do
|
9
|
+
it "returns a list of cookies from a Hash of headers" do
|
10
|
+
headers = { "Set-Cookie" => "token=strawberry; Path=/; HttpOnly" }
|
11
|
+
cookies = HTTPI::Cookie.list_from_headers(headers)
|
12
|
+
|
13
|
+
cookies.should have(1).item
|
14
|
+
cookies.first.should be_a(HTTPI::Cookie)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "handles multiple cookies" do
|
18
|
+
headers = { "Set-Cookie" => ["user=chucknorris; Path=/; HttpOnly", "token=strawberry; Path=/; HttpOnly"] }
|
19
|
+
cookies = HTTPI::Cookie.list_from_headers(headers)
|
20
|
+
cookies.should have(2).items
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#name" do
|
25
|
+
it "returns the name of the cookie" do
|
26
|
+
cookie.name.should == "token"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#name_and_value" do
|
31
|
+
it "returns the name and value of the cookie" do
|
32
|
+
cookie.name_and_value.should == "token=choc-choc-chip"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi"
|
3
|
+
|
4
|
+
describe HTTPI::CookieStore do
|
5
|
+
|
6
|
+
let(:user_cookie) { some_cookie(:user, "chucknorris") }
|
7
|
+
let(:token_cookie) { some_cookie(:token, "strawberry") }
|
8
|
+
|
9
|
+
it "stores a set of cookies" do
|
10
|
+
cookie_store = HTTPI::CookieStore.new
|
11
|
+
cookie_store.add(user_cookie, token_cookie)
|
12
|
+
cookie_store.fetch.should include("user=chucknorris", "token=strawberry")
|
13
|
+
|
14
|
+
# add a new token cookie with a different value
|
15
|
+
token_cookie = some_cookie(:token, "choc-choc-chip")
|
16
|
+
cookie_store.add(token_cookie)
|
17
|
+
|
18
|
+
cookie_store.fetch.should include("token=choc-choc-chip")
|
19
|
+
cookie_store.fetch.should_not include("token=strawberry")
|
20
|
+
end
|
21
|
+
|
22
|
+
def some_cookie(name, value)
|
23
|
+
HTTPI::Cookie.new("#{name}=#{value}; Path=/; HttpOnly")
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/spec/httpi/request_spec.rb
CHANGED
@@ -100,6 +100,29 @@ describe HTTPI::Request do
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
describe "#set_cookies" do
|
104
|
+
it "sets the cookie header for the next request" do
|
105
|
+
request.set_cookies response_with_cookie("some-cookie=choc-chip")
|
106
|
+
request.headers["Cookie"].should == "some-cookie=choc-chip"
|
107
|
+
end
|
108
|
+
|
109
|
+
it "sets additional cookies from subsequent requests" do
|
110
|
+
request.set_cookies response_with_cookie("some-cookie=choc-chip")
|
111
|
+
request.set_cookies response_with_cookie("second-cookie=oatmeal")
|
112
|
+
|
113
|
+
request.headers["Cookie"].should include("some-cookie=choc-chip", "second-cookie=oatmeal")
|
114
|
+
end
|
115
|
+
|
116
|
+
it "doesn't do anything if the response contains no cookies" do
|
117
|
+
request.set_cookies HTTPI::Response.new(200, {}, "")
|
118
|
+
request.headers["Cookie"].should be_nil
|
119
|
+
end
|
120
|
+
|
121
|
+
def response_with_cookie(cookie)
|
122
|
+
HTTPI::Response.new(200, { "Set-Cookie" => "#{cookie}; Path=/; HttpOnly" }, "")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
103
126
|
describe "#body" do
|
104
127
|
it "lets you specify the HTTP request body using a String" do
|
105
128
|
request.body = "<some>xml</some>"
|
data/spec/httpi/response_spec.rb
CHANGED
@@ -34,6 +34,23 @@ describe HTTPI::Response do
|
|
34
34
|
response.should_not be_multipart
|
35
35
|
end
|
36
36
|
end
|
37
|
+
|
38
|
+
describe "#cookies" do
|
39
|
+
it "returns an empty list" do
|
40
|
+
response.cookies.should == []
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with cookies" do
|
46
|
+
let(:response) { HTTPI::Response.new 200, { "Set-Cookie" => "some-cookie=choc-chip; Path=/; HttpOnly" }, "" }
|
47
|
+
|
48
|
+
describe "#cookies" do
|
49
|
+
it "returns a list of cookies" do
|
50
|
+
cookie = response.cookies.first
|
51
|
+
cookie.should be_a(HTTPI::Cookie)
|
52
|
+
end
|
53
|
+
end
|
37
54
|
end
|
38
55
|
|
39
56
|
context "empty" do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Daniel Harrington
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-06-
|
19
|
+
date: 2012-06-28 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -150,6 +150,8 @@ files:
|
|
150
150
|
- lib/httpi/adapter/net_http.rb
|
151
151
|
- lib/httpi/auth/config.rb
|
152
152
|
- lib/httpi/auth/ssl.rb
|
153
|
+
- lib/httpi/cookie.rb
|
154
|
+
- lib/httpi/cookie_store.rb
|
153
155
|
- lib/httpi/dime.rb
|
154
156
|
- lib/httpi/request.rb
|
155
157
|
- lib/httpi/response.rb
|
@@ -167,6 +169,8 @@ files:
|
|
167
169
|
- spec/httpi/adapter_spec.rb
|
168
170
|
- spec/httpi/auth/config_spec.rb
|
169
171
|
- spec/httpi/auth/ssl_spec.rb
|
172
|
+
- spec/httpi/cookie_spec.rb
|
173
|
+
- spec/httpi/cookie_store_spec.rb
|
170
174
|
- spec/httpi/httpi_spec.rb
|
171
175
|
- spec/httpi/request_spec.rb
|
172
176
|
- spec/httpi/response_spec.rb
|