chef-api 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/chef-api.gemspec +1 -0
- data/lib/chef-api/connection.rb +171 -1
- data/lib/chef-api/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80b62ceb2d3f3e1b7046d2115d6b741bc983499b
|
4
|
+
data.tar.gz: ade937778aea1f66776c212918e73565ed5f1bd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebb178741c859052b3762e52ec0d9da19b6b9bb9df52099319e028813e03b776e1ca8401dc9506bcd65a3be8a683e631c0acc89da3d1090a98a0e549e9d16b87
|
7
|
+
data.tar.gz: bd0cb8413f6add6ddac6c2f60d38a68b87d63e905a20eb2e92b36a77b7afd61d204de15242be4287e8e3d9717c38034b63fc664eae086f7823c9444281552422
|
data/CHANGELOG.md
CHANGED
data/chef-api.gemspec
CHANGED
data/lib/chef-api/connection.rb
CHANGED
@@ -204,7 +204,16 @@ module ChefAPI
|
|
204
204
|
if data.respond_to?(:read)
|
205
205
|
request.body_stream = data
|
206
206
|
elsif data.is_a?(Hash)
|
207
|
-
|
207
|
+
# If any of the values in the hash are File-like, assume this is a
|
208
|
+
# multi-part post
|
209
|
+
if data.values.any? { |value| value.respond_to?(:read) }
|
210
|
+
multipart = Multipart::Body.new(data)
|
211
|
+
request.content_length = multipart.content_length
|
212
|
+
request.content_type = multipart.content_type
|
213
|
+
request.body_stream = multipart.stream
|
214
|
+
else
|
215
|
+
request.form_data = data
|
216
|
+
end
|
208
217
|
else
|
209
218
|
request.body = data
|
210
219
|
end
|
@@ -503,4 +512,165 @@ module ChefAPI
|
|
503
512
|
end
|
504
513
|
end
|
505
514
|
end
|
515
|
+
|
516
|
+
require 'cgi'
|
517
|
+
require 'mime/types'
|
518
|
+
|
519
|
+
module Multipart
|
520
|
+
BOUNDARY = '------ChefAPIMultipartBoundary'.freeze
|
521
|
+
|
522
|
+
class Body
|
523
|
+
def initialize(params = {})
|
524
|
+
params.each do |key, value|
|
525
|
+
if value.respond_to?(:read)
|
526
|
+
parts << FilePart.new(key, value)
|
527
|
+
else
|
528
|
+
parts << ParamPart.new(key, value)
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
parts << EndingPart.new
|
533
|
+
end
|
534
|
+
|
535
|
+
def stream
|
536
|
+
MultiIO.new(*parts.map(&:io))
|
537
|
+
end
|
538
|
+
|
539
|
+
def content_type
|
540
|
+
"multipart/form-data; boundary=#{BOUNDARY}"
|
541
|
+
end
|
542
|
+
|
543
|
+
def content_length
|
544
|
+
parts.map(&:size).inject(:+)
|
545
|
+
end
|
546
|
+
|
547
|
+
private
|
548
|
+
|
549
|
+
def parts
|
550
|
+
@parts ||= []
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
class MultiIO
|
555
|
+
def initialize(*ios)
|
556
|
+
@ios = ios
|
557
|
+
@index = 0
|
558
|
+
end
|
559
|
+
|
560
|
+
# Read from IOs in order until `length` bytes have been received.
|
561
|
+
def read(length = nil, outbuf = nil)
|
562
|
+
got_result = false
|
563
|
+
outbuf = outbuf ? outbuf.replace('') : ''
|
564
|
+
|
565
|
+
while io = current_io
|
566
|
+
if result = io.read(length)
|
567
|
+
got_result ||= !result.nil?
|
568
|
+
result.force_encoding('BINARY') if result.respond_to?(:force_encoding)
|
569
|
+
outbuf << result
|
570
|
+
length -= result.length if length
|
571
|
+
break if length == 0
|
572
|
+
end
|
573
|
+
advance_io
|
574
|
+
end
|
575
|
+
|
576
|
+
(!got_result && length) ? nil : outbuf
|
577
|
+
end
|
578
|
+
|
579
|
+
def rewind
|
580
|
+
@ios.each { |io| io.rewind }
|
581
|
+
@index = 0
|
582
|
+
end
|
583
|
+
|
584
|
+
private
|
585
|
+
|
586
|
+
def current_io
|
587
|
+
@ios[@index]
|
588
|
+
end
|
589
|
+
|
590
|
+
def advance_io
|
591
|
+
@index += 1
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
#
|
596
|
+
# A generic key => value part.
|
597
|
+
#
|
598
|
+
class ParamPart
|
599
|
+
def initialize(name, value)
|
600
|
+
@part = build(name, value)
|
601
|
+
end
|
602
|
+
|
603
|
+
def io
|
604
|
+
@io ||= StringIO.new(@part)
|
605
|
+
end
|
606
|
+
|
607
|
+
def size
|
608
|
+
@part.bytesize
|
609
|
+
end
|
610
|
+
|
611
|
+
private
|
612
|
+
|
613
|
+
def build(name, value)
|
614
|
+
part = %|--#{BOUNDARY}\r\n|
|
615
|
+
part << %|Content-Disposition: form-data; name="#{CGI.escape(name)}"\r\n\r\n|
|
616
|
+
part << %|#{value}\r\n|
|
617
|
+
part
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
#
|
622
|
+
# A File part
|
623
|
+
#
|
624
|
+
class FilePart
|
625
|
+
def initialize(name, file)
|
626
|
+
@file = file
|
627
|
+
@head = build(name, file)
|
628
|
+
@foot = "\r\n"
|
629
|
+
end
|
630
|
+
|
631
|
+
def io
|
632
|
+
@io ||= MultiIO.new(
|
633
|
+
StringIO.new(@head),
|
634
|
+
@file,
|
635
|
+
StringIO.new(@foot)
|
636
|
+
)
|
637
|
+
end
|
638
|
+
|
639
|
+
def size
|
640
|
+
@head.bytesize + @file.size + @foot.bytesize
|
641
|
+
end
|
642
|
+
|
643
|
+
private
|
644
|
+
|
645
|
+
def build(name, file)
|
646
|
+
filename = File.basename(file.path)
|
647
|
+
mime_type = MIME::Types.type_for(filename)[0] || MIME::Types['application/octet-stream'][0]
|
648
|
+
|
649
|
+
part = %|--#{BOUNDARY}\r\n|
|
650
|
+
part << %|Content-Disposition: form-data; name="#{CGI.escape(name)}"; filename="#{filename}"\r\n|
|
651
|
+
part << %|Content-Length: #{file.size}\r\n|
|
652
|
+
part << %|Content-Type: #{mime_type.simplified}|
|
653
|
+
part << %|Content-Transfer-Encoding: binary\r\n|
|
654
|
+
part << %|\r\n|
|
655
|
+
part
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
659
|
+
#
|
660
|
+
# The end of the entire request
|
661
|
+
#
|
662
|
+
class EndingPart
|
663
|
+
def initialize
|
664
|
+
@part = "--#{BOUNDARY}--\r\n\r\n"
|
665
|
+
end
|
666
|
+
|
667
|
+
def io
|
668
|
+
@io ||= StringIO.new(@part)
|
669
|
+
end
|
670
|
+
|
671
|
+
def size
|
672
|
+
@part.bytesize
|
673
|
+
end
|
674
|
+
end
|
675
|
+
end
|
506
676
|
end
|
data/lib/chef-api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seth Vargo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06
|
11
|
+
date: 2014-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logify
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mime-types
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.3'
|
41
55
|
description: A tiny Chef API client with minimal dependencies
|
42
56
|
email:
|
43
57
|
- sethvargo@gmail.com
|
@@ -138,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
152
|
version: '0'
|
139
153
|
requirements: []
|
140
154
|
rubyforge_project:
|
141
|
-
rubygems_version: 2.
|
155
|
+
rubygems_version: 2.3.0
|
142
156
|
signing_key:
|
143
157
|
specification_version: 4
|
144
158
|
summary: A Chef API client in Ruby
|