cloudbridge 0.9.1
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/bin/cloud_mongrel_rails +5 -0
- data/lib/cloud_mongrel.rb +36 -0
- data/lib/cloudserver.rb +71 -0
- data/test/test_cloud_mongrel.rb +19 -0
- data/test/test_cloudserver.rb +16 -0
- metadata +59 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# This is a version of mongrel designed to connect to a cloudbridge server
|
2
|
+
# in order to receive its connections. It is heavily based on the version of
|
3
|
+
# mongrel that swiftiply uses.
|
4
|
+
|
5
|
+
begin
|
6
|
+
load_attempted ||= false
|
7
|
+
require 'cloudserver'
|
8
|
+
require 'mongrel'
|
9
|
+
rescue LoadError
|
10
|
+
unless load_attempted
|
11
|
+
load_attempted = true
|
12
|
+
require 'rubygems'
|
13
|
+
retry
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Mongrel
|
18
|
+
class HttpServer
|
19
|
+
alias_method(:native_initialize, :initialize)
|
20
|
+
|
21
|
+
# Modified to take a hash or array of hosts to listen on as the last argument.
|
22
|
+
def initialize(*args)
|
23
|
+
# If the last arg is a hash or array, take it off and use it for initializing the cloudserver.
|
24
|
+
if (args.last.kind_of?(Hash) || args.last.kind_of?(Array))
|
25
|
+
listen_hosts = args.pop
|
26
|
+
end
|
27
|
+
host, port = args[0], args[1]
|
28
|
+
args[0], args[1] = '0.0.0.0', 0 # make mongrel listen on a random port, we're going to close it after.
|
29
|
+
native_initialize(*args)
|
30
|
+
@host = host
|
31
|
+
@port = port
|
32
|
+
@socket.close
|
33
|
+
@socket = CloudServer.new(@host, @port)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/cloudserver.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
# This class emulates the behaviour of TCPServer, but 'listens' on a cloudbridge
|
4
|
+
# server rather than a local interface. Otherwise attempts to have an identical
|
5
|
+
# interface to TCPServer. At least as far as mongrel uses it.
|
6
|
+
class CloudServer
|
7
|
+
def initialize(cloud_host, cloud_port, listen_hosts = ['*'])
|
8
|
+
@cloud_host = cloud_host
|
9
|
+
@cloud_port = cloud_port
|
10
|
+
@listen_hosts = {}
|
11
|
+
listen_hosts.each {|host, key|
|
12
|
+
@listen_hosts[host] = key
|
13
|
+
}
|
14
|
+
@sockopts = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def setsockopt(*args)
|
18
|
+
@sockopts.push(args)
|
19
|
+
end
|
20
|
+
|
21
|
+
def accept()
|
22
|
+
# Connect to the cloudbridge and let it know we're available for a connection.
|
23
|
+
# This is all entirely syncronous.
|
24
|
+
begin
|
25
|
+
socket = TCPSocket.new(@cloud_host, @cloud_port)
|
26
|
+
@sockopts.each {|opt| socket.setsockopt(*opt) }
|
27
|
+
rescue Errno::ECONNREFUSED
|
28
|
+
sleep(0.5)
|
29
|
+
retry
|
30
|
+
end
|
31
|
+
socket.write("BRIDGE / HTTP/1.1\r\n")
|
32
|
+
@listen_hosts.each {|host, key|
|
33
|
+
socket.write("Host: #{host}" + (key ? " #{key}" : "") + "\r\n")
|
34
|
+
}
|
35
|
+
socket.write("\r\n")
|
36
|
+
code = nil
|
37
|
+
name = nil
|
38
|
+
while (line = socket.gets())
|
39
|
+
line = line.strip
|
40
|
+
if (line == "")
|
41
|
+
case code.to_i
|
42
|
+
when 100 # 100 Continue, just a ping. Ignore.
|
43
|
+
code = name = nil
|
44
|
+
next
|
45
|
+
when 101 # 101 Upgrade, successfuly got a connection.
|
46
|
+
socket.write("HTTP/1.1 100 Continue\r\n\r\n") # let the server know we're still here.
|
47
|
+
return socket
|
48
|
+
when 504 # 504 Gateway Timeout, just retry.
|
49
|
+
socket.close()
|
50
|
+
return accept()
|
51
|
+
else
|
52
|
+
raise "HTTP BRIDGE error #{code}: #{name} waiting for connection."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if (!code && !name)
|
57
|
+
if (match = line.match(%r{^HTTP/1\.[01] ([0-9]{3,3}) (.*)$}))
|
58
|
+
code = match[1]
|
59
|
+
name = match[2]
|
60
|
+
next
|
61
|
+
else
|
62
|
+
raise "Parse error in BRIDGE request reply."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def close()
|
69
|
+
# doesn't need to do anything. Yet.
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$: << '../lib'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'mongrel'
|
5
|
+
require 'cloud_mongrel'
|
6
|
+
|
7
|
+
class SimpleHandler < Mongrel::HttpHandler
|
8
|
+
def process(request, response)
|
9
|
+
response.start(200) do |head,out|
|
10
|
+
head["Content-Type"] = "text/plain"
|
11
|
+
out.write("hello!\n")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
h = Mongrel::HttpServer.new("0.0.0.0", "5432")
|
17
|
+
h.register("/test", SimpleHandler.new)
|
18
|
+
h.register("/files", Mongrel::DirHandler.new("."))
|
19
|
+
h.run.join
|
@@ -0,0 +1,16 @@
|
|
1
|
+
$: << "../lib"
|
2
|
+
|
3
|
+
require "cloudserver"
|
4
|
+
|
5
|
+
server = CloudServer.new(ARGV[0], "5432")
|
6
|
+
threads = []
|
7
|
+
ARGV[1].to_i.times {|threadid|
|
8
|
+
threads.push Thread.new {
|
9
|
+
puts("Thread #{threadid} started")
|
10
|
+
while (client = server.accept)
|
11
|
+
client.write("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: 6\r\n\r\nBlah #{threadid}")
|
12
|
+
client.close
|
13
|
+
end
|
14
|
+
}
|
15
|
+
}
|
16
|
+
threads.each {|thread| thread.join }
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloudbridge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Graham Batty
|
8
|
+
- Kirk Haines (Swiftiply base) (?)
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-02-08 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: CloudBridge is a self-healing minimal-configuration bridge between front-end and backend web servers. This library provides the tools needed to take advantage of it in ruby.
|
18
|
+
email: graham@rubyoncloud.com
|
19
|
+
executables:
|
20
|
+
- cloud_mongrel_rails
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files:
|
26
|
+
- bin/cloud_mongrel_rails
|
27
|
+
- lib/cloud_mongrel.rb
|
28
|
+
- lib/cloudserver.rb
|
29
|
+
- test/test_cloud_mongrel.rb
|
30
|
+
- test/test_cloudserver.rb
|
31
|
+
has_rdoc: true
|
32
|
+
homepage: http://rubyoncloud.com/cloudmachine
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options:
|
35
|
+
- --inline-source
|
36
|
+
- --charset=UTF-8
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.2.0
|
55
|
+
signing_key:
|
56
|
+
specification_version: 2
|
57
|
+
summary: CloudBridge is a self-healing minimal-configuration bridge between front-end and backend web servers. This library provides the tools needed to take advantage of it in ruby.
|
58
|
+
test_files: []
|
59
|
+
|