experella-proxy 0.0.10 → 0.0.11
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.
- data/bin/experella-proxy +5 -5
- data/config/default/config.rb +15 -16
- data/dev/experella-proxy +3 -4
- data/experella-proxy.gemspec +2 -2
- data/lib/experella-proxy/backend.rb +3 -5
- data/lib/experella-proxy/backend_server.rb +20 -22
- data/lib/experella-proxy/configuration.rb +19 -23
- data/lib/experella-proxy/connection.rb +29 -37
- data/lib/experella-proxy/connection_manager.rb +16 -21
- data/lib/experella-proxy/globals.rb +5 -7
- data/lib/experella-proxy/http_status_codes.rb +37 -38
- data/lib/experella-proxy/proxy.rb +8 -9
- data/lib/experella-proxy/request.rb +12 -13
- data/lib/experella-proxy/response.rb +28 -34
- data/lib/experella-proxy/server.rb +1 -6
- data/lib/experella-proxy/version.rb +5 -1
- data/lib/experella-proxy.rb +9 -10
- data/spec/echo-server/echo_server.rb +4 -6
- data/spec/experella-proxy/backend_server_spec.rb +16 -18
- data/spec/experella-proxy/configuration_spec.rb +4 -4
- data/spec/experella-proxy/connection_manager_spec.rb +15 -16
- data/spec/experella-proxy/experella-proxy_spec.rb +73 -76
- data/spec/experella-proxy/request_spec.rb +7 -7
- data/spec/experella-proxy/response_spec.rb +6 -6
- data/spec/fixtures/spec.log +187 -187
- data/spec/fixtures/test_config.rb +8 -10
- data/spec/spec_helper.rb +4 -5
- data/test/sinatra/hello_world_server.rb +0 -3
- data/test/sinatra/server_one.rb +1 -4
- data/test/sinatra/server_two.rb +2 -4
- metadata +3 -3
@@ -1,5 +1,4 @@
|
|
1
1
|
module ExperellaProxy
|
2
|
-
|
3
2
|
# static getter for the connection_manager variable
|
4
3
|
#
|
5
4
|
# @return [ConnectionManager] connection_manager
|
@@ -9,13 +8,12 @@ module ExperellaProxy
|
|
9
8
|
|
10
9
|
# The ConnectionManager is responsible for queueing and matching frontend {Connection} and {BackendServer} objects
|
11
10
|
class ConnectionManager
|
12
|
-
|
13
11
|
# The constructor
|
14
12
|
#
|
15
13
|
def initialize
|
16
|
-
@connection_queue = [] #array queue of client connection objects
|
17
|
-
@backend_queue = [] #array queue of available backend servers
|
18
|
-
@backend_list = {} #list of all backend servers
|
14
|
+
@connection_queue = [] # array queue of client connection objects
|
15
|
+
@backend_queue = [] # array queue of available backend servers
|
16
|
+
@backend_list = {} # list of all backend servers
|
19
17
|
end
|
20
18
|
|
21
19
|
# Matches {Request} to queued {BackendServer}
|
@@ -34,16 +32,16 @@ module ExperellaProxy
|
|
34
32
|
def backend_available?(request)
|
35
33
|
@backend_queue.each do |backend|
|
36
34
|
if backend.accept?(request)
|
37
|
-
#connect backend to requests connection if request matches
|
35
|
+
# connect backend to requests connection if request matches
|
38
36
|
backend.workload += 1
|
39
37
|
ret = @backend_queue.delete(backend)
|
40
|
-
#requeue backend if concurrency isnt maxed
|
38
|
+
# requeue backend if concurrency isnt maxed
|
41
39
|
@backend_queue.push(backend) if backend.workload < backend.concurrency
|
42
40
|
return ret
|
43
41
|
end
|
44
42
|
end
|
45
43
|
if match_any_backend?(request)
|
46
|
-
#push requests connection on queue if no backend was connected
|
44
|
+
# push requests connection on queue if no backend was connected
|
47
45
|
@connection_queue.push(request.conn)
|
48
46
|
:queued
|
49
47
|
else
|
@@ -58,14 +56,14 @@ module ExperellaProxy
|
|
58
56
|
# @param backend [BackendServer] BackendServer which got free
|
59
57
|
# @return [NilClass]
|
60
58
|
def free_backend(backend)
|
61
|
-
#check if any queued connections match new available backend
|
59
|
+
# check if any queued connections match new available backend
|
62
60
|
conn = match_connections(backend)
|
63
61
|
if conn
|
64
|
-
#return matching connection
|
65
|
-
#you should try to connect the new backend to this connection
|
62
|
+
# return matching connection
|
63
|
+
# you should try to connect the new backend to this connection
|
66
64
|
return conn
|
67
65
|
else
|
68
|
-
#push free backend on queue if it wasn't used for a queued conn or is already queued (concurrency)
|
66
|
+
# push free backend on queue if it wasn't used for a queued conn or is already queued (concurrency)
|
69
67
|
@backend_queue.push(backend) if @backend_list.include?(backend.name) && !@backend_queue.include?(backend)
|
70
68
|
backend.workload -= 1
|
71
69
|
end
|
@@ -78,17 +76,16 @@ module ExperellaProxy
|
|
78
76
|
# @return [Connection] a queued connection that would match the BackendServer
|
79
77
|
# @return [Boolean] true if backend was added to list
|
80
78
|
def add_backend(backend)
|
81
|
-
|
82
79
|
@backend_list[backend.name] = backend
|
83
80
|
|
84
|
-
#check if any queued connections match new available backend
|
81
|
+
# check if any queued connections match new available backend
|
85
82
|
conn = match_connections(backend)
|
86
83
|
if conn
|
87
|
-
#return matching connection
|
88
|
-
#you should try to connect the new backend to this connection
|
84
|
+
# return matching connection
|
85
|
+
# you should try to connect the new backend to this connection
|
89
86
|
return conn
|
90
87
|
else
|
91
|
-
#queue new backend
|
88
|
+
# queue new backend
|
92
89
|
@backend_queue.push(backend)
|
93
90
|
end
|
94
91
|
true
|
@@ -99,7 +96,6 @@ module ExperellaProxy
|
|
99
96
|
# @param backend [BackendServer] the BackendServer to be removed
|
100
97
|
# @return [Boolean] true if a backend was removed, else returns false
|
101
98
|
def remove_backend(backend)
|
102
|
-
|
103
99
|
ret = @backend_list.delete(backend.name)
|
104
100
|
@backend_queue.delete(backend)
|
105
101
|
|
@@ -138,7 +134,7 @@ module ExperellaProxy
|
|
138
134
|
@connection_queue.size
|
139
135
|
end
|
140
136
|
|
141
|
-
|
137
|
+
private
|
142
138
|
|
143
139
|
# Matches request to all known backends
|
144
140
|
#
|
@@ -162,6 +158,5 @@ module ExperellaProxy
|
|
162
158
|
end
|
163
159
|
nil
|
164
160
|
end
|
165
|
-
|
166
161
|
end
|
167
|
-
end
|
162
|
+
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
module ExperellaProxy
|
2
|
-
|
3
2
|
# defined hop by hop header fields
|
4
|
-
HOP_HEADERS =
|
3
|
+
HOP_HEADERS = %w(Connection Keep-Alive Proxy-Authorization TE Trailer Transfer-Encoding Upgrade)
|
5
4
|
|
6
5
|
# Provides getters for global variables
|
7
6
|
#
|
8
7
|
# All methods are private. The module needs to be included in every Class which needs it.
|
9
8
|
module Globals
|
10
|
-
|
11
|
-
private
|
9
|
+
private
|
12
10
|
|
13
11
|
# @!visibility public
|
14
12
|
|
@@ -25,8 +23,8 @@ module ExperellaProxy
|
|
25
23
|
# @param [Hash] details contains details of the event
|
26
24
|
# see ExperellaProxy::Configuration#on_event
|
27
25
|
|
28
|
-
def event(name,details={})
|
29
|
-
config.on_event.call(name,details)
|
26
|
+
def event(name, details={})
|
27
|
+
config.on_event.call(name, details)
|
30
28
|
end
|
31
29
|
|
32
30
|
# Get the global connection manager
|
@@ -40,4 +38,4 @@ module ExperellaProxy
|
|
40
38
|
config.logger
|
41
39
|
end
|
42
40
|
end
|
43
|
-
end
|
41
|
+
end
|
@@ -1,45 +1,44 @@
|
|
1
1
|
module ExperellaProxy
|
2
|
-
|
3
2
|
# Every standard HTTP code mapped to the appropriate message.
|
4
3
|
#
|
5
4
|
# @author Mongrel.
|
6
5
|
HTTP_STATUS_CODES = {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
6
|
+
100 => 'Continue',
|
7
|
+
101 => 'Switching Protocols',
|
8
|
+
200 => 'OK',
|
9
|
+
201 => 'Created',
|
10
|
+
202 => 'Accepted',
|
11
|
+
203 => 'Non-Authoritative Information',
|
12
|
+
204 => 'No Content',
|
13
|
+
205 => 'Reset Content',
|
14
|
+
206 => 'Partial Content',
|
15
|
+
300 => 'Multiple Choices',
|
16
|
+
301 => 'Moved Permanently',
|
17
|
+
302 => 'Moved Temporarily',
|
18
|
+
303 => 'See Other',
|
19
|
+
304 => 'Not Modified',
|
20
|
+
305 => 'Use Proxy',
|
21
|
+
400 => 'Bad Request',
|
22
|
+
401 => 'Unauthorized',
|
23
|
+
402 => 'Payment Required',
|
24
|
+
403 => 'Forbidden',
|
25
|
+
404 => 'Not Found',
|
26
|
+
405 => 'Method Not Allowed',
|
27
|
+
406 => 'Not Acceptable',
|
28
|
+
407 => 'Proxy Authentication Required',
|
29
|
+
408 => 'Request Time-out',
|
30
|
+
409 => 'Conflict',
|
31
|
+
410 => 'Gone',
|
32
|
+
411 => 'Length Required',
|
33
|
+
412 => 'Precondition Failed',
|
34
|
+
413 => 'Request Entity Too Large',
|
35
|
+
414 => 'Request-URI Too Large',
|
36
|
+
415 => 'Unsupported Media Type',
|
37
|
+
500 => 'Internal Server Error',
|
38
|
+
501 => 'Not Implemented',
|
39
|
+
502 => 'Bad Gateway',
|
40
|
+
503 => 'Service Unavailable',
|
41
|
+
504 => 'Gateway Time-out',
|
42
|
+
505 => 'HTTP Version not supported'
|
44
43
|
}
|
45
44
|
end
|
@@ -11,8 +11,7 @@ module ExperellaProxy
|
|
11
11
|
# @param options [Hash] option Hash passed to the {Connection}
|
12
12
|
# @param blk [Block] Block evaluated in each new {Connection}
|
13
13
|
def self.start(options, &blk)
|
14
|
-
|
15
|
-
#initalize backend servers from config
|
14
|
+
# initalize backend servers from config
|
16
15
|
config.backends.each do |backend|
|
17
16
|
connection_manager.add_backend(BackendServer.new(backend[:host], backend[:port], backend))
|
18
17
|
logger.info "Initializing backend #{backend[:name]} at #{backend[:host]}:#{backend[:port]} with concurrency\
|
@@ -21,11 +20,11 @@ module ExperellaProxy
|
|
21
20
|
logger.info "Backend mangles: #{backend[:mangle].inspect}"
|
22
21
|
end
|
23
22
|
|
24
|
-
#start eventmachine
|
23
|
+
# start eventmachine
|
25
24
|
EM.epoll
|
26
25
|
EM.run do
|
27
|
-
trap("TERM")
|
28
|
-
trap("INT")
|
26
|
+
trap("TERM"){ stop }
|
27
|
+
trap("INT"){ stop }
|
29
28
|
|
30
29
|
if config.proxy.empty?
|
31
30
|
logger.fatal "No proxy host:port address configured. Stopping experella-proxy."
|
@@ -37,10 +36,10 @@ module ExperellaProxy
|
|
37
36
|
unless proxy[:options].nil?
|
38
37
|
opts = options.merge(proxy[:options])
|
39
38
|
end
|
40
|
-
logger.info "Launching experella-proxy at #{proxy[:host]}:#{proxy[:port]} with #{config.timeout}s timeout..."
|
39
|
+
logger.info "Launching experella-proxy (#{ExperellaProxy::VERSION}) at #{proxy[:host]}:#{proxy[:port]} with #{config.timeout}s timeout..."
|
41
40
|
logger.info "with options: #{opts.inspect}"
|
42
|
-
EventMachine
|
43
|
-
|
41
|
+
EventMachine.start_server(proxy[:host], proxy[:port],
|
42
|
+
Connection, opts) do |conn|
|
44
43
|
conn.instance_eval(&blk)
|
45
44
|
end
|
46
45
|
end
|
@@ -53,7 +52,7 @@ module ExperellaProxy
|
|
53
52
|
#
|
54
53
|
def self.stop
|
55
54
|
if EM.reactor_running?
|
56
|
-
EventMachine
|
55
|
+
EventMachine.stop_event_loop
|
57
56
|
end
|
58
57
|
end
|
59
58
|
end
|
@@ -5,7 +5,6 @@ module ExperellaProxy
|
|
5
5
|
# Every Request belongs to a client {Connection}
|
6
6
|
#
|
7
7
|
class Request
|
8
|
-
|
9
8
|
include ExperellaProxy::Globals
|
10
9
|
|
11
10
|
attr_accessor :keep_alive, :chunked
|
@@ -18,9 +17,9 @@ module ExperellaProxy
|
|
18
17
|
@conn = conn
|
19
18
|
@header = {}
|
20
19
|
@chunked = false # if true the parsed body will be chunked
|
21
|
-
@uri = {} #contains port, path and query information for faster backend selection
|
20
|
+
@uri = {} # contains port, path and query information for faster backend selection
|
22
21
|
@keep_alive = true
|
23
|
-
@send_buffer =
|
22
|
+
@send_buffer = ''
|
24
23
|
@response = Response.new(self)
|
25
24
|
end
|
26
25
|
|
@@ -64,21 +63,21 @@ module ExperellaProxy
|
|
64
63
|
# First Header after Startline will always be "Host: ", after that order is determined by {#header}.each
|
65
64
|
#
|
66
65
|
def reconstruct_header
|
67
|
-
#split send_buffer into header and body part
|
66
|
+
# split send_buffer into header and body part
|
68
67
|
buf = @send_buffer.split(/\r\n\r\n/, 2) unless flushed?
|
69
68
|
@send_buffer = ""
|
70
|
-
#start line
|
69
|
+
# start line
|
71
70
|
@send_buffer << @header[:http_method] + ' '
|
72
71
|
@send_buffer << @header[:request_url] + ' '
|
73
72
|
@send_buffer << "HTTP/1.1\r\n"
|
74
|
-
@send_buffer << "Host: " + @header[:Host] + "\r\n" #add Host first for better header readability
|
75
|
-
#header fields
|
73
|
+
@send_buffer << "Host: " + @header[:Host] + "\r\n" # add Host first for better header readability
|
74
|
+
# header fields
|
76
75
|
@header.each do |key, value|
|
77
|
-
unless key == :http_method || key == :request_url || key == :http_version || key == :Host #exclude startline parameters
|
76
|
+
unless key == :http_method || key == :request_url || key == :http_version || key == :Host # exclude startline parameters
|
78
77
|
@send_buffer << key.to_s + ": "
|
79
78
|
if value.is_a?(Array)
|
80
79
|
@send_buffer << value.shift
|
81
|
-
until value.empty?
|
80
|
+
until value.empty?
|
82
81
|
@send_buffer << "," + value.shift
|
83
82
|
end
|
84
83
|
else
|
@@ -88,8 +87,8 @@ module ExperellaProxy
|
|
88
87
|
end
|
89
88
|
end
|
90
89
|
@send_buffer << "\r\n"
|
91
|
-
#reconstruction complete
|
92
|
-
@send_buffer << buf[1] unless buf.nil? #append buffered body
|
90
|
+
# reconstruction complete
|
91
|
+
@send_buffer << buf[1] unless buf.nil? # append buffered body
|
93
92
|
event(:request_reconstruct_header, :data => @send_buffer)
|
94
93
|
end
|
95
94
|
|
@@ -99,8 +98,8 @@ module ExperellaProxy
|
|
99
98
|
#
|
100
99
|
# @param hsh [Hash] hash with HTTP header Key:Value pairs
|
101
100
|
def update_header(hsh)
|
102
|
-
hsh = hsh.
|
101
|
+
hsh = hsh.reduce({}){ |memo, (k, v)| memo[k.to_sym] = v; memo }
|
103
102
|
@header.update(hsh)
|
104
103
|
end
|
105
104
|
end
|
106
|
-
end
|
105
|
+
end
|
@@ -5,7 +5,6 @@ module ExperellaProxy
|
|
5
5
|
# Every Response belongs to a request {Request}
|
6
6
|
#
|
7
7
|
class Response
|
8
|
-
|
9
8
|
include ExperellaProxy::Globals
|
10
9
|
|
11
10
|
attr_reader :header
|
@@ -18,12 +17,12 @@ module ExperellaProxy
|
|
18
17
|
@conn = request.conn
|
19
18
|
@header = {}
|
20
19
|
@status_code = 500
|
21
|
-
@no_length = false #set true if no content-length or transfer-encoding given
|
22
|
-
@keep_parsing = true #used for special no length case
|
20
|
+
@no_length = false # set true if no content-length or transfer-encoding given
|
21
|
+
@keep_parsing = true # used for special no length case
|
23
22
|
@chunked = false # if true the parsed body will be chunked
|
24
23
|
@buffer = false # default is false, so incoming data will be streamed,
|
25
24
|
# used for http1.0 clients and transfer-encoding chunked backend responses
|
26
|
-
@send_buffer =
|
25
|
+
@send_buffer = ''
|
27
26
|
@response_parser = Http::Parser.new
|
28
27
|
init_http_parser
|
29
28
|
end
|
@@ -36,33 +35,29 @@ module ExperellaProxy
|
|
36
35
|
#
|
37
36
|
# @param str [String] data as string
|
38
37
|
def <<(str)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
else
|
46
|
-
@conn.send_data str
|
47
|
-
end
|
48
|
-
|
49
|
-
rescue Http::Parser::Error
|
50
|
-
event(:response_add, :signature => @conn.signature, :error => true,
|
51
|
-
:description => "parser error caused by invalid response data")
|
52
|
-
# on error unbind response_parser object, so additional data doesn't get parsed anymore
|
53
|
-
#
|
54
|
-
# assigning a string to the parser variable, will cause incoming data to get buffered
|
55
|
-
# imho this is a better solution than adding a condition for this rare error case
|
56
|
-
@response_parser = ""
|
57
|
-
@conn.close
|
38
|
+
if @keep_parsing
|
39
|
+
offset = (@response_parser << str)
|
40
|
+
# edge case for message without content-length and transfer encoding
|
41
|
+
@conn.send_data str[offset..-1] unless @keep_parsing
|
42
|
+
else
|
43
|
+
@conn.send_data str
|
58
44
|
end
|
45
|
+
rescue Http::Parser::Error
|
46
|
+
event(:response_add, :signature => @conn.signature, :error => true,
|
47
|
+
:description => "parser error caused by invalid response data")
|
48
|
+
# on error unbind response_parser object, so additional data doesn't get parsed anymore
|
49
|
+
#
|
50
|
+
# assigning a string to the parser variable, will cause incoming data to get buffered
|
51
|
+
# imho this is a better solution than adding a condition for this rare error case
|
52
|
+
@response_parser = ""
|
53
|
+
@conn.close
|
59
54
|
end
|
60
55
|
|
61
56
|
# Returns the data in send_buffer and empties the send_buffer
|
62
57
|
#
|
63
58
|
# @return [String] data to send
|
64
59
|
def flush
|
65
|
-
event(:response_flush
|
60
|
+
event(:response_flush, :data => @send_buffer)
|
66
61
|
@send_buffer.slice!(0, @send_buffer.length)
|
67
62
|
end
|
68
63
|
|
@@ -81,16 +76,16 @@ module ExperellaProxy
|
|
81
76
|
#
|
82
77
|
def reconstruct_header
|
83
78
|
@send_buffer = ""
|
84
|
-
#start line
|
79
|
+
# start line
|
85
80
|
@send_buffer << "HTTP/1.1 "
|
86
81
|
@send_buffer << @status_code.to_s + ' '
|
87
82
|
@send_buffer << HTTP_STATUS_CODES[@status_code] + "\r\n"
|
88
|
-
#header fields
|
83
|
+
# header fields
|
89
84
|
@header.each do |key, value|
|
90
85
|
@send_buffer << key.to_s + ": "
|
91
86
|
if value.is_a?(Array)
|
92
87
|
@send_buffer << value.shift
|
93
|
-
until value.empty?
|
88
|
+
until value.empty?
|
94
89
|
@send_buffer << "," + value.shift
|
95
90
|
end
|
96
91
|
else
|
@@ -99,7 +94,7 @@ module ExperellaProxy
|
|
99
94
|
@send_buffer << "\r\n"
|
100
95
|
end
|
101
96
|
@send_buffer << "\r\n"
|
102
|
-
#reconstruction complete
|
97
|
+
# reconstruction complete
|
103
98
|
event(:response_reconstruct_header, :data => @send_buffer)
|
104
99
|
end
|
105
100
|
|
@@ -109,15 +104,15 @@ module ExperellaProxy
|
|
109
104
|
#
|
110
105
|
# @param hsh [Hash] hash with HTTP header Key:Value pairs
|
111
106
|
def update_header(hsh)
|
112
|
-
hsh = hsh.
|
107
|
+
hsh = hsh.reduce({}){ |memo, (k, v)| memo[k.to_sym] = v; memo }
|
113
108
|
@header.update(hsh)
|
114
109
|
end
|
115
110
|
|
116
|
-
|
111
|
+
private
|
117
112
|
|
118
113
|
# initializes the response http parser
|
119
114
|
def init_http_parser
|
120
|
-
#called when response headers are completely parsed (first \r\n\r\n triggers this)
|
115
|
+
# called when response headers are completely parsed (first \r\n\r\n triggers this)
|
121
116
|
@response_parser.on_headers_complete = proc do |h|
|
122
117
|
|
123
118
|
@status_code = @response_parser.status_code
|
@@ -142,7 +137,7 @@ module ExperellaProxy
|
|
142
137
|
@no_length = true
|
143
138
|
@header[:Connection] = "close"
|
144
139
|
end
|
145
|
-
#chunked encoded
|
140
|
+
# chunked encoded
|
146
141
|
else
|
147
142
|
# buffer response data if client uses http 1.0 until message complete
|
148
143
|
if @request.header[:http_version][0] == 1 && @request.header[:http_version][1] == 0
|
@@ -168,7 +163,6 @@ module ExperellaProxy
|
|
168
163
|
h.delete(s)
|
169
164
|
end
|
170
165
|
|
171
|
-
|
172
166
|
via = h.delete("Via")
|
173
167
|
if via.nil?
|
174
168
|
via = "1.1 experella"
|
@@ -219,4 +213,4 @@ module ExperellaProxy
|
|
219
213
|
end
|
220
214
|
end
|
221
215
|
end
|
222
|
-
end
|
216
|
+
end
|
@@ -7,7 +7,7 @@ module ExperellaProxy
|
|
7
7
|
#
|
8
8
|
# @param options [Hash] options Hash passed to the proxy
|
9
9
|
def initialize(options)
|
10
|
-
@options=options
|
10
|
+
@options = options
|
11
11
|
end
|
12
12
|
|
13
13
|
attr_reader :options
|
@@ -25,7 +25,6 @@ module ExperellaProxy
|
|
25
25
|
# {Connection#unbind} in on_unbind
|
26
26
|
#
|
27
27
|
def run
|
28
|
-
|
29
28
|
Proxy.start(options = {}) do |conn|
|
30
29
|
event(:server_new_connection, :msec => msec, :signature => signature)
|
31
30
|
|
@@ -58,10 +57,6 @@ module ExperellaProxy
|
|
58
57
|
|
59
58
|
end
|
60
59
|
end
|
61
|
-
|
62
60
|
end
|
63
|
-
|
64
61
|
end
|
65
|
-
|
66
62
|
end
|
67
|
-
|
@@ -1,5 +1,9 @@
|
|
1
1
|
module ExperellaProxy
|
2
2
|
# ExperellaProxy Gemversion
|
3
|
+
# 0.0.11
|
4
|
+
# * output version on start
|
5
|
+
# * rubocup config file
|
6
|
+
# * applied rubyocop config file
|
3
7
|
# 0.0.10
|
4
8
|
# * no logging any more just firing events
|
5
9
|
# 0.0.9
|
@@ -23,5 +27,5 @@ module ExperellaProxy
|
|
23
27
|
# * added self-signed SSL certificate for TLS/HTTPS
|
24
28
|
# * added config template init functionality
|
25
29
|
#
|
26
|
-
VERSION = "0.0.
|
30
|
+
VERSION = "0.0.11"
|
27
31
|
end
|
data/lib/experella-proxy.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'eventmachine'
|
3
3
|
require 'http_parser.rb'
|
4
|
+
require 'experella-proxy/version'
|
4
5
|
require 'experella-proxy/globals'
|
5
6
|
require 'experella-proxy/http_status_codes'
|
6
7
|
require 'experella-proxy/configuration'
|
@@ -35,7 +36,6 @@ require 'experella-proxy/response'
|
|
35
36
|
# @see file:README.md README
|
36
37
|
# @author Dennis-Florian Herr 2014 @Experteer GmbH
|
37
38
|
module ExperellaProxy
|
38
|
-
|
39
39
|
# Initializes ExperellaProxy's {Configuration} and {ConnectionManager}
|
40
40
|
#
|
41
41
|
# @param [Hash] options Hash passed to the configuration
|
@@ -43,11 +43,11 @@ module ExperellaProxy
|
|
43
43
|
# @return [Boolean] true if successful false if NoConfigError was raised
|
44
44
|
def self.init(options={})
|
45
45
|
begin
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
Configuration.new(options)
|
47
|
+
rescue Configuration::NoConfigError => e
|
48
|
+
puts e.message
|
49
|
+
puts e.backtrace.join("\n\t")
|
50
|
+
return false
|
51
51
|
end
|
52
52
|
@connection_manager = ConnectionManager.new
|
53
53
|
true
|
@@ -66,19 +66,18 @@ module ExperellaProxy
|
|
66
66
|
# Loses all buffered data
|
67
67
|
def self.restart
|
68
68
|
opts = @server.options
|
69
|
-
|
69
|
+
stop
|
70
70
|
Server.new(opts).run if ExperellaProxy.init(opts)
|
71
71
|
end
|
72
72
|
|
73
73
|
# Stops ExperellaProxy
|
74
74
|
#
|
75
75
|
def self.stop
|
76
|
-
|
76
|
+
Proxy.stop
|
77
77
|
end
|
78
|
-
|
79
78
|
end
|
80
79
|
|
81
|
-
#startup
|
80
|
+
# startup
|
82
81
|
ARGV << '--help' if ARGV.empty?
|
83
82
|
|
84
83
|
options = {}
|
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'eventmachine'
|
2
2
|
require 'http_parser.rb'
|
3
3
|
module EchoServer
|
4
|
-
|
5
4
|
def post_init
|
6
5
|
@parser = Http::Parser.new
|
7
|
-
@buffer =
|
6
|
+
@buffer = ''
|
8
7
|
|
9
8
|
@parser.on_headers_complete = proc do |h|
|
10
9
|
if @parser.request_path == "/chunked"
|
@@ -30,15 +29,14 @@ module EchoServer
|
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
33
|
-
def receive_data
|
32
|
+
def receive_data(data)
|
34
33
|
@buffer << data
|
35
34
|
@parser << data
|
36
35
|
end
|
37
|
-
|
38
36
|
end
|
39
37
|
|
40
38
|
EventMachine.run do
|
41
|
-
trap("QUIT")
|
39
|
+
trap("QUIT"){ EM.stop }
|
42
40
|
|
43
41
|
if ARGV.count == 2
|
44
42
|
EventMachine.start_server ARGV.first, ARGV.last.to_i, EchoServer
|
@@ -46,4 +44,4 @@ EventMachine.run do
|
|
46
44
|
raise "invalid number of params, expected [server] [port]"
|
47
45
|
end
|
48
46
|
|
49
|
-
end
|
47
|
+
end
|