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 +4 -4
- data/.travis.yml +1 -0
- data/lib/rflow/components/http/server.rb +59 -12
- data/lib/rflow/components/http/version.rb +1 -1
- data/rflow-components-http.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79e24768d609cc10c8e73a69b385f0a6adf75796
|
4
|
+
data.tar.gz: 5e4d61fbe3a1d235e2983909fda709765f6f8b0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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 #{
|
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 #{
|
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 =
|
67
|
-
m.data.client_port =
|
68
|
-
m.data.server_ip =
|
69
|
-
m.data.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 #{
|
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 #{
|
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 #{
|
119
|
-
server.
|
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
|
@@ -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
|
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
|
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:
|
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
|
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
|
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.
|
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
|