Permalink
Browse files

Split out client from caldecott

Change-Id: I5ec315dc824264ddb76774e256709b55f3679ef8
  • Loading branch information...
1 parent 7524d9f commit 5cd6c87f7880cb3a1184c7020aa76b213902c6f6 @mariash mariash committed Nov 27, 2012
View
@@ -6,3 +6,4 @@ spec/coverage
*.gem
Gemfile.lock
.rbenv-gemsets
+.idea
View
@@ -1,4 +1,4 @@
source "http://rubygems.org"
gemspec
-
+gem "caldecott-client", "0.0.1", :git => "https://github.com/cloudfoundry/caldecott-client.git", :ref => "e0111356"
View
@@ -21,4 +21,3 @@ THE SOFTWARE.
This software downloads additional open source software components upon install
that are distributed under separate terms and conditions. Please see the license
information provided in the individual software components for more information.
-
View
@@ -14,6 +14,8 @@ spec = Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.extra_rdoc_files = ["README.md", "LICENSE"]
+ s.add_dependency "caldecott-client", "~> 0.0.1"
+
s.add_dependency "em-http-request", "~> 0.3.0"
s.add_dependency "em-websocket", "~> 0.3.1"
s.add_dependency "async_sinatra", "~> 0.5.0"
View
@@ -2,7 +2,7 @@
require 'rubygems'
-require 'caldecott/client'
+require 'caldecott-client'
require 'caldecott/server'
require 'caldecott/session_logger'
View
@@ -1,7 +0,0 @@
-# Copyright (c) 2009-2011 VMware, Inc.
-
-require 'caldecott'
-require 'caldecott/client/client'
-require 'caldecott/client/tunnel'
-require 'caldecott/client/http_tunnel'
-require 'caldecott/client/websocket_tunnel'
@@ -1,79 +0,0 @@
-# Copyright (c) 2009-2011 VMware, Inc.
-
-require 'eventmachine'
-
-module Caldecott
- module Client
- def self.sanitize_url(tun_url)
- tun_url = tun_url =~ /(http|https|ws).*/i ? tun_url : "https://#{tun_url}"
- end
-
- def self.start(opts)
- local_port = opts[:local_port]
- tun_url = opts[:tun_url]
- dst_host = opts[:dst_host]
- dst_port = opts[:dst_port]
- log_file = opts[:log_file]
- log_level = opts[:log_level]
- auth_token = opts[:auth_token]
-
- @quiet = opts[:quiet]
-
- trap("TERM") { stop }
- trap("INT") { stop }
-
- tun_url = sanitize_url(tun_url)
-
- EM.run do
- unless @quiet
- puts "Starting local server on port #{local_port} to #{tun_url}"
- end
-
- EM.start_server("0.0.0.0", local_port, TcpConnection) do |conn|
- # avoid races between tunnel setup and incoming local data
- conn.pause
-
- log = SessionLogger.new("client", log_file)
- log.level = SessionLogger.severity_from_string(log_level)
-
- tun = nil
-
- conn.onopen do
- log.debug "local connected"
- tun = Tunnel.start(log, tun_url, dst_host, dst_port, auth_token)
- end
-
- tun.onopen do
- log.debug "tunnel connected"
- conn.resume
- end
-
- conn.onreceive do |data|
- log.debug "l -> t #{data.length}"
- tun.send_data(data)
- end
-
- tun.onreceive do |data|
- log.debug("l <- t #{data.length}")
- conn.send_data(data)
- end
-
- conn.onclose do
- log.debug "local closed"
- tun.close
- end
-
- tun.onclose do
- log.debug "tunnel closed"
- conn.close_connection_after_writing
- end
- end
- end
- end
-
- def self.stop
- puts "Caldecott shutting down" unless @quiet
- EM.stop
- end
- end
-end
@@ -1,240 +0,0 @@
-# Copyright (c) 2009-2011 VMware, Inc.
-
-require 'em-http'
-require 'json'
-
-module Caldecott
- module Client
- class HttpTunnel
- MAX_RETRIES = 10
-
- def initialize(logger, url, dst_host, dst_port, auth_token)
- @log, @auth_token = logger, auth_token
- @closing = false
- init_msg = ""
-
- # FIXME: why is this optional?
- if dst_host
- init_msg = { :host => dst_host, :port => dst_port }.to_json
- end
-
- start(url, init_msg)
- end
-
- def onopen(&blk)
- @onopen = blk
- @onopen.call if @opened
- end
-
- def onclose(&blk)
- @onclose = blk
- @onclose.call if @closed
- end
-
- def onreceive(&blk)
- @onreceive = blk
- end
-
- def send_data(data)
- @writer.send_data(data)
- end
-
- def close
- return if @closing or @closed
- @closing = true
- @writer.close if @writer
- @reader.close if @reader
- stop
- end
-
- def trigger_on_open
- @opened = true
- @onopen.call if @onopen
- end
-
- def trigger_on_close
- close
- @closed = true
- @onclose.call if @onclose
- @onclose = nil
- end
-
- def trigger_on_receive(data)
- @onreceive.call(data)
- end
-
- def start(base_uri, init_msg, attempts = MAX_RETRIES)
- if attempts <= 0
- trigger_on_close
- return
- end
-
- begin
- parsed_uri = Addressable::URI.parse(base_uri)
- parsed_uri.path = '/tunnels'
-
- @log.debug "post #{parsed_uri.to_s}"
- req = EM::HttpRequest.new(parsed_uri.to_s).post :body => init_msg, :head => { "Auth-Token" => @auth_token, "Content-Length" => init_msg.bytesize }
-
- req.callback do
- @log.debug "post #{parsed_uri.to_s} #{req.response_header.status}"
- unless [200, 201, 204].include?(req.response_header.status)
- start(base_uri, init_msg, attempts - 1)
- else
- resp = JSON.parse(req.response)
-
- parsed_uri.path = resp["path"]
- @tun_uri = parsed_uri.to_s
-
- parsed_uri.path = resp["path_out"]
- @reader = Reader.new(@log, parsed_uri.to_s, self, @auth_token)
-
- parsed_uri.path = resp["path_in"]
- @writer = Writer.new(@log, parsed_uri.to_s, self, @auth_token)
- trigger_on_open
- end
- end
-
- req.errback do
- @log.debug "post #{parsed_uri.to_s} error"
- start(base_uri, init_msg, attempts - 1)
- end
-
- rescue Exception => e
- @log.error e
- trigger_on_close
- raise e
- end
- end
-
- def stop(attempts = MAX_RETRIES)
- if attempts <= 0
- trigger_on_close
- return
- end
-
- return if @tun_uri.nil?
-
- @log.debug "delete #{@tun_uri}"
- req = EM::HttpRequest.new("#{@tun_uri}").delete :head => { "Auth-Token" => @auth_token }
-
- req.errback do
- @log.debug "delete #{@tun_uri} error"
- stop(attempts - 1)
- end
-
- req.callback do
- @log.debug "delete #{@tun_uri} #{req.response_header.status}"
- if [200, 202, 204, 404].include?(req.response_header.status)
- trigger_on_close
- else
- stop(attempts - 1)
- end
- end
- end
-
- class Reader
- def initialize(log, uri, conn, auth_token)
- @log, @base_uri, @conn, @auth_token = log, uri, conn, auth_token
- @closing = false
- start
- end
-
- def close
- @closing = true
- end
-
- def start(seq = 1, attempts = MAX_RETRIES)
- return if @closing
-
- if attempts <= 0
- @conn.trigger_on_close
- return
- end
-
- uri = "#{@base_uri}/#{seq}"
- @log.debug "get #{uri}"
- req = EM::HttpRequest.new(uri).get :timeout => 0, :head => { "Auth-Token" => @auth_token }
-
- req.errback do
- @log.debug "get #{uri} error"
- start(seq, attempts - 1)
- end
-
- req.callback do
- @log.debug "get #{uri} #{req.response_header.status}"
- case req.response_header.status
- when 200
- @conn.trigger_on_receive(req.response)
- start(seq + 1)
- when 404
- @conn.trigger_on_close
- else
- start(seq, attempts - 1)
- end
- end
- end
- end
-
- class Writer
- def initialize(log, uri, conn, auth_token)
- @log, @uri, @conn, @auth_token = log, uri, conn, auth_token
- @seq, @write_buffer = 1, ""
- @closing = @writing = false
- end
-
- def send_data(data)
- @write_buffer << data
- send_data_buffered unless @writing
- end
-
- def close
- @closing = true
- end
-
- private
-
- def send_data_buffered(attempts = MAX_RETRIES)
- return if @closing
-
- @writing = true
-
- @log.debug "attempts left: #{attempts}"
- if attempts <= 0
- @conn.trigger_on_close
- return
- end
-
- data, @write_buffer = @write_buffer, ""
-
- uri = "#{@uri}/#{@seq}"
- @log.debug "put #{uri}"
- req = EM::HttpRequest.new(uri).put :body => data, :head => { "Auth-Token" => @auth_token, "Content-Length" => data.bytesize }
-
- req.errback do
- @log.debug "put #{uri} error"
- send_data_buffered(attempts - 1)
- end
-
- req.callback do
- @log.debug "put #{uri} #{req.response_header.status}"
- case req.response_header.status
- when 200, 202, 204
- @seq += 1
-
- if @write_buffer.empty?
- @writing = false
- else
- send_data_buffered
- end
- when 404
- @conn.trigger_on_close
- else
- send_data_buffered(attempts - 1)
- end
- end
- end
- end
- end
- end
-end
@@ -1,23 +0,0 @@
-# Copyright (c) 2009-2011 VMware, Inc.
-
-require 'addressable/uri'
-
-module Caldecott
- module Client
- module Tunnel
- # Note: I wanted to do this with self#new but had issues
- # with getting send :initialize to figure out the right
- # number of arguments
- def self.start(logger, tun_url, dst_host, dst_port, auth_token)
- case Addressable::URI.parse(tun_url).normalized_scheme
- when "http", "https"
- HttpTunnel.new(logger, tun_url, dst_host, dst_port, auth_token)
- when "ws"
- WebSocketTunnel.new(logger, tun_url, dst_host, dst_port, auth_token)
- else
- raise "invalid url"
- end
- end
- end
- end
-end
Oops, something went wrong.

0 comments on commit 5cd6c87

Please sign in to comment.