httpsimple 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
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"