rflow-components-http 1.0.1 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0183b24ca93c01e10195f3a436fd76b44863dfe5
4
- data.tar.gz: 7868db2089a6b7e30b58ddf8d6f39a9eb77ae8b9
3
+ metadata.gz: 79e24768d609cc10c8e73a69b385f0a6adf75796
4
+ data.tar.gz: 5e4d61fbe3a1d235e2983909fda709765f6f8b0a
5
5
  SHA512:
6
- metadata.gz: e97d00002ee102a0ea59e5b1123778ed2a3cdb108dada488902d4ce8bef97fb5284c21d1538849892b17f1e45b6d409bcb79844198647271a6092837e67b73d6
7
- data.tar.gz: 80d0783989f62e22ecfa28545edac5b75665b84da65b9b4c75c17d036414ff35f523d8f0ebcb30f131cfb3f21d1f5a2e0a7a364d51d85d996d7f49dfeda103f6
6
+ metadata.gz: cb3f4b7aee8590a9eb80f5307930ffe05466d8a869f3a36efadb58a587795be6ef604355395e6ad976a0ed62102136261bfde0116b56d41826c86bb794e117f8
7
+ data.tar.gz: 787b9b10ec5eafe8bcf1c9277c1784e1f974fa41c2da72bd207ecf3593c844dfba05cf290f3145bb3769ed6c61487e803602b1371795cd0a92e4b80010ececc2
data/.travis.yml CHANGED
@@ -8,6 +8,7 @@ rvm:
8
8
  before_install:
9
9
  - sudo apt-get install libtool autoconf automake uuid-dev build-essential
10
10
  - wget http://download.zeromq.org/zeromq-3.2.4.tar.gz && tar zxvf zeromq-3.2.4.tar.gz && cd zeromq-3.2.4 && ./configure && make && sudo make install && cd ..
11
+ - gem update bundler
11
12
  # Only has 4.0.4, need 3.2 version due to old em-zeromq
12
13
  # - sudo add-apt-repository -y ppa:chris-lea/zeromq
13
14
  # - sudo apt-get update
@@ -9,19 +9,26 @@ class RFlow
9
9
  input_port :response_port
10
10
  output_port :request_port
11
11
 
12
- attr_accessor :port, :listen, :server_signature, :connections
12
+ attr_accessor :port, :listen, :server_signature, :connections, :closed_connections,
13
+ :proxy_real_client_ip_header, :proxy_real_client_port_header,
14
+ :proxy_real_server_ip_header, :proxy_real_server_port_header
13
15
 
14
16
  def configure!(config)
15
17
  @listen = config['listen'] ? config['listen'] : '127.0.0.1'
16
18
  @port = config['port'] ? config['port'].to_i : 8000
19
+ @proxy_real_client_ip_header = config.has_key?('proxy-real-client-ip-header') ? config['proxy-real-client-ip-header'] : 'X-Real-IP'
20
+ @proxy_real_client_port_header = config.has_key?('proxy-real-client-port-header') ? config['proxy-real-client-port-header'] : 'X-Real-Port'
21
+ @proxy_real_server_ip_header = config.has_key?('proxy-real-server-ip-header') ? config['proxy-real-server-ip-header'] : 'X-Server-IP'
22
+ @proxy_real_server_port_header = config.has_key?('proxy-real-server-port-header') ? config['proxy-real-server-port-header'] : 'X-Server-Port'
17
23
  @connections = {}
24
+ @closed_connections = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
18
25
  end
19
26
 
20
27
  def run!
21
28
  @server_signature = EM.start_server(@listen, @port, Connection) do |conn|
22
29
  conn.server = self
23
30
  self.connections[conn.signature.to_s] = conn
24
- RFlow.logger.debug { "#{name}: Connection from #{conn.client_ip}:#{conn.client_port} to #{conn.server_ip}:#{conn.server_port}" }
31
+ RFlow.logger.debug { "#{name}: Connection from #{conn.client_details} to #{conn.server_details}" }
25
32
  end
26
33
  end
27
34
 
@@ -37,10 +44,24 @@ class RFlow
37
44
  connection_signature_string = processing_event.context.to_s
38
45
  if connections[connection_signature_string]
39
46
  connections[connection_signature_string].send_http_response message
47
+ else
48
+ conn = closed_connections.read(connection_signature_string)
49
+ if conn
50
+ RFlow.logger.info "#{name}: Could not send HTTP response to #{conn.client_details}: connection is already closed"
51
+ else
52
+ RFlow.logger.info "#{name}: Could not send HTTP response to <client details expired>: connection is already closed"
53
+ end
40
54
  end
41
55
  end
42
56
  end
43
57
 
58
+ class ClosedConnection
59
+ attr_accessor :client_details
60
+ def initialize(client_details)
61
+ @client_details = client_details
62
+ end
63
+ end
64
+
44
65
  class Connection < EventMachine::Connection
45
66
  include EventMachine::HttpServer
46
67
 
@@ -54,19 +75,35 @@ class RFlow
54
75
  no_environment_strings
55
76
  end
56
77
 
78
+ def client_details
79
+ if @real_client_ip
80
+ "#{client_ip}:#{client_port} (proxied from #{@real_client_ip}:#{@real_client_port})"
81
+ else
82
+ "#{client_ip}:#{client_port}"
83
+ end
84
+ end
85
+
86
+ def server_details
87
+ if @real_server_ip
88
+ "#{server_ip}:#{server_port} (proxied as #{@real_server_ip}:#{@real_server_port})"
89
+ else
90
+ "#{server_ip}:#{server_port}"
91
+ end
92
+ end
93
+
57
94
  def receive_data(data)
58
- RFlow.logger.debug { "#{server.name}: Received #{data.bytesize} bytes of data from #{client_ip}:#{client_port} to #{@server_ip}:#{@server_port}" }
95
+ RFlow.logger.debug { "#{server.name}: Received #{data.bytesize} bytes of data from #{client_details} to #{server_details}" }
59
96
  super
60
97
  end
61
98
 
62
99
  def process_http_request
63
- RFlow.logger.debug { "#{server.name}: Received HTTP request from #{client_ip}:#{client_port} to #{@server_ip}:#{@server_port} for #{@http_request_uri}" }
100
+ RFlow.logger.debug { "#{server.name}: Received HTTP request from #{client_details} to #{server_details} for #{@http_request_uri}" }
64
101
 
65
102
  server.request_port.send_message(RFlow::Message.new('RFlow::Message::Data::HTTP::Request').tap do |m|
66
- m.data.client_ip = @client_ip
67
- m.data.client_port = @client_port
68
- m.data.server_ip = @server_ip
69
- m.data.server_port = @server_port
103
+ m.data.client_ip = client_ip
104
+ m.data.client_port = client_port
105
+ m.data.server_ip = server_ip
106
+ m.data.server_port = server_port
70
107
 
71
108
  m.data.method = @http_request_method
72
109
  m.data.uri = @http_request_uri
@@ -78,6 +115,15 @@ class RFlow
78
115
  @http_headers.split(/\0/).each do |header|
79
116
  name, val = header.split(/:\s*/, 2)
80
117
  m.data.headers[name] = val
118
+ if server.proxy_real_client_ip_header && (name == server.proxy_real_client_ip_header)
119
+ @real_client_ip ||= val
120
+ elsif server.proxy_real_client_port_header && (name == server.proxy_real_client_port_header)
121
+ @real_client_port ||= val
122
+ elsif server.proxy_real_server_ip_header && (name == server.proxy_real_server_ip_header)
123
+ @real_server_ip ||= val
124
+ elsif server.proxy_real_server_port_header && (name == server.proxy_real_server_port_header)
125
+ @real_server_port ||= val
126
+ end
81
127
  end
82
128
 
83
129
  m.provenance << RFlow::Message::ProcessingEvent.new(server.uuid, Time.now.utc).tap do |e|
@@ -86,7 +132,7 @@ class RFlow
86
132
  end
87
133
  end)
88
134
  rescue Exception => e
89
- RFlow.logger.error "#{server.name}: Error processing HTTP request from #{client_ip}:#{client_port} to #{@server_ip}:#{@server_port} for #{@http_request_uri}: #{e.class.name}: #{e.message}, because: #{e.backtrace.inspect}"
135
+ RFlow.logger.error "#{server.name}: Error processing HTTP request from #{client_details} to #{server_details} for #{@http_request_uri}: #{e.class.name}: #{e.message}, because: #{e.backtrace.inspect}"
90
136
  end
91
137
 
92
138
  def send_http_response(response_message = nil)
@@ -106,7 +152,7 @@ class RFlow
106
152
  end
107
153
  end
108
154
 
109
- RFlow.logger.debug { "#{server.name}: Sending an HTTP response #{resp.status} to #{client_ip}:#{client_port}" }
155
+ RFlow.logger.debug { "#{server.name}: Sending an HTTP response #{resp.status} to #{client_details}" }
110
156
 
111
157
  resp.send_response
112
158
  close_connection_after_writing
@@ -115,8 +161,9 @@ class RFlow
115
161
  # Called when a connection is torn down for whatever reason.
116
162
  # Remove this connection from the server's list
117
163
  def unbind(reason = nil)
118
- RFlow.logger.debug { "#{server.name}: Disconnected from HTTP client #{client_ip}:#{client_port}#{reason.nil? ? '' : " due to '#{reason}'"}" }
119
- server.connections.delete(self.signature.to_s)
164
+ RFlow.logger.debug { "#{server.name}: Disconnected from HTTP client #{client_details}#{reason.nil? ? '' : " due to '#{reason}'"}" }
165
+ server.closed_connections.write(signature.to_s, ClosedConnection.new(client_details))
166
+ server.connections.delete(signature.to_s)
120
167
  super()
121
168
  end
122
169
  end
@@ -1,7 +1,7 @@
1
1
  class RFlow
2
2
  module Components
3
3
  module HTTP
4
- VERSION = "1.0.1"
4
+ VERSION = "1.1.0"
5
5
  end
6
6
  end
7
7
  end
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
22
  s.require_paths = ["lib"]
23
23
 
24
- s.add_dependency 'rflow', '~> 1.0.0'
24
+ s.add_dependency 'rflow', '~> 1.0'
25
25
  s.add_dependency 'eventmachine_httpserver_update', '~> 0.2.1'
26
26
 
27
27
  s.add_development_dependency 'rspec', '~> 3.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rflow-components-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael L. Artz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-17 00:00:00.000000000 Z
11
+ date: 2016-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rflow
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.0
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.0
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: eventmachine_httpserver_update
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -129,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
129
  version: '0'
130
130
  requirements: []
131
131
  rubyforge_project: rflow-components-http
132
- rubygems_version: 2.3.0
132
+ rubygems_version: 2.2.2
133
133
  signing_key:
134
134
  specification_version: 4
135
135
  summary: HTTP client and server components for the RFlow FBP framework