thin-glazed 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|