Skip to content

Commit

Permalink
fix: Support Ruby 2.4 (fixes #16)
Browse files Browse the repository at this point in the history
  • Loading branch information
argos83 authored Nov 16, 2017
1 parent 6be0b02 commit 9384501
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 87 deletions.
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ Metrics/LineLength:

Metrics/MethodLength:
Max: 13

Style/BlockLength:
Exclude:
- 'spec/**/*spec.rb'
17 changes: 13 additions & 4 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
machine:
ruby:
version: 2.2.3
version: 2.2.8

dependencies:
override:
- 'rvm-exec 2.2.8 bundle install'
- 'rvm-exec 2.3.5 bundle install'
- 'rvm-exec 2.4.2 bundle install'

test:
post:
- bundle exec rspec
- bundle exec rubocop
override:
- 'rvm-exec 2.2.8 bundle exec rspec'
- 'rvm-exec 2.3.5 bundle exec rspec'
- 'rvm-exec 2.4.2 bundle exec rspec'
- 'rvm-exec 2.4.2 bundle exec rubocop'
6 changes: 3 additions & 3 deletions lib/ritm/certs/ca.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ def sign(certificate)
def self.signing_profile
{
'extensions' => {
'keyUsage' => { 'usage' => %w(keyEncipherment digitalSignature) },
'extendedKeyUsage' => { 'usage' => %w(serverAuth clientAuth) }
'keyUsage' => { 'usage' => %w[keyEncipherment digitalSignature] },
'extendedKeyUsage' => { 'usage' => %w[serverAuth clientAuth] }
}
}
end

def self.ca_signing_profile
{ 'extensions' => { 'keyUsage' => { 'usage' => %w(critical keyCertSign keyEncipherment digitalSignature) } } }
{ 'extensions' => { 'keyUsage' => { 'usage' => %w[critical keyCertSign keyEncipherment digitalSignature] } } }
end
end
end
2 changes: 1 addition & 1 deletion lib/ritm/helpers/encodings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Ritm
# ENCODER/DECODER of HTTP content
module Encodings
ENCODINGS = [:identity, :gzip, :deflate].freeze
ENCODINGS = %i[identity gzip deflate].freeze

def self.encode(encoding, data)
case encoding
Expand Down
2 changes: 1 addition & 1 deletion lib/ritm/interception/http_forwarder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def initialize(request_interceptor, response_interceptor, context_config)
# TODO: make SSL verification a configuration setting
@client = Faraday.new(ssl: { verify: false }) do |conn|
conn.adapter :net_http
conn.proxy @config.misc.upstream_proxy unless @config.misc.upstream_proxy.nil?
conn.proxy = @config.misc.upstream_proxy unless @config.misc.upstream_proxy.nil?
end
end

Expand Down
18 changes: 17 additions & 1 deletion lib/ritm/proxy/cert_signing_https_server.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
require 'openssl'
require 'webrick'
require 'webrick/https'
require 'ritm/certs/certificate'

IS_RUBY_2_4_OR_OLDER = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4')

module Ritm
module Proxy
# Patches WEBrick::HTTPServer SSL context creation to get
Expand Down Expand Up @@ -40,11 +43,24 @@ def prepare_sni_callback(ctx, ca)
end

def context_with_cert(original_ctx, cert)
ctx = original_ctx.dup
ctx = duplicate_context(original_ctx)
ctx.key = cert.private_key
ctx.cert = cert.x509
ctx
end

def duplicate_context(original_ctx)
return original_ctx.dup unless IS_RUBY_2_4_OR_OLDER

ctx = OpenSSL::SSL::SSLContext.new

original_ctx.instance_variables.each do |variable_name|
prop_name = variable_name.to_s.sub(/^@/, '')
set_prop_method = "#{prop_name}="
ctx.send(set_prop_method, original_ctx.send(prop_name)) if ctx.respond_to? set_prop_method
end
ctx
end
end
end
end
2 changes: 1 addition & 1 deletion lib/ritm/proxy/proxy_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def proxy_service(req, res)
send("do_#{req.request_method}", req, res)
rescue NoMethodError
raise WEBrick::HTTPStatus::MethodNotAllowed, "unsupported method `#{req.request_method}'."
rescue => err
rescue StandardError => err
raise WEBrick::HTTPStatus::ServiceUnavailable, err.message
end

Expand Down
2 changes: 1 addition & 1 deletion lib/ritm/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Ritm version
module Ritm
VERSION = '1.0.0'.freeze
VERSION = '1.0.1'.freeze
end
18 changes: 9 additions & 9 deletions ritm.gemspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- encoding: utf-8 -*-
lib = File.expand_path('../lib/', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'date'
require 'ritm/version'

Gem::Specification.new do |s|
Expand All @@ -14,15 +14,15 @@ Gem::Specification.new do |s|
s.files = Dir['lib/**/*']
s.homepage = 'https://github.com/argos83/ritm'
s.license = 'Apache License, v2.0'
s.add_runtime_dependency 'faraday', '~> 0.9'
s.add_runtime_dependency 'webrick', '~> 1.3'
s.add_runtime_dependency 'certificate_authority', '~> 0.1.6'
s.add_runtime_dependency 'dot_hash', '~> 0.5'
s.add_development_dependency 'rspec', '~> 3.4'
s.add_development_dependency 'rubocop', '~> 0.40'
s.add_development_dependency 'simplecov', '~> 0.11'
s.add_development_dependency 'sinatra', '~> 1.4'
s.add_development_dependency 'thin', '~> 1.6'
s.add_development_dependency 'rake', '~> 11.1'
s.add_runtime_dependency 'faraday', '~> 0.13'
s.add_runtime_dependency 'webrick', '~> 1.3'
s.add_development_dependency 'httpclient', '~> 2.8'
s.add_development_dependency 'rake', '~> 12.2'
s.add_development_dependency 'rspec', '~> 3.7'
s.add_development_dependency 'rubocop', '~> 0.51'
s.add_development_dependency 'simplecov', '~> 0.15'
s.add_development_dependency 'sinatra', '~> 1.4'
s.add_development_dependency 'thin', '~> 1.7'
end
2 changes: 1 addition & 1 deletion spec/helpers/ritm_spec_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def client(base_url, verify_ssl: false, ca_file: nil, proxy: DEFAULT_PROXY_ADDRE
conn.adapter :net_http
conn.ssl[:verify] = verify_ssl
conn.ssl[:ca_file] = ca_file unless ca_file.nil?
conn.proxy proxy
conn.proxy = proxy
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/helpers/web_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def extract_headers(env)
Zlib::Deflate.deflate('Misunderstanding all you see')
end

[:get, :post, :put, :patch, :delete, :options].each do |method|
%i[get post put patch delete options].each do |method|
send(method, '/echo') do
request.body.rewind
info = { method: request.request_method,
Expand Down
38 changes: 19 additions & 19 deletions spec/intercept_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,45 @@
RSpec.describe Ritm do
include RitmSpecUtils

%w(http://localhost:4567 https://localhost:4443).each do |base_url|
%w[http://localhost:4567 https://localhost:4443].each do |base_url|
before(:each) do
interceptor.clear
end

it 'intercepts requests and responses' do
expect(interceptor.requests.size).to be 0
expect(interceptor.responses.size).to be 0
expect(interceptor.requests.size).to eq 0
expect(interceptor.responses.size).to eq 0
client(base_url).get('/ping')
expect(interceptor.requests.size).to be 1
expect(interceptor.responses.size).to be 1
expect(interceptor.requests.size).to eq 1
expect(interceptor.responses.size).to eq 1
end

it 'can disable interception temporarily' do
expect(interceptor.requests.size).to be 0
expect(interceptor.responses.size).to be 0
expect(interceptor.requests.size).to eq 0
expect(interceptor.responses.size).to eq 0
Ritm.disable
client(base_url).get('/ping')
expect(interceptor.requests.size).to be 0
expect(interceptor.responses.size).to be 0
expect(interceptor.requests.size).to eq 0
expect(interceptor.responses.size).to eq 0
Ritm.enable
client(base_url).get('/ping')
expect(interceptor.requests.size).to be 1
expect(interceptor.responses.size).to be 1
expect(interceptor.requests.size).to eq 1
expect(interceptor.responses.size).to eq 1
end

it 'can be configured to use upstream proxies' do
resp = nil
with_proxy do |session|
c = client(base_url, verify_ssl: false, proxy: 'http://localhost:7777')
c.get('/ping')
expect(interceptor.requests.size).to be 0
expect(interceptor.responses.size).to be 0
expect(interceptor.requests.size).to eq 0
expect(interceptor.responses.size).to eq 0

session.configure { misc[:upstream_proxy] = DEFAULT_PROXY_ADDRESS }

resp = c.get('/ping')
expect(interceptor.requests.size).to be 1
expect(interceptor.responses.size).to be 1
expect(interceptor.requests.size).to eq 1
expect(interceptor.responses.size).to eq 1
end
expect(resp.body).to eq 'pong'
end
Expand All @@ -59,7 +59,7 @@
exec_order << :b
client(base_url).get('/ping')
exec_order << :d
expect(exec_order).to eq([:a, :b, :c, :d])
expect(exec_order).to eq(%i[a b c d])
end

it 'gets access to method, resource, headers, and body' do
Expand Down Expand Up @@ -103,13 +103,13 @@
exec_order << :b
client(base_url).get('/ping')
exec_order << :d
expect(exec_order).to eq([:a, :b, :c, :d])
expect(exec_order).to eq(%i[a b c d])
end

it 'gets access to status, headers, and body' do
client(base_url).get('/ping')
res = interceptor.responses.last
expect(res.status).to be(200)
expect(res.status).to eq 200
expect(res.header['content-length']).to eq('4')
expect(res.header['content-type']).to eq('text/html;charset=utf-8')
expect(res.body).to eq('pong')
Expand All @@ -123,7 +123,7 @@
res.header['content-type'] = 'text/plain'
end
res = client(base_url).get('/ping')
expect(res.status).to be(404)
expect(res.status).to eq 404
expect(res.headers['content-length']).to eq('6')
expect(res.headers['content-type']).to eq('text/plain')
expect(res.headers['x-custom']).to eq('narf')
Expand Down
4 changes: 2 additions & 2 deletions spec/intercept_ssl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
expect(extensions['basicConstraints']).to eq('CA:FALSE')
# Issuer
expect(extensions['authorityKeyIdentifier'])
.to eq("keyid:DF:54:83:59:A4:73:F7:F6:A1:4A:CC:CD:3B:CE:3F:A5:4D:8A:4D:D6\n")
expect(cert.issuer.to_s).to eq('/CN=RubyInTheMiddle')
.to eq("keyid:B1:7B:8A:53:DB:01:1B:F1:51:03:61:AC:21:C7:36:D7:CE:15:BD:08\n")
expect(cert.issuer.to_s).to eq('/CN=RubyInTheMiddle/O=RubyInTheMiddle/OU=RubyInTheMiddle/C=AR')
end

it 'generates a new CA if it was not specified' do
Expand Down
33 changes: 15 additions & 18 deletions spec/resources/insecure_ca.crt
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
-----BEGIN CERTIFICATE-----
MIIDLjCCAhagAwIBAgIBATANBgkqhkiG9w0BAQ0FADAaMRgwFgYDVQQDDA9SdWJ5
SW5UaGVNaWRkbGUwHhcNMTYwNTE0MDkxNTQ0WhcNMTcwNTE0MDkxNTQ0WjAaMRgw
FgYDVQQDDA9SdWJ5SW5UaGVNaWRkbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQC3cDaxf3F3Mjg8NMwrRufztRfgvJjro+2NOub9iVvA1I4SfzQRAHv0
lqRCqqXjOIjA/3pIoT/L5uQglbQfCpIptbTod6lUkHwPV3mNEqa+iYn34xpUK2vp
nZYaVFXc54JAJiATb95AlxMZkOnM3dwXOIsPl5d88RX1DXZNjRNKj/2Iotk1pVVK
JoW2drvTeiDotCqVXnsOzbGj+468ZH53K9wlcPmb1Dixpac0CMYwgSajBRn/7MwI
gMJMmIojfNOWxs1vMiG8Y2vpTIhLLGtT9WXrZoqYpVvDT4BvL7rXihD/IRYzCc8H
xcQp2z8eEaXP8FITDbax4U66QVU/VyJpAgMBAAGjfzB9MB0GA1UdDgQWBBTfVINZ
pHP39qFKzM07zj+lTYpN1jAOBgNVHQ8BAf8EBAMCAqQwHQYDVR0lBBYwFAYIKwYB
BQUHAwEGCCsGAQUFBwMCMAwGA1UdEwQFMAMBAf8wHwYDVR0jBBgwFoAU31SDWaRz
9/ahSszNO84/pU2KTdYwDQYJKoZIhvcNAQENBQADggEBAI144JqC/znKMkJuiuxE
zK2NkHKOK0taC5ecfzejn/ymkxzEg4XCJrCwnnEBkLR+yQYZgJQ4JpqnPShtycLq
yi1Ro2qzoeDWKD9l5hifaJrT9ZMeAqHTlNV7oM6fQmLK3oC8y2COo+0TlGPsu2L2
iYnf8Ro4t0A0/flDjOKxYn9+PN5/AEHROzk+IVkjmoumrPpOro6Z3WGRvNRAzlER
5jYMZsIe23AMI0CC+Hx+I6jEdBikQTX6/B25gqcS+tXX1Kj7swQyNKB1pRo9jh+I
qZRKSpXv4v7YgY3ylFCIdqbpVpF0zCojUMI1RF68VDscx5rY6q1SfvJCn6p9+8B+
0fE=
MIICqzCCAhSgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBbMRgwFgYDVQQDDA9SdWJ5
SW5UaGVNaWRkbGUxGDAWBgNVBAoMD1J1YnlJblRoZU1pZGRsZTEYMBYGA1UECwwP
UnVieUluVGhlTWlkZGxlMQswCQYDVQQGEwJBUjAeFw0xNzEwMTcwNjExMjNaFw0z
MzExMTIwNjExMjNaMFsxGDAWBgNVBAMMD1J1YnlJblRoZU1pZGRsZTEYMBYGA1UE
CgwPUnVieUluVGhlTWlkZGxlMRgwFgYDVQQLDA9SdWJ5SW5UaGVNaWRkbGUxCzAJ
BgNVBAYTAkFSMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7HZILDz/7Ms2B
8QjdYIUaCj/rvHSJkH7qQsE9QcZ9M6H4ie2a1nCX9C91c84UQCYeqeTJ20PwJsk9
jMahtOCbREMl3dDzrQYMasFY9XVf1BhK+C+RZwdzZnXp9G9h1S/lJA1sxQ0FVCSn
L8pSRAUvBeugdST7ClchmcUR2kf9vwIDAQABo38wfTAdBgNVHQ4EFgQUsXuKU9sB
G/FRA2GsIcc2184VvQgwDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQWMBQGCCsGAQUF
BwMBBggrBgEFBQcDAjAMBgNVHRMEBTADAQH/MB8GA1UdIwQYMBaAFLF7ilPbARvx
UQNhrCHHNtfOFb0IMA0GCSqGSIb3DQEBDQUAA4GBAJmcy+MueNqatZN6PUedpAPf
WNOo9Me6rmzU7uZmB4tj23q3hq31MeudZLsI0UfNCkLv0tf9yw2ENMG7W6QJ4NDN
O40Avi/YK2Ibvbq/hPucJbFrXHCh8w94fT6gRvW0K4gkOTL1SSuX5wkGfQqGo5Yg
NAU/3e2YVsgfqCkvyxzW
-----END CERTIFICATE-----
38 changes: 13 additions & 25 deletions spec/resources/insecure_ca.priv
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

0 comments on commit 9384501

Please sign in to comment.