httpsimple 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/README.md +4 -0
  2. data/lib/httpsimple.rb +81 -42
  3. metadata +2 -2
data/README.md CHANGED
@@ -47,6 +47,10 @@ response = HttpSimple.post(url, :username => 'bob', :password => '1234') do |sim
47
47
  simple.max_redirects = 2
48
48
  # Turn off ssl cert verification - dangerous
49
49
  simple.strict_ssl = false
50
+ # Debug output. calls set_debug_ouput on the
51
+ # underlying Net::HTTP object passing it $stderr
52
+ # WARNING: Unsafe for production
53
+ simple.debug = true
50
54
  end
51
55
  ```
52
56
 
@@ -1,8 +1,9 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
+ require 'cgi'
3
4
 
4
5
  module HttpSimple
5
- VERSION='1.0.4'
6
+ VERSION='1.0.5'
6
7
  def self.get(url, data=nil, &block)
7
8
  request(url, :get, data, &block)
8
9
  end
@@ -46,6 +47,7 @@ module HttpSimple
46
47
  @debug = false
47
48
  # Response handlers
48
49
  @handlers = {}
50
+ @set_cookie_headers = []
49
51
 
50
52
  end
51
53
 
@@ -93,54 +95,91 @@ module HttpSimple
93
95
 
94
96
  end
95
97
 
96
- def fetch(uri, request, limit=1)
97
- http = Net::HTTP.new(uri.host, uri.port)
98
- http.use_ssl = uri.scheme == 'https'
99
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @scrict_ssl
100
- http.set_debug_output $stderr if @debug
101
- http.read_timeout = @timeout
98
+ private
99
+
100
+ def fetch(uri, request, limit=1)
101
+ http = Net::HTTP.new(uri.host, uri.port)
102
+ http.use_ssl = uri.scheme == 'https'
103
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @scrict_ssl
104
+ http.set_debug_output $stderr if @debug
105
+ http.read_timeout = @timeout
102
106
 
103
- @headers.each_pair { |k,v| request[k] = v } unless @headers.empty?
107
+ @headers.each_pair { |k,v| request[k] = v } unless @headers.empty?
104
108
 
105
- response = http.start do |http|
106
- http.request(request)
107
- end
109
+ response = http.start do |http|
110
+ http.request(request)
111
+ end
108
112
 
109
- code = response.code.to_sym
110
- if @handlers.key?(code)
111
- @handlers[code].call(http, request, response)
112
- end
113
+ code = response.code.to_sym
114
+ if @handlers.key?(code)
115
+ @handlers[code].call(http, request, response)
116
+ end
113
117
 
114
- case response
115
- when Net::HTTPSuccess
116
- return response
117
- when Net::HTTPRedirection
118
- return response unless @follow_redirects
119
- raise HTTPMaxRedirectError.new(@max_redirects) if limit == 0
120
- block = lambda { |url, req| fetch(url, req, limit - 1) }
121
- new_uri = URI(response['location'])
122
- # Handle relative redirects ie /foo
123
- new_uri = uri + new_uri unless new_uri.is_a? URI::HTTP
124
- if request.is_a? Net::HTTP::Get
125
- get(new_uri, &block)
126
- elsif request.is_a? Net::HTTP::Post
127
- post(new_uri, &block)
118
+ case response
119
+ when Net::HTTPSuccess
120
+ return update_response_cookies(response)
121
+ when Net::HTTPRedirection
122
+ return response unless @follow_redirects
123
+ raise_error_if_redirection_limit_reached(limit)
124
+ new_uri = URI(response['location'])
125
+ # Handle relative redirects ie /foo
126
+ new_uri = uri + new_uri unless new_uri.is_a? URI::HTTP
127
+ merge_request_cookies(get_cookies_for_redirect(response))
128
+ block = lambda { |url, req| fetch(url, req, limit - 1) }
129
+
130
+ if request.is_a? Net::HTTP::Get
131
+ get(new_uri, &block)
132
+ elsif request.is_a? Net::HTTP::Post
133
+ post(new_uri, &block)
134
+ end
135
+ when Net::HTTPResponse
136
+ response.error!
128
137
  end
129
- when Net::HTTPResponse
130
- response.error!
131
- end
132
138
 
133
- end
134
- private :fetch
139
+ end
135
140
 
136
- def get_path(uri)
137
- if uri.path.length == 0 and uri.query.nil?
138
- "/"
139
- elsif uri.query.nil?
140
- uri.path
141
- else
142
- "#{uri.path}?#{uri.query}"
141
+ def raise_error_if_redirection_limit_reached(limit)
142
+ raise HTTPMaxRedirectError.new(@max_redirects) if limit == 0
143
+ end
144
+
145
+ def get_cookies_for_redirect(response)
146
+ cookies = response.get_fields("set-cookie")
147
+ return if cookies.nil?
148
+ @set_cookie_headers.concat(cookies)
149
+
150
+ cookies.collect! {|raw_cookie|
151
+ name, value = get_cookie_name_value_pair(raw_cookie)
152
+ "#{name}=#{value}" unless value.nil?
153
+ }.compact!
154
+
155
+ cookies.join("; ") unless cookies.empty?
143
156
  end
144
- end
157
+
158
+ def get_cookie_name_value_pair(raw_cookie)
159
+ ignore = ["domain", "path", "expires"]
160
+ CGI::Cookie::parse(raw_cookie).each_pair { |k,v|
161
+ return k,v[0] unless ignore.include? k.downcase
162
+ }
163
+ raise ArgumentError.new("Invalid set-cookie value: #{raw_cookie}")
164
+ end
165
+
166
+ def merge_request_cookies(cookies)
167
+ # TODO: scrutinize this merging logic. Duplicate cookies from
168
+ # ``cookies`` should probably overwrite the ones in ``@headers``.
169
+ return unless !cookies.nil?
170
+ if @headers.include? "cookie"
171
+ @headers['cookie'] = [@headers['cookie'], cookies].join("; ")
172
+ else
173
+ @headers['cookie'] = cookies
174
+ end
175
+ end
176
+
177
+ def update_response_cookies(response)
178
+ @set_cookie_headers.each { |cookie|
179
+ response.header.add_field('set-cookie', cookie)
180
+ }
181
+ @set_cookie_headers = []
182
+ response
183
+ end
145
184
  end
146
185
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpsimple
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-14 00:00:00.000000000 Z
12
+ date: 2013-02-27 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! " Simple wrapper around Ruby's net/http library. It supports \n redirects
15
15
  and HTTPS.\n"