piko-clean-pkg 0.0.1

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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/httparty-0.24.2/CONTRIBUTING.md +23 -0
  3. data/httparty-0.24.2/Changelog.md +624 -0
  4. data/httparty-0.24.2/Gemfile +27 -0
  5. data/httparty-0.24.2/Guardfile +17 -0
  6. data/httparty-0.24.2/MIT-LICENSE +20 -0
  7. data/httparty-0.24.2/README.md +79 -0
  8. data/httparty-0.24.2/Rakefile +10 -0
  9. data/httparty-0.24.2/bin/httparty +123 -0
  10. data/httparty-0.24.2/cucumber.yml +1 -0
  11. data/httparty-0.24.2/docs/README.md +223 -0
  12. data/httparty-0.24.2/examples/README.md +90 -0
  13. data/httparty-0.24.2/examples/aaws.rb +36 -0
  14. data/httparty-0.24.2/examples/basic.rb +28 -0
  15. data/httparty-0.24.2/examples/body_stream.rb +14 -0
  16. data/httparty-0.24.2/examples/crack.rb +19 -0
  17. data/httparty-0.24.2/examples/custom_parsers.rb +68 -0
  18. data/httparty-0.24.2/examples/delicious.rb +37 -0
  19. data/httparty-0.24.2/examples/google.rb +16 -0
  20. data/httparty-0.24.2/examples/headers_and_user_agents.rb +10 -0
  21. data/httparty-0.24.2/examples/idn.rb +10 -0
  22. data/httparty-0.24.2/examples/logging.rb +36 -0
  23. data/httparty-0.24.2/examples/microsoft_graph.rb +52 -0
  24. data/httparty-0.24.2/examples/multipart.rb +35 -0
  25. data/httparty-0.24.2/examples/nokogiri_html_parser.rb +19 -0
  26. data/httparty-0.24.2/examples/party_foul_mode.rb +90 -0
  27. data/httparty-0.24.2/examples/peer_cert.rb +9 -0
  28. data/httparty-0.24.2/examples/rescue_json.rb +17 -0
  29. data/httparty-0.24.2/examples/rubyurl.rb +14 -0
  30. data/httparty-0.24.2/examples/stackexchange.rb +24 -0
  31. data/httparty-0.24.2/examples/stream_download.rb +26 -0
  32. data/httparty-0.24.2/examples/tripit_sign_in.rb +44 -0
  33. data/httparty-0.24.2/examples/twitter.rb +31 -0
  34. data/httparty-0.24.2/examples/whoismyrep.rb +10 -0
  35. data/httparty-0.24.2/httparty.gemspec +32 -0
  36. data/httparty-0.24.2/lib/httparty/connection_adapter.rb +237 -0
  37. data/httparty-0.24.2/lib/httparty/cookie_hash.rb +23 -0
  38. data/httparty-0.24.2/lib/httparty/decompressor.rb +102 -0
  39. data/httparty-0.24.2/lib/httparty/exceptions.rb +66 -0
  40. data/httparty-0.24.2/lib/httparty/hash_conversions.rb +71 -0
  41. data/httparty-0.24.2/lib/httparty/headers_processor.rb +32 -0
  42. data/httparty-0.24.2/lib/httparty/logger/apache_formatter.rb +47 -0
  43. data/httparty-0.24.2/lib/httparty/logger/curl_formatter.rb +93 -0
  44. data/httparty-0.24.2/lib/httparty/logger/logger.rb +30 -0
  45. data/httparty-0.24.2/lib/httparty/logger/logstash_formatter.rb +62 -0
  46. data/httparty-0.24.2/lib/httparty/module_inheritable_attributes.rb +56 -0
  47. data/httparty-0.24.2/lib/httparty/net_digest_auth.rb +135 -0
  48. data/httparty-0.24.2/lib/httparty/parser.rb +157 -0
  49. data/httparty-0.24.2/lib/httparty/request/body.rb +125 -0
  50. data/httparty-0.24.2/lib/httparty/request/multipart_boundary.rb +13 -0
  51. data/httparty-0.24.2/lib/httparty/request/streaming_multipart_body.rb +190 -0
  52. data/httparty-0.24.2/lib/httparty/request.rb +466 -0
  53. data/httparty-0.24.2/lib/httparty/response/headers.rb +35 -0
  54. data/httparty-0.24.2/lib/httparty/response.rb +156 -0
  55. data/httparty-0.24.2/lib/httparty/response_fragment.rb +21 -0
  56. data/httparty-0.24.2/lib/httparty/text_encoder.rb +72 -0
  57. data/httparty-0.24.2/lib/httparty/utils.rb +13 -0
  58. data/httparty-0.24.2/lib/httparty/version.rb +5 -0
  59. data/httparty-0.24.2/lib/httparty.rb +699 -0
  60. data/httparty-0.24.2/script/release +42 -0
  61. data/httparty-0.24.2/website/css/common.css +47 -0
  62. data/httparty-0.24.2/website/index.html +73 -0
  63. data/piko-clean-pkg.gemspec +12 -0
  64. metadata +103 -0
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HTTParty
4
+ class Request
5
+ class StreamingMultipartBody
6
+ NEWLINE = "\r\n"
7
+ CHUNK_SIZE = 64 * 1024 # 64 KB chunks
8
+
9
+ def initialize(parts, boundary)
10
+ @parts = parts
11
+ @boundary = boundary
12
+ @part_index = 0
13
+ @state = :header
14
+ @current_file = nil
15
+ @header_buffer = nil
16
+ @header_offset = 0
17
+ @footer_sent = false
18
+ end
19
+
20
+ def size
21
+ @size ||= calculate_size
22
+ end
23
+
24
+ def read(length = nil, outbuf = nil)
25
+ outbuf = outbuf ? outbuf.replace(''.b) : ''.b
26
+
27
+ return read_all(outbuf) if length.nil?
28
+
29
+ while outbuf.bytesize < length
30
+ chunk = read_chunk(length - outbuf.bytesize)
31
+ break if chunk.nil?
32
+ outbuf << chunk
33
+ end
34
+
35
+ outbuf.empty? ? nil : outbuf
36
+ end
37
+
38
+ def rewind
39
+ @part_index = 0
40
+ @state = :header
41
+ @current_file = nil
42
+ @header_buffer = nil
43
+ @header_offset = 0
44
+ @footer_sent = false
45
+ @parts.each do |_key, value, _is_file|
46
+ value.rewind if value.respond_to?(:rewind)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def read_all(outbuf)
53
+ while (chunk = read_chunk(CHUNK_SIZE))
54
+ outbuf << chunk
55
+ end
56
+ outbuf.empty? ? nil : outbuf
57
+ end
58
+
59
+ def read_chunk(max_length)
60
+ loop do
61
+ return nil if @part_index >= @parts.size && @footer_sent
62
+
63
+ if @part_index >= @parts.size
64
+ @footer_sent = true
65
+ return "--#{@boundary}--#{NEWLINE}".b
66
+ end
67
+
68
+ key, value, is_file = @parts[@part_index]
69
+
70
+ case @state
71
+ when :header
72
+ chunk = read_header_chunk(key, value, is_file, max_length)
73
+ return chunk if chunk
74
+
75
+ when :body
76
+ chunk = read_body_chunk(value, is_file, max_length)
77
+ return chunk if chunk
78
+
79
+ when :newline
80
+ @state = :header
81
+ @part_index += 1
82
+ return NEWLINE.b
83
+ end
84
+ end
85
+ end
86
+
87
+ def read_header_chunk(key, value, is_file, max_length)
88
+ if @header_buffer.nil?
89
+ @header_buffer = build_part_header(key, value, is_file)
90
+ @header_offset = 0
91
+ end
92
+
93
+ remaining = @header_buffer.bytesize - @header_offset
94
+ if remaining > 0
95
+ chunk_size = [remaining, max_length].min
96
+ chunk = @header_buffer.byteslice(@header_offset, chunk_size)
97
+ @header_offset += chunk_size
98
+ return chunk
99
+ end
100
+
101
+ @header_buffer = nil
102
+ @header_offset = 0
103
+ @state = :body
104
+ nil
105
+ end
106
+
107
+ def read_body_chunk(value, is_file, max_length)
108
+ if is_file
109
+ chunk = read_file_chunk(value, max_length)
110
+ if chunk
111
+ return chunk
112
+ else
113
+ @current_file = nil
114
+ @state = :newline
115
+ return nil
116
+ end
117
+ else
118
+ @state = :newline
119
+ return value.to_s.b
120
+ end
121
+ end
122
+
123
+ def read_file_chunk(file, max_length)
124
+ chunk_size = [max_length, CHUNK_SIZE].min
125
+ chunk = file.read(chunk_size)
126
+ return nil if chunk.nil?
127
+ chunk.force_encoding(Encoding::BINARY) if chunk.respond_to?(:force_encoding)
128
+ chunk
129
+ end
130
+
131
+ def build_part_header(key, value, is_file)
132
+ header = "--#{@boundary}#{NEWLINE}".b
133
+ header << %(Content-Disposition: form-data; name="#{key}").b
134
+ if is_file
135
+ header << %(; filename="#{file_name(value).gsub(/["\r\n]/, replacement_table)}").b
136
+ header << NEWLINE.b
137
+ header << "Content-Type: #{content_type(value)}#{NEWLINE}".b
138
+ else
139
+ header << NEWLINE.b
140
+ end
141
+ header << NEWLINE.b
142
+ header
143
+ end
144
+
145
+ def calculate_size
146
+ total = 0
147
+ @parts.each do |key, value, is_file|
148
+ total += build_part_header(key, value, is_file).bytesize
149
+ total += content_size(value, is_file)
150
+ total += NEWLINE.bytesize
151
+ end
152
+ total += "--#{@boundary}--#{NEWLINE}".bytesize
153
+ total
154
+ end
155
+
156
+ def content_size(value, is_file)
157
+ if is_file
158
+ if value.respond_to?(:size)
159
+ value.size
160
+ elsif value.respond_to?(:stat)
161
+ value.stat.size
162
+ else
163
+ value.read.bytesize.tap { value.rewind }
164
+ end
165
+ else
166
+ value.to_s.b.bytesize
167
+ end
168
+ end
169
+
170
+ def content_type(object)
171
+ return object.content_type if object.respond_to?(:content_type)
172
+ require 'mini_mime'
173
+ mime = MiniMime.lookup_by_filename(object.path)
174
+ mime ? mime.content_type : 'application/octet-stream'
175
+ end
176
+
177
+ def file_name(object)
178
+ object.respond_to?(:original_filename) ? object.original_filename : File.basename(object.path)
179
+ end
180
+
181
+ def replacement_table
182
+ @replacement_table ||= {
183
+ '"' => '%22',
184
+ "\r" => '%0D',
185
+ "\n" => '%0A'
186
+ }.freeze
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,466 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
4
+
5
+ module HTTParty
6
+ class Request #:nodoc:
7
+ SupportedHTTPMethods = [
8
+ Net::HTTP::Get,
9
+ Net::HTTP::Post,
10
+ Net::HTTP::Patch,
11
+ Net::HTTP::Put,
12
+ Net::HTTP::Delete,
13
+ Net::HTTP::Head,
14
+ Net::HTTP::Options,
15
+ Net::HTTP::Move,
16
+ Net::HTTP::Copy,
17
+ Net::HTTP::Mkcol,
18
+ Net::HTTP::Lock,
19
+ Net::HTTP::Unlock,
20
+ ]
21
+
22
+ SupportedURISchemes = ['http', 'https', 'webcal', nil]
23
+
24
+ NON_RAILS_QUERY_STRING_NORMALIZER = proc do |query|
25
+ Array(query).sort_by { |a| a[0].to_s }.map do |key, value|
26
+ if value.nil?
27
+ key.to_s
28
+ elsif value.respond_to?(:to_ary)
29
+ value.to_ary.map {|v| "#{key}=#{ERB::Util.url_encode(v.to_s)}"}
30
+ else
31
+ HashConversions.to_params(key => value)
32
+ end
33
+ end.flatten.join('&')
34
+ end
35
+
36
+ JSON_API_QUERY_STRING_NORMALIZER = proc do |query|
37
+ Array(query).sort_by { |a| a[0].to_s }.map do |key, value|
38
+ if value.nil?
39
+ key.to_s
40
+ elsif value.respond_to?(:to_ary)
41
+ values = value.to_ary.map{|v| ERB::Util.url_encode(v.to_s)}
42
+ "#{key}=#{values.join(',')}"
43
+ else
44
+ HashConversions.to_params(key => value)
45
+ end
46
+ end.flatten.join('&')
47
+ end
48
+
49
+ def self._load(data)
50
+ http_method, path, options, last_response, last_uri, raw_request = Marshal.load(data)
51
+ instance = new(http_method, path, options)
52
+ instance.last_response = last_response
53
+ instance.last_uri = last_uri
54
+ instance.instance_variable_set("@raw_request", raw_request)
55
+ instance
56
+ end
57
+
58
+ attr_accessor :http_method, :options, :last_response, :redirect, :last_uri
59
+ attr_reader :path
60
+
61
+ def initialize(http_method, path, o = {})
62
+ @changed_hosts = false
63
+ @credentials_sent = false
64
+
65
+ self.http_method = http_method
66
+ self.options = {
67
+ limit: o.delete(:no_follow) ? 1 : 5,
68
+ assume_utf16_is_big_endian: true,
69
+ default_params: {},
70
+ follow_redirects: true,
71
+ parser: Parser,
72
+ uri_adapter: URI,
73
+ connection_adapter: ConnectionAdapter
74
+ }.merge(o)
75
+ self.path = path
76
+ set_basic_auth_from_uri
77
+ end
78
+
79
+ def path=(uri)
80
+ uri_adapter = options[:uri_adapter]
81
+
82
+ @path = if uri.is_a?(uri_adapter)
83
+ uri
84
+ elsif String.try_convert(uri)
85
+ uri_adapter.parse(uri).normalize
86
+ else
87
+ raise ArgumentError,
88
+ "bad argument (expected #{uri_adapter} object or URI string)"
89
+ end
90
+ end
91
+
92
+ def request_uri(uri)
93
+ if uri.respond_to? :request_uri
94
+ uri.request_uri
95
+ else
96
+ uri.path
97
+ end
98
+ end
99
+
100
+ def uri
101
+ if redirect && path.relative? && path.path[0] != '/'
102
+ last_uri_host = @last_uri.path.gsub(/[^\/]+$/, '')
103
+
104
+ path.path = "/#{path.path}" if last_uri_host[-1] != '/'
105
+ path.path = "#{last_uri_host}#{path.path}"
106
+ end
107
+
108
+ if path.relative? && path.host
109
+ new_uri = options[:uri_adapter].parse("#{@last_uri.scheme}:#{path}").normalize
110
+ elsif path.relative?
111
+ new_uri = options[:uri_adapter].parse("#{base_uri}#{path}").normalize
112
+ else
113
+ new_uri = path.clone
114
+ end
115
+
116
+ validate_uri_safety!(new_uri) unless redirect
117
+
118
+ # avoid double query string on redirects [#12]
119
+ unless redirect
120
+ new_uri.query = query_string(new_uri)
121
+ end
122
+
123
+ unless SupportedURISchemes.include? new_uri.scheme
124
+ raise UnsupportedURIScheme, "'#{new_uri}' Must be HTTP, HTTPS or Generic"
125
+ end
126
+
127
+ @last_uri = new_uri
128
+ end
129
+
130
+ def base_uri
131
+ if redirect
132
+ base_uri = "#{@last_uri.scheme}://#{@last_uri.host}"
133
+ base_uri = "#{base_uri}:#{@last_uri.port}" if @last_uri.port != 80
134
+ base_uri
135
+ else
136
+ options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri])
137
+ end
138
+ end
139
+
140
+ def format
141
+ options[:format] || (format_from_mimetype(last_response['content-type']) if last_response)
142
+ end
143
+
144
+ def parser
145
+ options[:parser]
146
+ end
147
+
148
+ def connection_adapter
149
+ options[:connection_adapter]
150
+ end
151
+
152
+ def perform(&block)
153
+ validate
154
+ setup_raw_request
155
+ chunked_body = nil
156
+ current_http = http
157
+
158
+ begin
159
+ self.last_response = current_http.request(@raw_request) do |http_response|
160
+ if block
161
+ chunks = []
162
+
163
+ http_response.read_body do |fragment|
164
+ encoded_fragment = encode_text(fragment, http_response['content-type'])
165
+ chunks << encoded_fragment if !options[:stream_body]
166
+ block.call ResponseFragment.new(encoded_fragment, http_response, current_http)
167
+ end
168
+
169
+ chunked_body = chunks.join
170
+ end
171
+ end
172
+
173
+ handle_host_redirection if response_redirects?
174
+ result = handle_unauthorized
175
+ result ||= handle_response(chunked_body, &block)
176
+ result
177
+ rescue *COMMON_NETWORK_ERRORS => e
178
+ raise options[:foul] ? HTTParty::NetworkError.new("#{e.class}: #{e.message}") : e
179
+ end
180
+ end
181
+
182
+ def handle_unauthorized(&block)
183
+ return unless digest_auth? && response_unauthorized? && response_has_digest_auth_challenge?
184
+ return if @credentials_sent
185
+ @credentials_sent = true
186
+ perform(&block)
187
+ end
188
+
189
+ def raw_body
190
+ @raw_request.body
191
+ end
192
+
193
+ def _dump(_level)
194
+ opts = options.dup
195
+ opts.delete(:logger)
196
+ opts.delete(:parser) if opts[:parser] && opts[:parser].is_a?(Proc)
197
+ Marshal.dump([http_method, path, opts, last_response, @last_uri, @raw_request])
198
+ end
199
+
200
+ private
201
+
202
+ def http
203
+ connection_adapter.call(uri, options)
204
+ end
205
+
206
+ def credentials
207
+ (options[:basic_auth] || options[:digest_auth]).to_hash
208
+ end
209
+
210
+ def username
211
+ credentials[:username]
212
+ end
213
+
214
+ def password
215
+ credentials[:password]
216
+ end
217
+
218
+ def normalize_query(query)
219
+ if query_string_normalizer
220
+ query_string_normalizer.call(query)
221
+ else
222
+ HashConversions.to_params(query)
223
+ end
224
+ end
225
+
226
+ def query_string_normalizer
227
+ options[:query_string_normalizer]
228
+ end
229
+
230
+ def setup_raw_request
231
+ if options[:headers].respond_to?(:to_hash)
232
+ headers_hash = options[:headers].to_hash
233
+ else
234
+ headers_hash = nil
235
+ end
236
+
237
+ @raw_request = http_method.new(request_uri(uri), headers_hash)
238
+ @raw_request.body_stream = options[:body_stream] if options[:body_stream]
239
+
240
+ if options[:body]
241
+ body = Body.new(
242
+ options[:body],
243
+ query_string_normalizer: query_string_normalizer,
244
+ force_multipart: options[:multipart]
245
+ )
246
+
247
+ if body.multipart?
248
+ content_type = "multipart/form-data; boundary=#{body.boundary}"
249
+ @raw_request['Content-Type'] = content_type
250
+ elsif options[:body].respond_to?(:to_hash) && !@raw_request['Content-Type']
251
+ @raw_request['Content-Type'] = 'application/x-www-form-urlencoded'
252
+ end
253
+
254
+ if body.streaming? && options[:stream_body] == true
255
+ stream = body.to_stream
256
+ @raw_request.body_stream = stream
257
+ @raw_request['Content-Length'] = stream.size.to_s
258
+ else
259
+ @raw_request.body = body.call
260
+ end
261
+ end
262
+
263
+ @raw_request.instance_variable_set(:@decode_content, decompress_content?)
264
+
265
+ if options[:basic_auth] && send_authorization_header?
266
+ @raw_request.basic_auth(username, password)
267
+ @credentials_sent = true
268
+ end
269
+ setup_digest_auth if digest_auth? && response_unauthorized? && response_has_digest_auth_challenge?
270
+ end
271
+
272
+ def digest_auth?
273
+ !!options[:digest_auth]
274
+ end
275
+
276
+ def decompress_content?
277
+ !options[:skip_decompression]
278
+ end
279
+
280
+ def response_unauthorized?
281
+ !!last_response && last_response.code == '401'
282
+ end
283
+
284
+ def response_has_digest_auth_challenge?
285
+ !last_response['www-authenticate'].nil? && last_response['www-authenticate'].length > 0
286
+ end
287
+
288
+ def setup_digest_auth
289
+ @raw_request.digest_auth(username, password, last_response)
290
+ end
291
+
292
+ def query_string(uri)
293
+ query_string_parts = []
294
+ query_string_parts << uri.query unless uri.query.nil?
295
+
296
+ if options[:query].respond_to?(:to_hash)
297
+ query_string_parts << normalize_query(options[:default_params].merge(options[:query].to_hash))
298
+ else
299
+ query_string_parts << normalize_query(options[:default_params]) unless options[:default_params].empty?
300
+ query_string_parts << options[:query] unless options[:query].nil?
301
+ end
302
+
303
+ query_string_parts.reject!(&:empty?) unless query_string_parts == ['']
304
+ query_string_parts.size > 0 ? query_string_parts.join('&') : nil
305
+ end
306
+
307
+ def assume_utf16_is_big_endian
308
+ options[:assume_utf16_is_big_endian]
309
+ end
310
+
311
+ def handle_response(raw_body, &block)
312
+ if response_redirects?
313
+ handle_redirection(&block)
314
+ else
315
+ raw_body ||= last_response.body
316
+
317
+ body = decompress(raw_body, last_response['content-encoding']) unless raw_body.nil?
318
+
319
+ unless body.nil?
320
+ body = encode_text(body, last_response['content-type'])
321
+
322
+ if decompress_content?
323
+ last_response.delete('content-encoding')
324
+ raw_body = body
325
+ end
326
+ end
327
+
328
+ Response.new(self, last_response, lambda { parse_response(body) }, body: raw_body)
329
+ end
330
+ end
331
+
332
+ def handle_redirection(&block)
333
+ options[:limit] -= 1
334
+ if options[:logger]
335
+ logger = HTTParty::Logger.build(options[:logger], options[:log_level], options[:log_format])
336
+ logger.format(self, last_response)
337
+ end
338
+ self.path = last_response['location']
339
+ self.redirect = true
340
+ if last_response.class == Net::HTTPSeeOther
341
+ unless options[:maintain_method_across_redirects] && options[:resend_on_redirect]
342
+ self.http_method = Net::HTTP::Get
343
+ end
344
+ elsif last_response.code != '307' && last_response.code != '308'
345
+ unless options[:maintain_method_across_redirects]
346
+ self.http_method = Net::HTTP::Get
347
+ end
348
+ end
349
+ if http_method == Net::HTTP::Get
350
+ clear_body
351
+ end
352
+ capture_cookies(last_response)
353
+ perform(&block)
354
+ end
355
+
356
+ def handle_host_redirection
357
+ check_duplicate_location_header
358
+ redirect_path = options[:uri_adapter].parse(last_response['location']).normalize
359
+ return if redirect_path.relative? || path.host == redirect_path.host || uri.host == redirect_path.host
360
+ @changed_hosts = true
361
+ end
362
+
363
+ def check_duplicate_location_header
364
+ location = last_response.get_fields('location')
365
+ if location.is_a?(Array) && location.count > 1
366
+ raise DuplicateLocationHeader.new(last_response)
367
+ end
368
+ end
369
+
370
+ def send_authorization_header?
371
+ !@changed_hosts
372
+ end
373
+
374
+ def response_redirects?
375
+ case last_response
376
+ when Net::HTTPNotModified # 304
377
+ false
378
+ when Net::HTTPRedirection
379
+ options[:follow_redirects] && last_response.key?('location')
380
+ end
381
+ end
382
+
383
+ def parse_response(body)
384
+ parser.call(body, format)
385
+ end
386
+
387
+ # Some Web Application Firewalls reject incoming GET requests that have a body
388
+ # if we redirect, and the resulting verb is GET then we will clear the body that
389
+ # may be left behind from the initiating request
390
+ def clear_body
391
+ options[:body] = nil
392
+ @raw_request.body = nil
393
+ end
394
+
395
+ def capture_cookies(response)
396
+ return unless response['Set-Cookie']
397
+ cookies_hash = HTTParty::CookieHash.new
398
+ cookies_hash.add_cookies(options[:headers].to_hash['Cookie']) if options[:headers] && options[:headers].to_hash['Cookie']
399
+ response.get_fields('Set-Cookie').each { |cookie| cookies_hash.add_cookies(cookie) }
400
+
401
+ options[:headers] ||= {}
402
+ options[:headers]['Cookie'] = cookies_hash.to_cookie_string
403
+ end
404
+
405
+ # Uses the HTTP Content-Type header to determine the format of the
406
+ # response It compares the MIME type returned to the types stored in the
407
+ # SupportedFormats hash
408
+ def format_from_mimetype(mimetype)
409
+ if mimetype && parser.respond_to?(:format_from_mimetype)
410
+ parser.format_from_mimetype(mimetype)
411
+ end
412
+ end
413
+
414
+ def validate
415
+ raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0
416
+ raise ArgumentError, 'only get, post, patch, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method)
417
+ raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].respond_to?(:to_hash)
418
+ raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth]
419
+ raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].respond_to?(:to_hash)
420
+ raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].respond_to?(:to_hash)
421
+ raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].respond_to?(:to_hash)
422
+ end
423
+
424
+ def post?
425
+ Net::HTTP::Post == http_method
426
+ end
427
+
428
+ def set_basic_auth_from_uri
429
+ if path.userinfo
430
+ username, password = path.userinfo.split(':')
431
+ options[:basic_auth] = {username: username, password: password}
432
+ @credentials_sent = true
433
+ end
434
+ end
435
+
436
+ def decompress(body, encoding)
437
+ Decompressor.new(body, encoding).decompress
438
+ end
439
+
440
+ def encode_text(text, content_type)
441
+ TextEncoder.new(
442
+ text,
443
+ content_type: content_type,
444
+ assume_utf16_is_big_endian: assume_utf16_is_big_endian
445
+ ).call
446
+ end
447
+
448
+ def validate_uri_safety!(new_uri)
449
+ return if options[:skip_uri_validation]
450
+
451
+ configured_base_uri = options[:base_uri]
452
+ return unless configured_base_uri
453
+
454
+ normalized_base = options[:uri_adapter].parse(
455
+ HTTParty.normalize_base_uri(configured_base_uri)
456
+ )
457
+
458
+ return if new_uri.host == normalized_base.host
459
+
460
+ raise UnsafeURIError,
461
+ "Requested URI '#{new_uri}' has host '#{new_uri.host}' but the " \
462
+ "configured base_uri '#{normalized_base}' has host '#{normalized_base.host}'. " \
463
+ "This request could send credentials to an unintended server."
464
+ end
465
+ end
466
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+
5
+ module HTTParty
6
+ class Response #:nodoc:
7
+ class Headers < ::SimpleDelegator
8
+ include ::Net::HTTPHeader
9
+
10
+ def initialize(header_values = nil)
11
+ @header = {}
12
+ if header_values
13
+ header_values.each_pair do |k,v|
14
+ if v.is_a?(Array)
15
+ v.each do |sub_v|
16
+ add_field(k, sub_v)
17
+ end
18
+ else
19
+ add_field(k, v)
20
+ end
21
+ end
22
+ end
23
+ super(@header)
24
+ end
25
+
26
+ def ==(other)
27
+ if other.is_a?(::Net::HTTPHeader)
28
+ @header == other.instance_variable_get(:@header)
29
+ elsif other.is_a?(Hash)
30
+ @header == other || @header == Headers.new(other).instance_variable_get(:@header)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end