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 +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
|