minio-ruby 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.
- checksums.yaml +7 -0
- data/lib/minio.rb +111 -0
- data/lib/minio/digest.rb +28 -0
- data/lib/minio/error.rb +10 -0
- data/lib/minio/helper.rb +18 -0
- data/lib/minio/signer.rb +169 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4e80b50c33f3bf729385175bc47e0387e8a0fce1
|
4
|
+
data.tar.gz: 2bd287d3cb03a2dea5abc42a38da1110df146bd7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cd4692fae1e4a41505644c32d2c8338b2f00f89484765d40a8ba57c9aa30f822de9f3e045e8ddadfd082536f17d4fa10621ebdb9f4cca401f5159742d76532d7
|
7
|
+
data.tar.gz: d9716ef1fc2216e79938b671716cc3d9bb6bb72d052d2156448acb6c90f0ffc5e8fa92c63361afdcf43f0964920816437316dac02b5548fe4630c273b55b8342
|
data/lib/minio.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "net/https"
|
3
|
+
require "base64"
|
4
|
+
require "openssl"
|
5
|
+
require 'uri'
|
6
|
+
require "minio/signer"
|
7
|
+
require "minio/digest"
|
8
|
+
require 'digest'
|
9
|
+
|
10
|
+
module MinioRuby
|
11
|
+
class MinioClient
|
12
|
+
attr_accessor :endPoint, :port, :accessKey, :secretKey, :secure, :transport, :region
|
13
|
+
|
14
|
+
def initialize params = {}
|
15
|
+
# TODO: add extensive error checking of params here.
|
16
|
+
params.each { |key, value| send "#{key}=", value }
|
17
|
+
end
|
18
|
+
|
19
|
+
def getObject(bucketname, objectname)
|
20
|
+
|
21
|
+
req = endPoint + '/' + bucketname + '/' + objectname
|
22
|
+
signer = MinioRuby::Signer.new(access_key: self.accessKey, secret_key:self.secretKey, region: self.region)
|
23
|
+
body = ""
|
24
|
+
headers = {}
|
25
|
+
headers = signer.sign_v4("GET", req, headers, body, true)
|
26
|
+
|
27
|
+
uri = URI.parse(self.endPoint)
|
28
|
+
https = Net::HTTP.new(uri.host,uri.port)
|
29
|
+
https.use_ssl = true
|
30
|
+
|
31
|
+
req = Net::HTTP::Get.new(self.endPoint + '/' + bucketname + '/' + objectname, initheader = headers)
|
32
|
+
req.body = body
|
33
|
+
https.set_debug_output($stdout)
|
34
|
+
response = https.request(req)
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def putObject(bucketname, objectname, data, length, content_type='application/octet-stream')
|
40
|
+
req = endPoint + '/' + bucketname + '/' + objectname
|
41
|
+
signer = MinioRuby::Signer.new(access_key: self.accessKey, secret_key: self.secretKey , region: self.region)
|
42
|
+
headers = {}
|
43
|
+
headers = signer.sign_v4("PUT", req, headers, data, true)
|
44
|
+
|
45
|
+
puts data
|
46
|
+
uri = URI.parse(self.endPoint)
|
47
|
+
https = Net::HTTP.new(uri.host,uri.port)
|
48
|
+
https.use_ssl = true
|
49
|
+
|
50
|
+
req = Net::HTTP::Put.new(self.endPoint + '/'+bucketname+'/'+objectname, initheader = headers)
|
51
|
+
req.body = data
|
52
|
+
https.set_debug_output($stdout)
|
53
|
+
response = https.request(req)
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def bucketExists(bucketname)
|
59
|
+
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def fputObject(bucketname, objectname, filepath, content_type)
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
def makeBucket(bucketname, location='us-east-1')
|
71
|
+
|
72
|
+
method = "PUT"
|
73
|
+
headers = {'User-Agent' => 'MinioRuby'}
|
74
|
+
content = ""
|
75
|
+
signer = MinioRuby::Signer.new(access_key: self.accessKey, secret_key: self.secretKey , region: self.region)
|
76
|
+
body = ""
|
77
|
+
|
78
|
+
#headers['Content-Length'] = content.length.to_s
|
79
|
+
req = self.endPoint + '/' + bucketname
|
80
|
+
|
81
|
+
|
82
|
+
content_sha256_hex = Digest::SHA256.hexdigest(content)
|
83
|
+
#headers['Content-Md5'] = Digest::MD5.base64digest(content)
|
84
|
+
|
85
|
+
headers = signer.sign_v4(method, req, headers, body, true)
|
86
|
+
|
87
|
+
puts req
|
88
|
+
|
89
|
+
uri = URI.parse(self.endPoint + '/' + bucketname)
|
90
|
+
|
91
|
+
https = Net::HTTP.new(uri.host,uri.port)
|
92
|
+
https.use_ssl = true
|
93
|
+
|
94
|
+
req = Net::HTTP::Put.new(uri, initheader = headers)
|
95
|
+
req.body = body
|
96
|
+
https.set_debug_output($stdout)
|
97
|
+
response = https.request(req)
|
98
|
+
|
99
|
+
|
100
|
+
if response.code != "200"
|
101
|
+
puts "Error Making bucket"
|
102
|
+
else
|
103
|
+
puts "Made bucket"
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
data/lib/minio/digest.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "openssl"
|
3
|
+
|
4
|
+
module MinioRuby
|
5
|
+
|
6
|
+
class Digestor
|
7
|
+
# calculate sha256 hex digest.
|
8
|
+
def self.hexdigest(value)
|
9
|
+
Digest::SHA256.new.update(value).hexdigest
|
10
|
+
end
|
11
|
+
|
12
|
+
# calculate hmac digest.
|
13
|
+
def self.hmac(key, value)
|
14
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value)
|
15
|
+
end
|
16
|
+
|
17
|
+
# calculate hmac hex digest.
|
18
|
+
def self.hexhmac(key, value)
|
19
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.base64(value)
|
23
|
+
return Digest::MD5.base64digest(value)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
end
|
data/lib/minio/error.rb
ADDED
data/lib/minio/helper.rb
ADDED
data/lib/minio/signer.rb
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
|
2
|
+
require "openssl"
|
3
|
+
require "time"
|
4
|
+
require "uri"
|
5
|
+
require "pathname"
|
6
|
+
require "minio/digest"
|
7
|
+
|
8
|
+
module MinioRuby
|
9
|
+
class Signer
|
10
|
+
RFC8601BASIC = "%Y%m%dT%H%M%SZ"
|
11
|
+
SIGNV4ALGO = 'AWS4-HMAC-SHA256'
|
12
|
+
attr_reader :access_key, :secret_key, :region, :date, :service
|
13
|
+
attr_reader :method, :uri, :headers
|
14
|
+
|
15
|
+
# Initialize signer for calculating your signature.
|
16
|
+
# Params:
|
17
|
+
# +config+: configuration data with access keys and region.
|
18
|
+
def initialize(config)
|
19
|
+
@access_key = config[:access_key] || config["access_key"]
|
20
|
+
@secret_key = config[:secret_key] || config["secret_key"]
|
21
|
+
@region = config[:region] || config["region"]
|
22
|
+
@date = Time.now.utc.strftime(RFC8601BASIC)
|
23
|
+
@service = "s3"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Signature v4 function returns back headers with Authorization header.
|
27
|
+
# Params:
|
28
|
+
# +method+: http method.
|
29
|
+
# +endpoint+: S3 endpoint URL.
|
30
|
+
def sign_v4(method, endpoint, headers, body = nil, debug = false)
|
31
|
+
@method = method.upcase
|
32
|
+
@endpoint = endpoint
|
33
|
+
@headers = headers
|
34
|
+
@uri = URI(endpoint)
|
35
|
+
|
36
|
+
puts "EP : "+@endpoint
|
37
|
+
puts "Headers : "+@headers.to_s
|
38
|
+
|
39
|
+
headers["X-Amz-Date"] = date
|
40
|
+
headers["X-Amz-Content-Sha256"] = Digestor.hexdigest(body || "")
|
41
|
+
|
42
|
+
|
43
|
+
headers["Host"] = get_host(@uri)
|
44
|
+
puts "--->" + get_host(@uri)
|
45
|
+
|
46
|
+
|
47
|
+
dump if debug
|
48
|
+
signed_headers = headers.dup
|
49
|
+
|
50
|
+
signed_headers['Authorization'] = get_authorization(headers)
|
51
|
+
signed_headers
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# Get host header value from endpoint.
|
57
|
+
# Params:
|
58
|
+
# +endpoint+: endpoint URI object.
|
59
|
+
def get_host(endpoint)
|
60
|
+
puts "recieved : "+ endpoint.to_s
|
61
|
+
puts "port : "+ endpoint.port.to_s
|
62
|
+
if endpoint.port
|
63
|
+
if ((endpoint.port == 443) || (endpoint.port == 80))
|
64
|
+
return endpoint.host
|
65
|
+
else
|
66
|
+
return endpoint.host + ":" + endpoint.port.to_s
|
67
|
+
end
|
68
|
+
else
|
69
|
+
#return endpoint.host
|
70
|
+
return endpoint.host + ":" + endpoint.port.to_s
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
# Get authorization header value.
|
79
|
+
# Params:
|
80
|
+
# +headers+: list of headers supplied for the request.
|
81
|
+
def get_authorization(headers)
|
82
|
+
[
|
83
|
+
"AWS4-HMAC-SHA256 Credential=#{access_key}/#{credential_scope}",
|
84
|
+
"SignedHeaders=#{headers.keys.map(&:downcase).sort.join(";")}",
|
85
|
+
"Signature=#{signature}"
|
86
|
+
].join(', ')
|
87
|
+
end
|
88
|
+
|
89
|
+
# Calculate HMAC based signature in following format.
|
90
|
+
# --- format ---
|
91
|
+
# kSecret = Your AWS Secret Access Key
|
92
|
+
# kDate = HMAC("AWS4" + kSecret, Date)
|
93
|
+
# kRegion = HMAC(kDate, Region)
|
94
|
+
# kService = HMAC(kRegion, Service)
|
95
|
+
# kSigning = HMAC(kService, "aws4_request")
|
96
|
+
# --------------
|
97
|
+
def signature
|
98
|
+
k_date = Digestor.hmac("AWS4" + secret_key, date[0,8])
|
99
|
+
k_region = Digestor.hmac(k_date, region)
|
100
|
+
k_service = Digestor.hmac(k_region, service)
|
101
|
+
k_credentials = Digestor.hmac(k_service, "aws4_request")
|
102
|
+
Digestor.hexhmac(k_credentials, string_to_sign)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Generate string to sign.
|
106
|
+
# --- format ---
|
107
|
+
# StringToSign =
|
108
|
+
# Algorithm + '\n' +
|
109
|
+
# RequestDate + '\n' +
|
110
|
+
# CredentialScope + '\n' +
|
111
|
+
# HashedCanonicalRequest
|
112
|
+
# --------------
|
113
|
+
def string_to_sign
|
114
|
+
[
|
115
|
+
SIGNV4ALGO,
|
116
|
+
date,
|
117
|
+
credential_scope,
|
118
|
+
Digestor.hexdigest(canonical_request)
|
119
|
+
].join("\n")
|
120
|
+
end
|
121
|
+
|
122
|
+
# Generate credential scope.
|
123
|
+
# --- format ---
|
124
|
+
# <mmddyyyy>/<region>/<service>/aws4_request
|
125
|
+
# --------------
|
126
|
+
def credential_scope
|
127
|
+
[
|
128
|
+
date[0,8],
|
129
|
+
region,
|
130
|
+
service,
|
131
|
+
"aws4_request"
|
132
|
+
].join("/")
|
133
|
+
end
|
134
|
+
|
135
|
+
# Generate a canonical request of following style.
|
136
|
+
# --- format ---
|
137
|
+
# canonicalRequest =
|
138
|
+
# <HTTPMethod>\n
|
139
|
+
# <CanonicalURI>\n
|
140
|
+
# <CanonicalQueryString>\n
|
141
|
+
# <CanonicalHeaders>\n
|
142
|
+
# <SignedHeaders>\n
|
143
|
+
# <HashedPayload>
|
144
|
+
# --------------
|
145
|
+
def canonical_request
|
146
|
+
[
|
147
|
+
method,
|
148
|
+
Pathname.new(uri.path).cleanpath.to_s,
|
149
|
+
uri.query,
|
150
|
+
headers.sort.map {|k, v| [k.downcase,v.strip].join(':')}.join("\n") + "\n",
|
151
|
+
headers.sort.map {|k, v| k.downcase}.join(";"),
|
152
|
+
headers["X-Amz-Content-Sha256"]
|
153
|
+
].join("\n")
|
154
|
+
end
|
155
|
+
|
156
|
+
def dump
|
157
|
+
puts "-----------------DUMP BEGIN ---------------------"
|
158
|
+
puts "string to sign"
|
159
|
+
puts string_to_sign
|
160
|
+
puts "canonical_request"
|
161
|
+
puts canonical_request
|
162
|
+
puts "authorization"
|
163
|
+
puts "-----------------DUMP END ----------------------"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minio-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Minio, Inc.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: http
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
description: The official Minio Client SDK for Ruby.
|
28
|
+
email:
|
29
|
+
- dev@minio.io
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- lib/minio.rb
|
35
|
+
- lib/minio/digest.rb
|
36
|
+
- lib/minio/error.rb
|
37
|
+
- lib/minio/helper.rb
|
38
|
+
- lib/minio/signer.rb
|
39
|
+
homepage: https://github.com/watsy0007/minio-ruby
|
40
|
+
licenses:
|
41
|
+
- Apache-2.0
|
42
|
+
metadata: {}
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 2.6.12
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Minio Client SDK for Ruby
|
63
|
+
test_files: []
|