Class: Bridge::TCPSocket
- Inherits:
-
TCPSocket
- Object
- TCPSocket
- Bridge::TCPSocket
- Defined in:
- lib/bridge/tcp_server.rb
Overview
This is the class returned by TCPServer.accept. It is a TCPSocket with a couple of extra features.
Defined Under Namespace
Classes: RetryError
Instance Method Summary collapse
-
#initialize(cloud_host, cloud_port, listen_hosts, listen_keys) ⇒ TCPSocket
constructor
A new instance of TCPSocket.
- #send_bridge_request ⇒ Object
-
#setup ⇒ Object
This does the full setup process on the request, returning only when the connection is actually available.
-
#verify ⇒ Object
This just tries to determine if the server will honor requests as specified above so that the TCPServer initializer can error out early if it won’t.
Constructor Details
#initialize(cloud_host, cloud_port, listen_hosts, listen_keys) ⇒ TCPSocket
Returns a new instance of TCPSocket.
14 15 16 17 18 19 20 21 |
# File 'lib/bridge/tcp_server.rb', line 14 def initialize(cloud_host, cloud_port, listen_hosts, listen_keys) @cloud_host = cloud_host @cloud_port = cloud_port @listen_hosts = listen_hosts @listen_keys = listen_keys super(@cloud_host, @cloud_port) end |
Instance Method Details
#send_bridge_request ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/bridge/tcp_server.rb', line 23 def send_bridge_request() write("BRIDGE / HTTP/1.1\r\n") write("Expect: 100-continue\r\n") @listen_hosts.each {|host| write("Host: #{host}\r\n") } @listen_keys.each {|key| write("Host-Key: #{key}\r\n") } write("\r\n") end |
#setup ⇒ Object
This does the full setup process on the request, returning only when the connection is actually available.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/bridge/tcp_server.rb', line 63 def setup() send_bridge_request code = nil name = nil headers = [] while (line = gets()) line = line.strip if (line == "") case code.to_i when 100 # 100 Continue, just a ping. Ignore. code = name = nil headers = [] next when 101 # 101 Upgrade, successfuly got a connection. write("HTTP/1.1 100 Continue\r\n\r\n") # let the server know we're still here. return self when 401 # 401 Access Denied, key wasn't right. close() raise "HTTP BRIDGE error #{code}: host key was invalid or missing, but required." when 503, 504 # 503 Service Unavailable or 504 Gateway Timeout, just retry. close() sleep_time = headers.find {|header| header["Retry-After"] } || 5 raise RetryError.new("BRIDGE server timed out or is overloaded, wait #{sleep_time}s to try again.", sleep_time) else raise "HTTP BRIDGE error #{code}: #{name} waiting for connection." end end if (!code && !name) # This is the initial response line if (match = line.match(%r{^HTTP/1\.[01] ([0-9]{3,3}) (.*)$})) code = match[1] name = match[2] next else raise "Parse error in BRIDGE request reply." end else if (match = line.match(%r{^(.+?):\s+(.+)$})) headers.push({match[1] => match[2]}) else raise "Parse error in BRIDGE request reply's headers." end end end return nil end |
#verify ⇒ Object
This just tries to determine if the server will honor requests as specified above so that the TCPServer initializer can error out early if it won’t.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/bridge/tcp_server.rb', line 38 def verify() send_bridge_request() begin line = gets() match = line.match(%r{^HTTP/1\.[01] ([0-9]{3,3}) (.*)$}) if (!match) raise "HTTP BRIDGE error: bridge server sent incorrect reply to bridge request." end case code = match[1].to_i when 100, 101 return true when 401 # 401 Access Denied, key wasn't right. raise "HTTP BRIDGE error #{code}: host key was invalid or missing, but required." when 503, 504 # 503 Service Unavailable or 504 Gateway Timeout raise "HTTP BRIDGE error #{code}: could not verify server can handle requests because it's overloaded." else raise "HTTP BRIDGE error #{code}: #{match[2]} unknown error connecting to bridge server." end ensure close() # once we do this, we just assume the connection is useless. end end |