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 CHANGED
@@ -1,3 +1,8 @@
1
+ ## 1.1.0
2
+
3
+ * Refactoring: Moved code that sets the cookies from the last response for the
4
+ next request from Savon to `HTTPI::Request#set_cookies`.
5
+
1
6
  ## 1.0.0 (2012-06-07)
2
7
 
3
8
  * Feature: [#48](https://github.com/rubiii/httpi/pull/48) @jheiss added support
@@ -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/
@@ -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
@@ -1,5 +1,5 @@
1
1
  module HTTPI
2
2
 
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.0"
4
4
 
5
5
  end
@@ -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
@@ -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>"
@@ -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: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 0
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-07 00:00:00 Z
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