Skip to content

Commit 08c347f

Browse files
authored
Merge pull request #154 from jay7x/unrest
refactor: replace rest-client with net/http
2 parents 0b3047b + e9d89f8 commit 08c347f

File tree

4 files changed

+58
-22
lines changed

4 files changed

+58
-22
lines changed

lib/puppet_blacksmith/forge.rb

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
require 'rest-client'
1+
require 'net/http'
22
require 'json'
33
require 'yaml'
44
require 'base64'
5+
require 'uri'
56

67
module Blacksmith
78
class Forge
@@ -21,7 +22,6 @@ def initialize(username = nil, password = nil, url = nil, forge_type = nil, toke
2122
self.password = password
2223
self.token = token
2324
self.api_key = api_key
24-
RestClient.proxy = ENV.fetch('http_proxy', nil)
2525
load_credentials
2626
self.url = url unless url.nil?
2727
if %r{http(s)?://forge.puppetlabs.com}.match?(self.url)
@@ -51,15 +51,32 @@ def push!(name, package = nil, author = nil, version = nil)
5151
private
5252

5353
def upload(author, name, file)
54-
url = http_url(author, name, file)
55-
case forge_type
56-
when FORGE_TYPE_ARTIFACTORY
57-
RestClient::Request.execute(method: :put, url: url, payload: File.new(file, 'rb'), headers: http_headers)
58-
else
59-
RestClient::Request.execute(method: :post, url: url, payload: { file: File.new(file, 'rb') }, headers: http_headers)
54+
target_url = http_url(author, name, file)
55+
uri = URI(target_url)
56+
57+
http = Net::HTTP.new(uri.host, uri.port)
58+
http.use_ssl = (uri.scheme == 'https')
59+
60+
response = File.open(file, 'rb') do |f|
61+
if forge_type == FORGE_TYPE_ARTIFACTORY
62+
request = Net::HTTP::Put.new(uri.request_uri, http_headers)
63+
request.body_stream = f
64+
else
65+
request = Net::HTTP::Post.new(uri.request_uri, http_headers)
66+
request.set_form([
67+
['file', f, { filename: File.basename(file) }],
68+
], 'multipart/form-data')
69+
end
70+
http.request(request)
6071
end
61-
rescue RestClient::Exception => e
62-
raise Blacksmith::Error, "Error uploading #{name} to the forge #{url} [#{e.message}]: #{e.response}"
72+
73+
raise Blacksmith::Error, "Error uploading #{name} to the forge #{target_url} [#{response.code} #{response.message}]: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
74+
rescue Net::HTTPClientException => e
75+
raise Blacksmith::Error, "Error uploading #{name} to the forge #{target_url} [#{e.response.code} #{e.response.message}]: #{e.response.body}"
76+
rescue Net::HTTPFatalError => e
77+
raise Blacksmith::Error, "HTTP error during upload: #{e.message}"
78+
rescue StandardError => e
79+
raise Blacksmith::Error, "Error uploading #{name} to the forge #{target_url} [#{e.class} #{e.message}]"
6380
end
6481

6582
def http_url(author, name, file)

puppet-blacksmith.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ Gem::Specification.new do |s|
1818

1919
s.add_dependency 'base64', '>= 0.2', '< 0.4'
2020
s.add_dependency 'puppet-modulebuilder', '~> 2.0', '>= 2.0.2'
21-
s.add_dependency 'rest-client', '~>2.0'
2221
s.add_development_dependency 'aruba', '~> 2.1'
2322
s.add_development_dependency 'cucumber', '>= 9', '< 11'
2423
s.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6'

spec/puppet_blacksmith/forge_shared.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
let(:target) { File.expand_path(File.join(__dir__, '..', '..', 'pkg', module_name)) }
2222
let(:package) { "#{target}.tar.gz" }
2323

24-
let(:headers) { { 'User-Agent' => %r{^Blacksmith/#{Blacksmith::VERSION} Ruby/.* \(.*\)$}o } }
25-
2624
def create_tarball
2725
FileUtils.mkdir_p(target)
2826

spec/puppet_blacksmith/forge_spec.rb

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,43 @@
6969
before { create_tarball }
7070

7171
context 'when using a Forge API key' do
72-
before do
73-
stub_request(:post, "#{forge}/v3/releases").with(
74-
headers: headers.merge({ 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
75-
'Authorization' => 'Bearer e52f78b62e97cb8d8db6659a73aa522cca0f5c74d4714e0ed0bdd10000000000', 'Content-Type' => %r{\Amultipart/form-data;}, }),
76-
) do |request|
77-
request.body =~ %r{Content-Disposition: form-data; name="file"; filename="maestrodev-test.tar.gz"\r\nContent-Type: application/gzip}
78-
end.to_return(status: 200, body: File.read(File.join(spec_data, 'response.json')), headers: {})
72+
# WebMock doesn't support `set_form()` yet: https://github.com/bblimke/webmock/issues/959
73+
# Disable it and use RSpec mocks instead
74+
before { WebMock.disable! }
75+
after { WebMock.enable! }
76+
77+
let(:http) do
78+
http = instance_double(Net::HTTP)
79+
allow(http).to receive(:use_ssl=)
80+
http
81+
end
82+
let(:response_ok) do
83+
resp = instance_double(Net::HTTPOK, body: '{}', code: 200, message: 'OK')
84+
allow(resp).to receive(:is_a?).with(Net::HTTPSuccess).and_return(true)
85+
resp
7986
end
8087

8188
it 'push the module' do
8289
subject.api_key = api_key
8390
subject.url = forge
8491

85-
resp = subject.push!(module_name, package)
86-
expect(resp.code).to eq(200)
92+
allow(Net::HTTP).to receive(:new).and_return(http)
93+
# Allow any POST and return OK always
94+
allow(http).to receive(:request).with(instance_of(Net::HTTP::Post)).and_return(response_ok)
95+
96+
subject.push!(module_name, package)
97+
# Ensure the connection is to the right host & port
98+
expect(Net::HTTP).to have_received(:new).with('forgestagingapi.puppetlabs.com', 443)
99+
# Ensure the expected request actually happens
100+
expect(http).to have_received(:request).with(
101+
satisfy do |req|
102+
expect(req).to be_a(Net::HTTP::Post)
103+
expect(req.path).to eq('/v3/releases')
104+
expect(req['Content-Type']).to match(%r{multipart/form-data})
105+
expect(req['Authorization']).to eq("Bearer #{api_key}")
106+
expect(req['User-Agent']).to match(%r{^Blacksmith/#{Blacksmith::VERSION} Ruby/.* \(.*\)$}o)
107+
end,
108+
)
87109
end
88110
end
89111
end

0 commit comments

Comments
 (0)