rflow-components-http 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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