Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit 888adb6b9ce6c4e3375c0fcc10397b7ecae42156 0 parents
@stve authored
0  .gemtest
No changes.
17 .gitignore
@@ -0,0 +1,17 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
3  .rspec
@@ -0,0 +1,3 @@
+--color
+--format=nested
+--backtrace
1  .simplecov
@@ -0,0 +1 @@
+SimpleCov.start
3  .yardopts
@@ -0,0 +1,3 @@
+--markup markdown
+-
+LICENSE.md
4 Gemfile
@@ -0,0 +1,4 @@
+source 'http://rubygems.org'
+
+# Specify your gem's dependencies in pow_proxy.gemspec
+gemspec
20 LICENSE.md
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Steve Agalloco, Assaf Arkin
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 Rakefile
@@ -0,0 +1,18 @@
+#!/usr/bin/env rake
+
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rspec/core/rake_task'
+RSpec::Core::RakeTask.new(:spec)
+
+task :default => :spec
+task :test => :spec
+
+require 'yard'
+namespace :doc do
+ YARD::Rake::YardocTask.new do |task|
+ task.files = ['LICENSE.md', 'lib/**/*.rb']
+ task.options = ['--markup', 'markdown']
+ end
+end
32 Readme.md
@@ -0,0 +1,32 @@
+PowProxy
+========
+
+PowProxy is a simple rack-based proxy that allows you to run your node apps through [Pow](http://pow.cx).
+
+PowProxy is based on a blog post by [Assaf Arkin](/assaf). It's super easy to use. You really should just read [Assaf's blog post](http://labnotes.org/2011/08/09/using-pow-with-your-node-js-project/) to get the full explanation.
+
+Usage
+-----
+
+Create a `config.ru` file in your project's root with the following:
+
+```ruby
+require 'pow_proxy'
+run PowProxy.new
+```
+
+By default, it assumes the host to be `localhost` and the port to be `3000` however you can configure that to be anything you'd like:
+
+```ruby
+require 'pow_proxy'
+run PowProxy.new(:host => '127.0.0.1', :port => 8080)
+```
+
+You can also set the host and port by exporting the `HOST` and `PORT` environment variables in your `.powenv`.
+
+Make sure your node app is running, symlink your app so that Pow knows about it and you'll be all set.
+
+Copyright
+---------
+
+Copyright (c) 2011 Steve Agalloco, Assaf Arkin. See [LICENSE](LICENSE.md) for details.
39 lib/pow_proxy.rb
@@ -0,0 +1,39 @@
+require "net/http"
+require "rack"
+
+class PowProxy
+ DEFAULT_HOST = "127.0.0.1"
+ DEFAULT_PORT = 3000
+
+ attr_reader :host, :port
+
+ def initialize(options = {})
+ @host = options.delete(:host) || ENV['HOST'] || DEFAULT_HOST
+ @port = options.delete(:port) || ENV['PORT'] || DEFAULT_PORT
+ end
+
+ def call(env)
+ begin
+ request = Rack::Request.new(env)
+ headers = {}
+ env.each do |key, value|
+ if key =~ /^http_(.*)/i
+ headers[$1] = value
+ end
+ end
+
+ headers["Content-Type"] = request.content_type if request.content_type
+ headers["Content-Length"] = request.content_length if request.content_length
+
+ http = Net::HTTP.new(@host, @port)
+ http.start do |http|
+ response = http.send_request(request.request_method, request.fullpath, request.body.read, headers)
+ headers = response.to_hash
+ headers.delete "transfer-encoding"
+ [response.code, headers, [response.body]]
+ end
+ rescue Errno::ECONNREFUSED
+ [500, {}, ["Could not establish a connection to #{@host}:#{@port}, make sure your node process is running."]]
+ end
+ end
+end
3  lib/pow_proxy/version.rb
@@ -0,0 +1,3 @@
+class PowProxy
+ VERSION = "0.0.1"
+end
26 pow_proxy.gemspec
@@ -0,0 +1,26 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/pow_proxy/version', __FILE__)
+
+Gem::Specification.new do |gem|
+ gem.name = "pow_proxy"
+ gem.version = PowProxy::VERSION
+
+ gem.authors = ["Steve Agalloco"]
+ gem.email = ["steve.agalloco@gmail.com"]
+ gem.description = 'A simple rack-based proxy that allows you to run your node apps through Pow.'
+ gem.summary = gem.description
+ gem.homepage = "https://github.com/spagalloco/pow_proxy"
+
+ gem.add_dependency 'rack'
+ gem.add_development_dependency 'rake', '~> 0.9'
+ gem.add_development_dependency 'rdiscount', '~> 1.6'
+ gem.add_development_dependency 'rspec', '~> 2.7'
+ gem.add_development_dependency 'simplecov', '~> 0.5'
+ gem.add_development_dependency 'yard', '~> 0.7'
+ gem.add_development_dependency 'webmock', '~> 1.7'
+
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ gem.files = `git ls-files`.split("\n")
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ gem.require_paths = ["lib"]
+end
100 spec/pow_proxy_spec.rb
@@ -0,0 +1,100 @@
+require 'spec_helper'
+
+describe PowProxy do
+
+ describe '.new' do
+ context 'defaults' do
+ before do
+ @proxy = PowProxy.new
+ end
+
+ it 'defaults the host to "127.0.0.1"' do
+ @proxy.host.should eq('127.0.0.1')
+ end
+
+ it 'defaults the port to 3000' do
+ @proxy.port.should eq(3000)
+ end
+ end
+
+ context 'options' do
+ before do
+ @proxy = PowProxy.new(:host => 'localhost2', :port => 4242)
+ end
+
+ it 'sets the host to "localhost2"' do
+ @proxy.host.should eq('localhost2')
+ end
+
+ it 'sets the port to 4242' do
+ @proxy.port.should eq(4242)
+ end
+ end
+
+ context 'ENV' do
+ before do
+ ENV['HOST'] = 'monk.local'
+ ENV['PORT'] = '8080'
+ @proxy = PowProxy.new
+ end
+
+ it 'defaults the host to "monk.local"' do
+ @proxy.host.should eq('monk.local')
+ end
+
+ it 'defaults the port to 8080' do
+ @proxy.port.should eq('8080')
+ end
+ end
+ end
+
+ describe 'integration' do
+ before do
+ @proxy = PowProxy.new(:host => 'app.local', :port => 2121)
+ end
+
+ it 'returns the requested content' do
+ stub_request(:get, "http://app.local:2121/").
+ with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
+ to_return(:status => 200, :body => "abcdefg", :headers => {})
+
+ env = { "REQUEST_METHOD"=>"GET", "PATH_INFO"=>"/", "rack.input" => StringIO.new }
+ response = @proxy.call(env)
+ body = response.last.shift
+ body.should eq('abcdefg')
+ end
+
+ it 'removes the transfer-encoding header from the response' do
+ stub_request(:get, "http://app.local:2121/").
+ with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
+ to_return(:status => 200, :body => "abcdefg", :headers => { 'Transfer-Encoding' => 'chunked'})
+
+ env = { "REQUEST_METHOD"=>"GET", "PATH_INFO"=>"/", "rack.input" => StringIO.new }
+ response = @proxy.call(env)
+ headers = response[1]
+ headers.should_not have_key('transfer-encoding')
+ end
+
+ it 'passes headers to the node server' do
+ stub_request(:get, "http://app.local:2121/").
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip,deflate,sdch', 'User-Agent'=>'Ruby'}).
+ to_return(:status => 200, :body => "abcdefg", :headers => {})
+
+ env = { "REQUEST_METHOD"=>"GET", "PATH_INFO"=>"/", "rack.input" => StringIO.new, 'HTTP_ACCEPT_ENCODING' => "gzip,deflate,sdch" }
+ response = @proxy.call(env)
+ body = response.last.shift
+ body.should eq('abcdefg')
+ end
+
+ it 'reports an error when it cannot request to the node server' do
+ Rack::Request.stub(:new).and_raise(Errno::ECONNREFUSED)
+
+ env = { "REQUEST_METHOD"=>"GET", "PATH_INFO"=>"/", "rack.input" => StringIO.new }
+ response = @proxy.call(env)
+ response.first.should eq(500)
+ body = response.last.shift
+ body.should match(/Could not establish a connection/)
+ end
+ end
+
+end
6 spec/spec_helper.rb
@@ -0,0 +1,6 @@
+$:.unshift File.expand_path('..', __FILE__)
+$:.unshift File.expand_path('../../lib', __FILE__)
+require 'simplecov'
+require 'pow_proxy'
+require 'rspec'
+require 'webmock/rspec'
Please sign in to comment.
Something went wrong with that request. Please try again.