Skip to content
Browse files

first commit

  • Loading branch information...
0 parents commit 096a20473f8fcf44157b702acdf98848277028f5 @lest lest committed Dec 15, 2010
Showing with 224 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +4 −0 Manifest
  3. +15 −0 Rakefile
  4. +71 −0 bin/proxylocal
  5. +133 −0 lib/client.rb
1 .gitignore
@@ -0,0 +1 @@
+/pkg
4 Manifest
@@ -0,0 +1,4 @@
+Manifest
+Rakefile
+bin/proxylocal
+lib/client.rb
15 Rakefile
@@ -0,0 +1,15 @@
+require 'rubygems'
+require 'rake'
+require 'echoe'
+
+require 'lib/client'
+
+Echoe.new('proxylocal', ProxyLocal::VERSION) do |p|
+ p.summary = 'Proxy your local web-server and make it publicly available over the internet'
+ p.url = 'http://proxylocal.com/'
+ p.author = 'Just Lest'
+ p.email = 'just.lest@gmail.com'
+ p.runtime_dependencies = ['eventmachine >=0.12.10', 'bert >=1.1.2']
+ p.require_signed = true
+ p.project = nil
+end
71 bin/proxylocal
@@ -0,0 +1,71 @@
+#!/usr/bin/env ruby
+
+require 'optparse'
+require 'yaml'
+require File.expand_path('client', File.join(File.dirname(__FILE__), '..', 'lib'))
+
+rc_path = File.expand_path(File.join('~', '.proxylocalrc'))
+rc = YAML.load_file(rc_path) rescue {}
+
+options = rc.dup
+
+begin
+ cmd_args = OptionParser.new do |opts|
+ opts.banner = 'Usage: proxylocal [options] [PORT]'
+
+ opts.on('--token TOKEN', 'Save token to .proxylocalrc') do |token|
+ rc[:token] = token
+ File.open(rc_path, 'w') { |f| f.write(YAML.dump(rc)) }
+ File.chmod(0600, rc_path)
+ exit
+ end
+
+ opts.on('--host HOST', 'Bind to host') do |host|
+ options[:hosts] ||= []
+ options[:hosts] << host
+ end
+
+ opts.on('--[no-]tls', 'Use TLS') do |tls|
+ options[:tls] = tls
+ end
+
+ opts.on('-s', '--server SERVER', 'Specify proxylocal server') do |s|
+ options[:server_host], options[:server_port] = s.split(':')
+ end
+
+ opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
+ options[:verbose] = v
+ end
+
+ opts.on_tail("--version", "Show version") do
+ puts ProxyLocal::VERSION
+ exit
+ end
+
+ opts.on_tail('-h', '--help', 'Show this message') do
+ puts opts
+ exit
+ end
+ end.parse!
+rescue OptionParser::MissingArgument => e
+ puts e
+ exit
+rescue OptionParser::InvalidOption => e
+ puts e
+ exit
+end
+
+options[:local_port] = cmd_args[0]
+
+default_options = {
+ :server_host => 'proxylocal.com',
+ :server_port => '8282',
+ :local_port => '80',
+ :tls => false,
+ :verbose => false,
+ :version => ProxyLocal::VERSION
+}
+
+options = default_options.merge(options.reject { |k, v| v.nil? })
+
+ProxyLocal::Client.run(options)
133 lib/client.rb
@@ -0,0 +1,133 @@
+require 'logger'
+require 'rubygems'
+require 'eventmachine'
+require 'bert'
+
+module ProxyLocal
+ VERSION = '0.2.2'
+
+ module Serializer
+ def self.dump(object)
+ BERT.encode(object)
+ end
+
+ def self.load(data)
+ BERT.decode(data)
+ end
+ end
+
+ class Client < EventMachine::Connection
+ include EventMachine::Protocols::ObjectProtocol
+
+ def self.run(options = {})
+ @@logger = Logger.new(STDOUT)
+ @@logger.level = options[:verbose] ? Logger::INFO : Logger::WARN
+
+ @@logger.info("Run with options #{options.inspect}")
+
+ trap "SIGCLD", "IGNORE"
+ trap "INT" do
+ puts
+ EventMachine.run
+ exit
+ end
+
+ EventMachine.run do
+ EventMachine.connect(options[:server_host], options[:server_port], self) do |c|
+ c.instance_eval do
+ @options = options
+ if @options[:tls]
+ @@logger.info("Request TLS")
+ send_object(:start_tls)
+ else
+ send_options
+ end
+ end
+ end
+ end
+ end
+
+ def serializer
+ Serializer
+ end
+
+ def send_options
+ send_object(BERT::Tuple[:options, @options])
+ end
+
+ def post_init
+ @connections = {}
+ end
+
+ def ssl_handshake_completed
+ send_options
+ end
+
+ def first_line(data)
+ data.split(/\r?\n/, 2).first
+ end
+
+ def receive_object(message)
+ message = [message] unless message.is_a?(Array)
+
+ case message[0]
+ when :start_tls
+ @@logger.info("Start TLS")
+ start_tls
+ when :message
+ puts message[1]
+ when :halt
+ EventMachine.stop_event_loop
+ when :connection
+ _, id = message
+ @@logger.info("New connection")
+ connection = EventMachine.connect('127.0.0.1', @options[:local_port], ClientProxy)
+ connection.on_data do |data|
+ send_object(BERT::Tuple[:stream, id, data])
+ end
+ connection.on_unbind do
+ @@logger.info("Connection closed")
+ @connections.delete(id)
+ send_object(BERT::Tuple[:close, id])
+ end
+ @connections[id] = connection
+ when :stream
+ _, id, data = message
+ @connections[id].send_data(data)
+ when :close
+ _, id = message
+ connection = @connections.delete(id)
+ connection.close_connection_after_writing if connection
+ else
+ @@logger.info("Received #{message.inspect}")
+ end
+ end
+
+ def unbind
+ EventMachine.stop_event_loop
+ puts "A connection has been terminated"
+ end
+ end
+
+ class ClientProxy < EventMachine::Connection
+ def post_init
+ @callbacks = {}
+ end
+
+ def receive_data(data)
+ @callbacks[:on_data].call(data) if @callbacks.has_key?(:on_data)
+ end
+
+ def unbind
+ @callbacks[:on_unbind].call if @callbacks.has_key?(:on_unbind)
+ end
+
+ def on_data(&block)
+ @callbacks[:on_data] = block
+ end
+
+ def on_unbind(&block)
+ @callbacks[:on_unbind] = block
+ end
+ end
+end

0 comments on commit 096a204

Please sign in to comment.
Something went wrong with that request. Please try again.