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