thin-glazed 0.1.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.
- data/.gitignore +17 -0
- data/.travis.yml +4 -0
- data/Gemfile +3 -0
- data/LICENCE +22 -0
- data/README.textile +60 -0
- data/Rakefile +11 -0
- data/lib/data/glazed.key +15 -0
- data/lib/data/glazed.pem +31 -0
- data/lib/rack/handler/thin_glazed.rb +19 -0
- data/lib/thin-glazed.rb +1 -0
- data/lib/thin/glazed.rb +20 -0
- data/lib/thin/glazed/as_default.rb +7 -0
- data/lib/thin/glazed/capybara.rb +40 -0
- data/lib/thin/glazed/http_client.rb +24 -0
- data/lib/thin/glazed/http_glazing.rb +32 -0
- data/lib/thin/glazed/https_glazing.rb +21 -0
- data/lib/thin/glazed/server.rb +17 -0
- data/lib/thin/glazed/version.rb +5 -0
- data/spec/thin/glazed/http_client_spec.rb +58 -0
- data/spec/thin/glazed/http_glazing_spec.rb +56 -0
- data/spec/thin/glazed/https_glazing_spec.rb +53 -0
- data/spec/thin/glazed/server_spec.rb +27 -0
- data/thin-glazed.gemspec +25 -0
- metadata +123 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENCE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Pat Allan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
h1. Thin::Glazed
|
2
|
+
|
3
|
+
This library adds an HTTPS proxy to Thin, which allows you to run your Rails apps that use both HTTP and HTTPS protocols simply within a browser, as well as in your Capybara integration tests, should you so desire.
|
4
|
+
|
5
|
+
It was written to keep things consistent - with SSL in development, test and production environments.
|
6
|
+
|
7
|
+
This wouldn't have been possible (or at least, would have been a far larger headache) if it wasn't for the source and examples of the em-proxy gem.
|
8
|
+
|
9
|
+
h2. Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile, in your development and/or test groups:
|
12
|
+
|
13
|
+
<pre><code>gem 'thin-glazed'</code></pre>
|
14
|
+
|
15
|
+
h2. Using it in development
|
16
|
+
|
17
|
+
You can use the glazed server when you fire up your Rails app locally:
|
18
|
+
|
19
|
+
<pre><code>./script/rails server thin_glazed</code></pre>
|
20
|
+
|
21
|
+
This will provide HTTPS over port 3443 - I use "my fork":https://github.com/freelancing-god/ssl_requirement of the bartll-ssl_requirement gem to specify which ports have which protocols, at the end of my @config/environments/development.rb@ file:
|
22
|
+
|
23
|
+
<pre><code>SslRequirement.non_ssl_port = 3000
|
24
|
+
SslRequirement.non_ssl_port = 3443</code></pre>
|
25
|
+
|
26
|
+
This ensures redirects from one protocol to the other work accordingly.
|
27
|
+
|
28
|
+
If you want to have this as your default development server, add a @:require@ option to the listing in your Gemfile:
|
29
|
+
|
30
|
+
<pre><code>gem 'thin-glazed', :require => 'thin/glazed/as_default'</code></pre>
|
31
|
+
|
32
|
+
And from there, it'll just work:
|
33
|
+
|
34
|
+
<pre><code>./script/rails server</code></pre>
|
35
|
+
|
36
|
+
h2. Using it with tests
|
37
|
+
|
38
|
+
*Note*: this currently has a dependency on "my fork":https://github.com/freelancing-god/ssl_requirement of bartll-ssl_requirement. I'd love some suggestions on instructing Rails on what the HTTP and HTTPS ports are without external requirements.
|
39
|
+
|
40
|
+
It should just work, if you're using straight Capybara, or Capybara with Selenium. For Webkit, you'll want to use @:glazed_webkit@ instead of @:webkit@ for your javascript driver:
|
41
|
+
|
42
|
+
<pre><code>Capybara.javascript_driver = :glazed_webkit</code></pre>
|
43
|
+
|
44
|
+
h2. Using it in production
|
45
|
+
|
46
|
+
Don't. This isn't built for production - you'd be far better served with a tool like Pound, or really just letting Nginx or Apache handle it all for you.
|
47
|
+
|
48
|
+
h2. Contributing
|
49
|
+
|
50
|
+
* Fork it
|
51
|
+
* Create your feature branch (`git checkout -b my-new-feature`)
|
52
|
+
* Write your tests
|
53
|
+
* Write the code to make your tests pass
|
54
|
+
* Commit your changes (`git commit -am 'Added some feature'`)
|
55
|
+
* Push to the branch (`git push origin my-new-feature`)
|
56
|
+
* Create new Pull Request
|
57
|
+
|
58
|
+
h2. Credits
|
59
|
+
|
60
|
+
Copyright (c) 2012, Thin::Glazed is developed and maintained by Pat Allan, and is released under the open MIT Licence.
|
data/Rakefile
ADDED
data/lib/data/glazed.key
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIICXAIBAAKBgQCzVsKSa2JvFglstgibytIh7WwidtvjZom2NbwJ0p/grwDIJEBn
|
3
|
+
v9SJL3nAo2rhnuFJrcI4DMUcLUV3eTE0++5phDSbh5dqS+jE3m29ELXhymhwwqM3
|
4
|
+
omhCVqKjWREQndHOdkYM/Sz9uufLPjx6xS8OaLmBERMZ7+QVKkrusWZ2nQIDAQAB
|
5
|
+
AoGBAJyMuvLHzLh9+yIr0V318fLt53w6V36tTr+BLrFAbJHdEoijpJksiqJqkBTK
|
6
|
+
Uo27fJwtkyIMe7A6EK7XW04OMbHwOWFlOK2qSH3E3GKR4rk5NgeE6ifglkVQ6o55
|
7
|
+
pKstlzEOGdo6VfaW9vtF4qs3QWdN79T8I1pyFWZOb+0Q8v1hAkEA7cn/uj8fHFGB
|
8
|
+
0ouH/ctbfQ8CPhBT0HcHCvAVr+/vf1gbIwywFgi7VF/jUlnbQt+mqzEFgA0WU1aM
|
9
|
+
Kkurdwjj2QJBAMESz1KQf3lvA9+xr1aUHGIpHSJyaHtU3SrBIW1irEDju6IuxP/y
|
10
|
+
/e+jBtobZ1P3VpiGmDt6EggsSV+NKCtX4mUCQEPu2Js520Z41rDy4egUx89jkU1v
|
11
|
+
1rIQvzdVvaxkzLRB1Ibf4hJ5biM9vbDSMPza7j+sIpkhpAYtDKAsvBCmvokCQAGk
|
12
|
+
FEkCW2L/04uaKgBVX+xhpxK84DB0JzEO1Sbl2MrwZI7bUOdP/GKGAy/lXbpz9rNz
|
13
|
+
KWYQAok5PyJlw7qik5UCQE10w3ehvA2M2906F+bhEXiEwYQst1zpHuUbY4uCDRcR
|
14
|
+
sZoiNMpXH+7aZPrQoUmyQDI7aaABZPyXz+iEXX6PFHo=
|
15
|
+
-----END RSA PRIVATE KEY-----
|
data/lib/data/glazed.pem
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIICkTCCAfoCCQCuFNIEhoEKAzANBgkqhkiG9w0BAQUFADCBjDELMAkGA1UEBhMC
|
3
|
+
QVUxETAPBgNVBAgTCFZpY3RvcmlhMRIwEAYDVQQHEwlNZWxib3VybmUxGTAXBgNV
|
4
|
+
BAoTEEZyZWVsYW5jaW5nIEdvZHMxEjAQBgNVBAMTCVBhdCBBbGxhbjEnMCUGCSqG
|
5
|
+
SIb3DQEJARYYcGF0QGZyZWVsYW5jaW5nLWdvZHMuY29tMB4XDTEyMDIwODA3MDg0
|
6
|
+
MloXDTEzMDIwNzA3MDg0MlowgYwxCzAJBgNVBAYTAkFVMREwDwYDVQQIEwhWaWN0
|
7
|
+
b3JpYTESMBAGA1UEBxMJTWVsYm91cm5lMRkwFwYDVQQKExBGcmVlbGFuY2luZyBH
|
8
|
+
b2RzMRIwEAYDVQQDEwlQYXQgQWxsYW4xJzAlBgkqhkiG9w0BCQEWGHBhdEBmcmVl
|
9
|
+
bGFuY2luZy1nb2RzLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAs1bC
|
10
|
+
kmtibxYJbLYIm8rSIe1sInbb42aJtjW8CdKf4K8AyCRAZ7/UiS95wKNq4Z7hSa3C
|
11
|
+
OAzFHC1Fd3kxNPvuaYQ0m4eXakvoxN5tvRC14cpocMKjN6JoQlaio1kREJ3RznZG
|
12
|
+
DP0s/brnyz48esUvDmi5gRETGe/kFSpK7rFmdp0CAwEAATANBgkqhkiG9w0BAQUF
|
13
|
+
AAOBgQCVIs9Nxz/N170TzsCDUOEB/Fu8pkK2zebFfF+Sk4Iqb0LuwOETFwB0/Lq+
|
14
|
+
5w1A3v9YzJVfgWnRcKRsudmHq2ZvmhEk0/LQ6GOv1TJE6I06g5odfgUtl9gBLiX7
|
15
|
+
vrxcFz2NRn1IWqZrOINed2odFceWBDKWXVbo2TyO557E5RJJyA==
|
16
|
+
-----END CERTIFICATE-----
|
17
|
+
-----BEGIN RSA PRIVATE KEY-----
|
18
|
+
MIICXAIBAAKBgQCzVsKSa2JvFglstgibytIh7WwidtvjZom2NbwJ0p/grwDIJEBn
|
19
|
+
v9SJL3nAo2rhnuFJrcI4DMUcLUV3eTE0++5phDSbh5dqS+jE3m29ELXhymhwwqM3
|
20
|
+
omhCVqKjWREQndHOdkYM/Sz9uufLPjx6xS8OaLmBERMZ7+QVKkrusWZ2nQIDAQAB
|
21
|
+
AoGBAJyMuvLHzLh9+yIr0V318fLt53w6V36tTr+BLrFAbJHdEoijpJksiqJqkBTK
|
22
|
+
Uo27fJwtkyIMe7A6EK7XW04OMbHwOWFlOK2qSH3E3GKR4rk5NgeE6ifglkVQ6o55
|
23
|
+
pKstlzEOGdo6VfaW9vtF4qs3QWdN79T8I1pyFWZOb+0Q8v1hAkEA7cn/uj8fHFGB
|
24
|
+
0ouH/ctbfQ8CPhBT0HcHCvAVr+/vf1gbIwywFgi7VF/jUlnbQt+mqzEFgA0WU1aM
|
25
|
+
Kkurdwjj2QJBAMESz1KQf3lvA9+xr1aUHGIpHSJyaHtU3SrBIW1irEDju6IuxP/y
|
26
|
+
/e+jBtobZ1P3VpiGmDt6EggsSV+NKCtX4mUCQEPu2Js520Z41rDy4egUx89jkU1v
|
27
|
+
1rIQvzdVvaxkzLRB1Ibf4hJ5biM9vbDSMPza7j+sIpkhpAYtDKAsvBCmvokCQAGk
|
28
|
+
FEkCW2L/04uaKgBVX+xhpxK84DB0JzEO1Sbl2MrwZI7bUOdP/GKGAy/lXbpz9rNz
|
29
|
+
KWYQAok5PyJlw7qik5UCQE10w3ehvA2M2906F+bhEXiEwYQst1zpHuUbY4uCDRcR
|
30
|
+
sZoiNMpXH+7aZPrQoUmyQDI7aaABZPyXz+iEXX6PFHo=
|
31
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'thin/glazed'
|
2
|
+
require 'rack/content_length'
|
3
|
+
require 'rack/chunked'
|
4
|
+
require 'rack/handler'
|
5
|
+
require 'rack/handler/thin'
|
6
|
+
|
7
|
+
class Rack::Handler::ThinGlazed < Rack::Handler::Thin
|
8
|
+
def self.run(app, options = {})
|
9
|
+
EventMachine.run do
|
10
|
+
https_proxy = ::Thin::Glazed::Server.new(options[:Host] || '0.0.0.0',
|
11
|
+
options[:ProxyPort] || 3443, options[:Port] || 3000)
|
12
|
+
https_proxy.start
|
13
|
+
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Rack::Handler.register 'thin_glazed', 'Rack::Handler::ThinGlazed'
|
data/lib/thin-glazed.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'thin/glazed'
|
data/lib/thin/glazed.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'thin'
|
3
|
+
|
4
|
+
module Thin::Glazed
|
5
|
+
#
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'thin/glazed/http_client'
|
9
|
+
require 'thin/glazed/http_glazing'
|
10
|
+
require 'thin/glazed/https_glazing'
|
11
|
+
require 'thin/glazed/server'
|
12
|
+
require 'thin/glazed/version'
|
13
|
+
|
14
|
+
if defined?(Rack)
|
15
|
+
require 'rack/handler/thin_glazed'
|
16
|
+
end
|
17
|
+
|
18
|
+
if defined?(Capybara) && Capybara.respond_to?(:configure)
|
19
|
+
require 'thin/glazed/capybara'
|
20
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rack/handler/thin_glazed'
|
2
|
+
|
3
|
+
class Thin::Glazed::Capybara
|
4
|
+
attr_reader :app, :port
|
5
|
+
|
6
|
+
def initialize(app, port)
|
7
|
+
@app, @port = app, port
|
8
|
+
|
9
|
+
SslRequirement.ssl_port = ssl_port
|
10
|
+
SslRequirement.non_ssl_port = port
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_server
|
14
|
+
Thin::Logging.silent = true
|
15
|
+
Rack::Handler::ThinGlazed.run app, :Port => port, :ProxyPort => ssl_port
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def ssl_port
|
21
|
+
@ssl_port ||= next_available_port
|
22
|
+
end
|
23
|
+
|
24
|
+
def next_available_port
|
25
|
+
server = TCPServer.new('127.0.0.1', 0)
|
26
|
+
server.addr[1]
|
27
|
+
ensure
|
28
|
+
server.close if server
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Capybara.configure do |config|
|
33
|
+
config.server { |app, port|
|
34
|
+
Thin::Glazed::Capybara.new(app, port).run_server
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
Capybara.register_driver :glazed_webkit do |app|
|
39
|
+
Capybara::Driver::Webkit.new(app, :ignore_ssl_errors => true)
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Thin::Glazed::HttpClient < EventMachine::Connection
|
2
|
+
attr_reader :proxy
|
3
|
+
|
4
|
+
def initialize(proxy)
|
5
|
+
@proxy = proxy
|
6
|
+
@connected = EventMachine::DefaultDeferrable.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def connection_completed
|
10
|
+
@connected.succeed
|
11
|
+
end
|
12
|
+
|
13
|
+
def receive_data(data)
|
14
|
+
proxy.relay_from_client(data)
|
15
|
+
end
|
16
|
+
|
17
|
+
def send(data)
|
18
|
+
@connected.callback { send_data data }
|
19
|
+
end
|
20
|
+
|
21
|
+
def unbind
|
22
|
+
proxy.unbind_client
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Thin::Glazed::HttpGlazing < EventMachine::Connection
|
2
|
+
attr_reader :client_port
|
3
|
+
|
4
|
+
def initialize(client_port)
|
5
|
+
@client_port = client_port
|
6
|
+
end
|
7
|
+
|
8
|
+
def receive_data(data)
|
9
|
+
client.send_data data unless data.nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def relay_from_client(data)
|
13
|
+
send_data data unless data.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
def unbind
|
17
|
+
client.close_connection
|
18
|
+
@client = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def unbind_client
|
22
|
+
close_connection_after_writing
|
23
|
+
@client = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def client
|
29
|
+
@client ||= EventMachine.connect '127.0.0.1', client_port,
|
30
|
+
Thin::Glazed::HttpClient, self
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Thin::Glazed::HttpsGlazing < Thin::Glazed::HttpGlazing
|
2
|
+
def post_init
|
3
|
+
start_tls(
|
4
|
+
:private_key_file => File.join(cert_path, 'glazed.key'),
|
5
|
+
:cert_chain_file => File.join(cert_path, 'glazed.pem'),
|
6
|
+
:verify_peer => false
|
7
|
+
)
|
8
|
+
end
|
9
|
+
|
10
|
+
def receive_data(data)
|
11
|
+
super data.gsub(/\r\n\r\n/, "\r\nX_FORWARDED_PROTO: https\r\n\r\n")
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def cert_path
|
17
|
+
@cert_path ||= File.expand_path File.join(
|
18
|
+
File.dirname(__FILE__), '..', '..', 'data'
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Thin::Glazed::Server
|
2
|
+
include Thin::Logging
|
3
|
+
|
4
|
+
attr_reader :host, :port, :client_port
|
5
|
+
|
6
|
+
def initialize(host, port, client_port)
|
7
|
+
@host, @port, @client_port = host, port, client_port
|
8
|
+
end
|
9
|
+
|
10
|
+
def start
|
11
|
+
log ">> Thin::Glazed HTTPS Proxy (v#{Thin::Glazed::VERSION})"
|
12
|
+
log ">> Listening on #{host}:#{port}"
|
13
|
+
|
14
|
+
EventMachine.start_server host, port, Thin::Glazed::HttpsGlazing,
|
15
|
+
client_port
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module EventMachine
|
2
|
+
class Connection; end
|
3
|
+
class DefaultDeferrable; end
|
4
|
+
end
|
5
|
+
|
6
|
+
require './lib/thin/glazed/http_client'
|
7
|
+
|
8
|
+
describe Thin::Glazed::HttpClient do
|
9
|
+
let(:client) { Thin::Glazed::HttpClient.new proxy }
|
10
|
+
let(:deferrable) { double('deferrable') }
|
11
|
+
let(:proxy) { double('proxy') }
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
EventMachine::DefaultDeferrable.stub :new => deferrable
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#connection_completed' do
|
18
|
+
it "calls succeed on the deferrable object" do
|
19
|
+
deferrable.should_receive(:succeed)
|
20
|
+
|
21
|
+
client.connection_completed
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#receive_data' do
|
26
|
+
it "passes on the data to the proxy" do
|
27
|
+
proxy.should_receive(:relay_from_client).with('foo bar baz')
|
28
|
+
|
29
|
+
client.receive_data('foo bar baz')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#send' do
|
34
|
+
it "buffers the data to send" do
|
35
|
+
deferrable.should_receive(:callback)
|
36
|
+
|
37
|
+
client.send('foo bar baz')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "eventually sends the data provided" do
|
41
|
+
deferrable.stub(:callback) do |block|
|
42
|
+
block.call
|
43
|
+
end
|
44
|
+
|
45
|
+
client.should_receive(:send_data).with('foo bar baz')
|
46
|
+
|
47
|
+
client.send('foo bar baz')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#unbind' do
|
52
|
+
it "unbinds itself from the proxy" do
|
53
|
+
proxy.should_receive(:unbind_client)
|
54
|
+
|
55
|
+
client.unbind
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module EventMachine
|
2
|
+
class Connection; end
|
3
|
+
end
|
4
|
+
|
5
|
+
require './lib/thin/glazed/http_glazing'
|
6
|
+
|
7
|
+
class Thin::Glazed::HttpClient; end
|
8
|
+
|
9
|
+
describe Thin::Glazed::HttpGlazing do
|
10
|
+
let(:glazing) { Thin::Glazed::HttpGlazing.new 3123 }
|
11
|
+
let(:client) { double('client', :send_data => true) }
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
EventMachine.stub :connect => client
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#receive_data' do
|
18
|
+
it "initializes a local client to the given port using itself as the proxy" do
|
19
|
+
EventMachine.should_receive(:connect).
|
20
|
+
with('127.0.0.1', 3123, Thin::Glazed::HttpClient, glazing).
|
21
|
+
and_return(client)
|
22
|
+
|
23
|
+
glazing.receive_data('qux')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "sends the data on to the client" do
|
27
|
+
client.should_receive(:send_data).with('quux')
|
28
|
+
|
29
|
+
glazing.receive_data('quux')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#relay_from_client' do
|
34
|
+
it "sends the data through from the client" do
|
35
|
+
glazing.should_receive(:send_data).with('baz')
|
36
|
+
|
37
|
+
glazing.relay_from_client 'baz'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#unbind' do
|
42
|
+
it "closes the client's connection" do
|
43
|
+
client.should_receive(:close_connection)
|
44
|
+
|
45
|
+
glazing.unbind
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#unbind_client' do
|
50
|
+
it "closes the connection once it's ready" do
|
51
|
+
glazing.should_receive(:close_connection_after_writing)
|
52
|
+
|
53
|
+
glazing.unbind_client
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module EventMachine
|
2
|
+
class Connection; end
|
3
|
+
end
|
4
|
+
|
5
|
+
require './lib/thin/glazed/http_glazing'
|
6
|
+
require './lib/thin/glazed/https_glazing'
|
7
|
+
|
8
|
+
class Thin::Glazed::HttpClient; end
|
9
|
+
|
10
|
+
describe Thin::Glazed::HttpsGlazing do
|
11
|
+
let(:glazing) { Thin::Glazed::HttpsGlazing.new 3444 }
|
12
|
+
let(:client) { double('client', :send_data => true) }
|
13
|
+
|
14
|
+
before :each do
|
15
|
+
EventMachine.stub :connect => client
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#post_init' do
|
19
|
+
it "sets up the SSL connection" do
|
20
|
+
base = File.expand_path File.join(
|
21
|
+
File.dirname(__FILE__), '..', '..', '..', 'lib', 'data'
|
22
|
+
)
|
23
|
+
glazing.should_receive(:start_tls).with(
|
24
|
+
:private_key_file => File.join(base, 'glazed.key'),
|
25
|
+
:cert_chain_file => File.join(base, 'glazed.pem'),
|
26
|
+
:verify_peer => false
|
27
|
+
)
|
28
|
+
|
29
|
+
glazing.post_init
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#receive_data' do
|
34
|
+
it "adds a HTTPS header to the HTTP request" do
|
35
|
+
http = <<-HTTP
|
36
|
+
GET /assets/icons/facebook.png HTTP/1.1
|
37
|
+
Host: localhost:3443
|
38
|
+
Accept: */*\r\n\r
|
39
|
+
HTTP
|
40
|
+
|
41
|
+
https = <<-HTTPS
|
42
|
+
GET /assets/icons/facebook.png HTTP/1.1
|
43
|
+
Host: localhost:3443
|
44
|
+
Accept: */*\r
|
45
|
+
X_FORWARDED_PROTO: https\r\n\r
|
46
|
+
HTTPS
|
47
|
+
|
48
|
+
client.should_receive(:send_data).with(https)
|
49
|
+
|
50
|
+
glazing.receive_data(http)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module EventMachine; end
|
2
|
+
|
3
|
+
module Thin
|
4
|
+
module Glazed
|
5
|
+
class HttpsGlazing; end
|
6
|
+
end
|
7
|
+
module Logging; end
|
8
|
+
end
|
9
|
+
|
10
|
+
require './lib/thin/glazed/server'
|
11
|
+
|
12
|
+
describe Thin::Glazed::Server do
|
13
|
+
let(:server) { Thin::Glazed::Server.new '1.2.3.4', 5678, 1234 }
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
server.stub :log => true
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#start' do
|
20
|
+
it "starts the HTTPS server with the given ports" do
|
21
|
+
EventMachine.should_receive(:start_server).
|
22
|
+
with('1.2.3.4', 5678, Thin::Glazed::HttpsGlazing, 1234)
|
23
|
+
|
24
|
+
server.start
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/thin-glazed.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/thin/glazed/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ['Pat Allan']
|
6
|
+
gem.email = ['pat@freelancing-gods.com']
|
7
|
+
gem.description = 'SSL Proxy for HTTP Thin servers'
|
8
|
+
gem.summary = 'SSL Proxy for HTTP Thin servers that forwards on HTTPS requests to a Thin server with the SSL layer removed.'
|
9
|
+
gem.homepage = 'https://github.com/freelancing-god/thin-glazed'
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map { |file|
|
12
|
+
File.basename(file)
|
13
|
+
}
|
14
|
+
gem.files = `git ls-files`.split("\n")
|
15
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
gem.name = 'thin-glazed'
|
17
|
+
gem.require_paths = ['lib']
|
18
|
+
gem.version = Thin::Glazed::VERSION
|
19
|
+
|
20
|
+
gem.add_runtime_dependency 'eventmachine', '>= 0'
|
21
|
+
gem.add_runtime_dependency 'thin', '>= 1.3.1'
|
22
|
+
|
23
|
+
gem.add_development_dependency 'rake', '~> 0.9.2.2'
|
24
|
+
gem.add_development_dependency 'rspec', '~> 2.8.0'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: thin-glazed
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pat Allan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: eventmachine
|
16
|
+
requirement: &70114487305600 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70114487305600
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: thin
|
27
|
+
requirement: &70114487302780 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.3.1
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70114487302780
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70114487863840 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.9.2.2
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70114487863840
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &70114487861300 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.8.0
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70114487861300
|
58
|
+
description: SSL Proxy for HTTP Thin servers
|
59
|
+
email:
|
60
|
+
- pat@freelancing-gods.com
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- .gitignore
|
66
|
+
- .travis.yml
|
67
|
+
- Gemfile
|
68
|
+
- LICENCE
|
69
|
+
- README.textile
|
70
|
+
- Rakefile
|
71
|
+
- lib/data/glazed.key
|
72
|
+
- lib/data/glazed.pem
|
73
|
+
- lib/rack/handler/thin_glazed.rb
|
74
|
+
- lib/thin-glazed.rb
|
75
|
+
- lib/thin/glazed.rb
|
76
|
+
- lib/thin/glazed/as_default.rb
|
77
|
+
- lib/thin/glazed/capybara.rb
|
78
|
+
- lib/thin/glazed/http_client.rb
|
79
|
+
- lib/thin/glazed/http_glazing.rb
|
80
|
+
- lib/thin/glazed/https_glazing.rb
|
81
|
+
- lib/thin/glazed/server.rb
|
82
|
+
- lib/thin/glazed/version.rb
|
83
|
+
- spec/thin/glazed/http_client_spec.rb
|
84
|
+
- spec/thin/glazed/http_glazing_spec.rb
|
85
|
+
- spec/thin/glazed/https_glazing_spec.rb
|
86
|
+
- spec/thin/glazed/server_spec.rb
|
87
|
+
- thin-glazed.gemspec
|
88
|
+
homepage: https://github.com/freelancing-god/thin-glazed
|
89
|
+
licenses: []
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
hash: 1358594511115786774
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
hash: 1358594511115786774
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 1.8.10
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: SSL Proxy for HTTP Thin servers that forwards on HTTPS requests to a Thin
|
118
|
+
server with the SSL layer removed.
|
119
|
+
test_files:
|
120
|
+
- spec/thin/glazed/http_client_spec.rb
|
121
|
+
- spec/thin/glazed/http_glazing_spec.rb
|
122
|
+
- spec/thin/glazed/https_glazing_spec.rb
|
123
|
+
- spec/thin/glazed/server_spec.rb
|