passenger 3.0.8 → 3.0.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (42) hide show
  1. data/NEWS +9 -0
  2. data/bin/passenger-install-nginx-module +1 -1
  3. data/build/basics.rb +0 -1
  4. data/build/cxx_tests.rb +5 -0
  5. data/build/rpm.rb +1 -1
  6. data/doc/Users guide Apache.html +1 -1
  7. data/doc/Users guide Nginx.html +1 -1
  8. data/ext/apache2/Configuration.cpp +12 -0
  9. data/ext/apache2/Configuration.hpp +12 -1
  10. data/ext/apache2/Hooks.cpp +2 -0
  11. data/ext/common/AgentsStarter.cpp +4 -0
  12. data/ext/common/AgentsStarter.h +2 -0
  13. data/ext/common/AgentsStarter.hpp +4 -0
  14. data/ext/common/Constants.h +1 -1
  15. data/ext/common/Logging.h +481 -261
  16. data/ext/common/LoggingAgent/LoggingServer.h +10 -4
  17. data/ext/common/LoggingAgent/Main.cpp +7 -2
  18. data/ext/common/LoggingAgent/RemoteSender.h +25 -3
  19. data/ext/common/MessageChannel.h +18 -227
  20. data/ext/common/MessageClient.h +95 -92
  21. data/ext/common/Utils/IOUtils.cpp +114 -1
  22. data/ext/common/Utils/IOUtils.h +57 -1
  23. data/ext/common/Utils/MessageIO.h +576 -0
  24. data/ext/nginx/Configuration.c +35 -0
  25. data/ext/nginx/Configuration.h +2 -0
  26. data/ext/nginx/ContentHandler.c +17 -6
  27. data/ext/nginx/ngx_http_passenger_module.c +8 -0
  28. data/lib/phusion_passenger.rb +2 -2
  29. data/lib/phusion_passenger/analytics_logger.rb +174 -117
  30. data/lib/phusion_passenger/app_process.rb +14 -2
  31. data/test/cxx/CxxTestMain.cpp +14 -19
  32. data/test/cxx/IOUtilsTest.cpp +68 -18
  33. data/test/cxx/LoggingTest.cpp +20 -24
  34. data/test/cxx/MessageChannelTest.cpp +1 -1
  35. data/test/cxx/MessageIOTest.cpp +310 -0
  36. data/test/cxx/TestSupport.cpp +47 -0
  37. data/test/cxx/TestSupport.h +8 -0
  38. data/test/ruby/analytics_logger_spec.rb +20 -28
  39. data/test/tut/tut.h +2 -0
  40. metadata +11 -11
  41. data/build/rdoctask.rb +0 -209
  42. data/test/cxx/HttpStatusExtractorTest.cpp +0 -198
@@ -57,6 +57,11 @@ static ngx_path_init_t ngx_http_proxy_temp_path = {
57
57
  };
58
58
 
59
59
 
60
+ static int
61
+ ngx_str_equals(ngx_str_t *str, const char *value) {
62
+ return ngx_memn2cmp(str->data, (u_char *) value, str->len, strlen(value)) == 0;
63
+ }
64
+
60
65
  void *
61
66
  passenger_create_main_conf(ngx_conf_t *cf)
62
67
  {
@@ -92,6 +97,10 @@ passenger_create_main_conf(ngx_conf_t *cf)
92
97
  conf->union_station_gateway_port = (ngx_uint_t) NGX_CONF_UNSET;
93
98
  conf->union_station_gateway_cert.data = NULL;
94
99
  conf->union_station_gateway_cert.len = 0;
100
+ conf->union_station_proxy_address.data = NULL;
101
+ conf->union_station_proxy_address.len = 0;
102
+ conf->union_station_proxy_type.data = NULL;
103
+ conf->union_station_proxy_type.len = 0;
95
104
 
96
105
  conf->prestart_uris = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
97
106
  if (conf->prestart_uris == NULL) {
@@ -234,6 +243,18 @@ passenger_init_main_conf(ngx_conf_t *cf, void *conf_pointer)
234
243
  conf->union_station_gateway_cert.data = (u_char *) "";
235
244
  }
236
245
 
246
+ if (conf->union_station_proxy_address.len == 0) {
247
+ conf->union_station_proxy_address.data = (u_char *) "";
248
+ }
249
+
250
+ if (conf->union_station_proxy_type.len == 0) {
251
+ conf->union_station_proxy_type.data = (u_char *) "";
252
+
253
+ } else if (!ngx_str_equals(&conf->union_station_proxy_type, "http")
254
+ && !ngx_str_equals(&conf->union_station_proxy_type, "socks5")) {
255
+ return "union_station_proxy_type may only be 'http' or 'socks5'.";
256
+ }
257
+
237
258
  return NGX_CONF_OK;
238
259
  }
239
260
 
@@ -1145,6 +1166,20 @@ const ngx_command_t passenger_commands[] = {
1145
1166
  offsetof(passenger_main_conf_t, union_station_gateway_cert),
1146
1167
  NULL },
1147
1168
 
1169
+ { ngx_string("union_station_proxy_address"),
1170
+ NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1171
+ ngx_conf_set_str_slot,
1172
+ NGX_HTTP_MAIN_CONF_OFFSET,
1173
+ offsetof(passenger_main_conf_t, union_station_proxy_address),
1174
+ NULL },
1175
+
1176
+ { ngx_string("union_station_proxy_type"),
1177
+ NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
1178
+ ngx_conf_set_str_slot,
1179
+ NGX_HTTP_MAIN_CONF_OFFSET,
1180
+ offsetof(passenger_main_conf_t, union_station_proxy_type),
1181
+ NULL },
1182
+
1148
1183
  { ngx_string("union_station_filter"),
1149
1184
  NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
1150
1185
  union_station_filter,
@@ -80,6 +80,8 @@ typedef struct {
80
80
  ngx_str_t union_station_gateway_address;
81
81
  ngx_uint_t union_station_gateway_port;
82
82
  ngx_str_t union_station_gateway_cert;
83
+ ngx_str_t union_station_proxy_address;
84
+ ngx_str_t union_station_proxy_type;
83
85
  ngx_array_t *prestart_uris;
84
86
  } passenger_main_conf_t;
85
87
 
@@ -336,6 +336,7 @@ create_request(ngx_http_request_t *r)
336
336
  ngx_table_elt_t *header;
337
337
  ngx_http_script_code_pt code;
338
338
  ngx_http_script_engine_t e, le;
339
+ ngx_http_core_srv_conf_t *cscf;
339
340
  passenger_loc_conf_t *slcf;
340
341
  passenger_main_conf_t *main_conf;
341
342
  passenger_context_t *context;
@@ -344,6 +345,7 @@ create_request(ngx_http_request_t *r)
344
345
  ngx_http_ssl_srv_conf_t *ssl_conf;
345
346
  #endif
346
347
 
348
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
347
349
  slcf = ngx_http_get_module_loc_conf(r, ngx_http_passenger_module);
348
350
  main_conf = &passenger_main_conf;
349
351
  context = ngx_http_get_module_ctx(r, ngx_http_passenger_module);
@@ -415,11 +417,15 @@ create_request(ngx_http_request_t *r)
415
417
  }
416
418
 
417
419
  /* SERVER_NAME; must be equal to HTTP_HOST without the port part */
418
- tmp = memchr(r->headers_in.host->value.data, ':', r->headers_in.host->value.len);
419
- if (tmp == NULL) {
420
- server_name_len = r->headers_in.host->value.len;
420
+ if (r->headers_in.host != NULL) {
421
+ tmp = memchr(r->headers_in.host->value.data, ':', r->headers_in.host->value.len);
422
+ if (tmp == NULL) {
423
+ server_name_len = r->headers_in.host->value.len;
424
+ } else {
425
+ server_name_len = (int) ((const u_char *) tmp - r->headers_in.host->value.data);
426
+ }
421
427
  } else {
422
- server_name_len = (int) ((const u_char *) tmp - r->headers_in.host->value.data);
428
+ server_name_len = cscf->server_name.len;
423
429
  }
424
430
  len += sizeof("SERVER_NAME") + server_name_len + 1;
425
431
 
@@ -650,8 +656,13 @@ create_request(ngx_http_request_t *r)
650
656
 
651
657
  /* SERVER_NAME */
652
658
  b->last = ngx_copy(b->last, "SERVER_NAME", sizeof("SERVER_NAME"));
653
- b->last = ngx_copy(b->last, r->headers_in.host->value.data,
654
- server_name_len);
659
+ if (r->headers_in.host != NULL) {
660
+ b->last = ngx_copy(b->last, r->headers_in.host->value.data,
661
+ server_name_len);
662
+ } else {
663
+ b->last = ngx_copy(b->last, cscf->server_name.data,
664
+ server_name_len);
665
+ }
655
666
  b->last = ngx_copy(b->last, "", 1);
656
667
 
657
668
  /* Various other HTTP headers. */
@@ -239,6 +239,8 @@ start_helper_server(ngx_cycle_t *cycle) {
239
239
  char *analytics_log_permissions;
240
240
  char *union_station_gateway_address;
241
241
  char *union_station_gateway_cert;
242
+ char *union_station_proxy_address;
243
+ char *union_station_proxy_type;
242
244
  char *error_message = NULL;
243
245
 
244
246
  core_conf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
@@ -256,6 +258,8 @@ start_helper_server(ngx_cycle_t *cycle) {
256
258
  analytics_log_permissions = ngx_str_null_terminate(&passenger_main_conf.analytics_log_permissions);
257
259
  union_station_gateway_address = ngx_str_null_terminate(&passenger_main_conf.union_station_gateway_address);
258
260
  union_station_gateway_cert = ngx_str_null_terminate(&passenger_main_conf.union_station_gateway_cert);
261
+ union_station_proxy_address = ngx_str_null_terminate(&passenger_main_conf.union_station_proxy_address);
262
+ union_station_proxy_type = ngx_str_null_terminate(&passenger_main_conf.union_station_proxy_type);
259
263
 
260
264
  prestart_uris = (ngx_str_t *) passenger_main_conf.prestart_uris->elts;
261
265
  prestart_uris_ary = calloc(sizeof(char *), passenger_main_conf.prestart_uris->nelts);
@@ -284,6 +288,8 @@ start_helper_server(ngx_cycle_t *cycle) {
284
288
  union_station_gateway_address,
285
289
  passenger_main_conf.union_station_gateway_port,
286
290
  union_station_gateway_cert,
291
+ union_station_proxy_address,
292
+ union_station_proxy_type,
287
293
  (const char **) prestart_uris_ary, passenger_main_conf.prestart_uris->nelts,
288
294
  starting_helper_server_after_fork,
289
295
  cycle,
@@ -355,6 +361,8 @@ cleanup:
355
361
  free(analytics_log_permissions);
356
362
  free(union_station_gateway_address);
357
363
  free(union_station_gateway_cert);
364
+ free(union_station_proxy_address);
365
+ free(union_station_proxy_type);
358
366
  free(error_message);
359
367
  if (prestart_uris_ary != NULL) {
360
368
  for (i = 0; i < passenger_main_conf.prestart_uris->nelts; i++) {
@@ -25,9 +25,9 @@ module PhusionPassenger
25
25
  ###### Version numbers ######
26
26
 
27
27
  # Phusion Passenger version number. Don't forget to edit ext/common/Constants.h too.
28
- VERSION_STRING = '3.0.8'
28
+ VERSION_STRING = '3.0.9'
29
29
 
30
- PREFERRED_NGINX_VERSION = '1.0.5'
30
+ PREFERRED_NGINX_VERSION = '1.0.6'
31
31
  PREFERRED_PCRE_VERSION = '8.12'
32
32
  STANDALONE_INTERFACE_VERSION = 1
33
33
 
@@ -24,7 +24,7 @@
24
24
  require 'thread'
25
25
  require 'phusion_passenger/utils'
26
26
  require 'phusion_passenger/debug_logging'
27
- require 'phusion_passenger/message_client'
27
+ require 'phusion_passenger/message_channel'
28
28
 
29
29
  module PhusionPassenger
30
30
 
@@ -38,24 +38,33 @@ class AnalyticsLogger
38
38
  class Log
39
39
  attr_reader :txn_id
40
40
 
41
- def initialize(shared_data = nil, txn_id = nil)
42
- if shared_data
43
- @shared_data = shared_data
41
+ def initialize(connection = nil, txn_id = nil)
42
+ if connection
43
+ @connection = connection
44
44
  @txn_id = txn_id
45
- shared_data.ref
45
+ connection.ref
46
46
  end
47
47
  end
48
48
 
49
49
  def null?
50
- return !@shared_data
50
+ return !@connection
51
51
  end
52
52
 
53
53
  def message(text)
54
- @shared_data.synchronize do
55
- @shared_data.client.write("log", @txn_id,
56
- AnalyticsLogger.timestamp_string)
57
- @shared_data.client.write_scalar(text)
58
- end if @shared_data
54
+ @connection.synchronize do
55
+ return if !@connection.connected?
56
+ begin
57
+ @connection.channel.write("log", @txn_id,
58
+ AnalyticsLogger.timestamp_string)
59
+ @connection.channel.write_scalar(text)
60
+ rescue SystemCallError, IOError => e
61
+ @connection.disconnect
62
+ DebugLogging.warn("Error communicating with the logging agent: #{e.message}")
63
+ rescue Exception => e
64
+ @connection.disconnect
65
+ raise e
66
+ end
67
+ end if @connection
59
68
  end
60
69
 
61
70
  def begin_measure(name, extra_info = nil)
@@ -107,30 +116,39 @@ class AnalyticsLogger
107
116
  end
108
117
 
109
118
  def close(flush_to_disk = false)
110
- @shared_data.synchronize do
111
- # We need an ACK here. See abstract_request_handler.rb finalize_request.
112
- @shared_data.client.write("closeTransaction", @txn_id,
113
- AnalyticsLogger.timestamp_string, true)
114
- result = @shared_data.client.read
115
- if result != ["ok"]
116
- raise "Expected logging server to respond with 'ok', but got #{result.inspect} instead"
117
- end
118
- if flush_to_disk
119
- @shared_data.client.write("flush")
120
- result = @shared_data.client.read
119
+ @connection.synchronize do
120
+ begin
121
+ # We need an ACK here. See abstract_request_handler.rb finalize_request.
122
+ @connection.channel.write("closeTransaction", @txn_id,
123
+ AnalyticsLogger.timestamp_string, true)
124
+ result = @connection.channel.read
121
125
  if result != ["ok"]
122
- raise "Invalid logging server response #{result.inspect} to the 'flush' command"
126
+ raise "Expected logging agent to respond with 'ok', but got #{result.inspect} instead"
127
+ end
128
+ if flush_to_disk
129
+ @connection.channel.write("flush")
130
+ result = @connection.channel.read
131
+ if result != ["ok"]
132
+ raise "Invalid logging agent response #{result.inspect} to the 'flush' command"
133
+ end
123
134
  end
135
+ rescue SystemCallError, IOError => e
136
+ @connection.disconnect
137
+ DebugLogging.warn("Error communicating with the logging agent: #{e.message}")
138
+ rescue Exception => e
139
+ @connection.disconnect
140
+ raise e
141
+ ensure
142
+ @connection.unref
143
+ @connection = nil
124
144
  end
125
- @shared_data.unref
126
- @shared_data = nil
127
- end if @shared_data
145
+ end if @connection
128
146
  end
129
147
 
130
148
  def closed?
131
- if @shared_data
132
- @shared_data.synchronize do
133
- return !@shared_data.client.connected?
149
+ if @connection
150
+ @connection.synchronize do
151
+ return !@connection.connected?
134
152
  end
135
153
  else
136
154
  return nil
@@ -170,10 +188,10 @@ class AnalyticsLogger
170
188
  @random_dev = File.open("/dev/urandom")
171
189
 
172
190
  # This mutex protects the following instance variables, but
173
- # not the contents of @shared_data.
191
+ # not the contents of @connection.
174
192
  @mutex = Mutex.new
175
193
 
176
- @shared_data = SharedData.new
194
+ @connection = Connection.new(nil)
177
195
  if @server_address && local_socket_address?(@server_address)
178
196
  @max_connect_tries = 10
179
197
  else
@@ -185,20 +203,20 @@ class AnalyticsLogger
185
203
 
186
204
  def clear_connection
187
205
  @mutex.synchronize do
188
- @shared_data.synchronize do
206
+ @connection.synchronize do
189
207
  @random_dev = File.open("/dev/urandom") if @random_dev.closed?
190
- @shared_data.unref
191
- @shared_data = SharedData.new
208
+ @connection.unref
209
+ @connection = Connection.new(nil)
192
210
  end
193
211
  end
194
212
  end
195
213
 
196
214
  def close
197
215
  @mutex.synchronize do
198
- @shared_data.synchronize do
216
+ @connection.synchronize do
199
217
  @random_dev.close
200
- @shared_data.unref
201
- @shared_data = nil
218
+ @connection.unref
219
+ @connection = nil
202
220
  end
203
221
  end
204
222
  end
@@ -212,44 +230,53 @@ class AnalyticsLogger
212
230
 
213
231
  txn_id = (AnalyticsLogger.current_time.to_i / 60).to_s(36)
214
232
  txn_id << "-#{random_token(11)}"
233
+
215
234
  Lock.new(@mutex).synchronize do |lock|
216
- Lock.new(@shared_data.mutex).synchronize do |shared_data_lock|
217
- try_count = 0
218
- if current_time >= @next_reconnect_time
219
- while try_count < @max_connect_tries
235
+ if current_time < @next_reconnect_time
236
+ return Log.new
237
+ end
238
+
239
+ Lock.new(@connection.mutex).synchronize do |connection_lock|
240
+ if !@connection.connected?
220
241
  begin
221
- connect if !connected?
222
- @shared_data.client.write("openTransaction",
223
- txn_id, group_name, "", category,
224
- AnalyticsLogger.timestamp_string,
225
- union_station_key,
226
- true,
227
- true)
228
- result = @shared_data.client.read
229
- if result != ["ok"]
230
- raise "Expected logging server to respond with 'ok', but got #{result.inspect} instead"
231
- end
232
- return Log.new(@shared_data, txn_id)
233
- rescue Errno::ENOENT, *NETWORK_ERRORS
234
- try_count += 1
235
- disconnect(true)
236
- shared_data_lock.reset(@shared_data.mutex, false)
237
- lock.unlock
238
- sleep RETRY_SLEEP if try_count < @max_connect_tries
239
- lock.lock
240
- shared_data_lock.lock
242
+ connect
243
+ connection_lock.reset(@connection.mutex)
244
+ rescue SystemCallError, IOError
245
+ @connection.disconnect
246
+ DebugLogging.warn("Cannot connect to the logging agent at #{@server_address}; " +
247
+ "retrying in #{@reconnect_timeout} second(s).")
248
+ @next_reconnect_time = current_time + @reconnect_timeout
249
+ return Log.new
241
250
  rescue Exception => e
242
- disconnect
251
+ @connection.disconnect
243
252
  raise e
244
253
  end
245
254
  end
246
- # Failed to connect.
247
- DebugLogging.warn("Cannot connect to the logging agent (#{@server_address}); " +
248
- "retrying in #{@reconnect_timeout} second(s).")
249
- @next_reconnect_time = current_time + @reconnect_timeout
255
+
256
+ begin
257
+ @connection.channel.write("openTransaction",
258
+ txn_id, group_name, "", category,
259
+ AnalyticsLogger.timestamp_string,
260
+ union_station_key,
261
+ true,
262
+ true)
263
+ result = @connection.channel.read
264
+ if result != ["ok"]
265
+ raise "Expected logging server to respond with 'ok', but got #{result.inspect} instead"
266
+ end
267
+ return Log.new(@connection, txn_id)
268
+ rescue SystemCallError, IOError
269
+ @connection.disconnect
270
+ DebugLogging.warn("The logging agent at #{@server_address}" <<
271
+ " closed the connection; will reconnect in " <<
272
+ "#{@reconnect_timeout} second(s).")
273
+ @next_reconnect_time = current_time + @reconnect_timeout
274
+ return Log.new
275
+ rescue Exception => e
276
+ @connection.disconnect
277
+ raise e
278
+ end
250
279
  end
251
- return Log.new
252
- end
253
280
  end
254
281
  end
255
282
 
@@ -261,38 +288,46 @@ class AnalyticsLogger
261
288
  end
262
289
 
263
290
  Lock.new(@mutex).synchronize do |lock|
264
- Lock.new(@shared_data.mutex).synchronize do |shared_data_lock|
265
- try_count = 0
266
- if current_time >= @next_reconnect_time
267
- while try_count < @max_connect_tries
291
+ if current_time < @next_reconnect_time
292
+ return Log.new
293
+ end
294
+
295
+ Lock.new(@connection.mutex).synchronize do |connection_lock|
296
+ if !@connection.connected?
268
297
  begin
269
- connect if !connected?
270
- @shared_data.client.write("openTransaction",
271
- txn_id, group_name, "", category,
272
- AnalyticsLogger.timestamp_string,
273
- union_station_key,
274
- true)
275
- return Log.new(@shared_data, txn_id)
276
- rescue Errno::ENOENT, *NETWORK_ERRORS
277
- try_count += 1
278
- disconnect(true)
279
- shared_data_lock.reset(@shared_data.mutex, false)
280
- lock.unlock
281
- sleep RETRY_SLEEP if try_count < @max_connect_tries
282
- lock.lock
283
- shared_data_lock.lock
298
+ connect
299
+ connection_lock.reset(@connection.mutex)
300
+ rescue SystemCallError, IOError
301
+ @connection.disconnect
302
+ DebugLogging.warn("Cannot connect to the logging agent at #{@server_address}; " +
303
+ "retrying in #{@reconnect_timeout} second(s).")
304
+ @next_reconnect_time = current_time + @reconnect_timeout
305
+ return Log.new
284
306
  rescue Exception => e
285
- disconnect
307
+ @connection.disconnect
286
308
  raise e
287
309
  end
288
310
  end
289
- # Failed to connect.
290
- DebugLogging.warn("Cannot connect to the logging agent (#{@server_address}); " +
291
- "retrying in #{@reconnect_timeout} second(s).")
292
- @next_reconnect_time = current_time + @reconnect_timeout
311
+
312
+ begin
313
+ @connection.channel.write("openTransaction",
314
+ txn_id, group_name, "", category,
315
+ AnalyticsLogger.timestamp_string,
316
+ union_station_key,
317
+ true)
318
+ return Log.new(@connection, txn_id)
319
+ rescue SystemCallError, IOError
320
+ @connection.disconnect
321
+ DebugLogging.warn("The logging agent at #{@server_address}" <<
322
+ " closed the connection; will reconnect in " <<
323
+ "#{@reconnect_timeout} second(s).")
324
+ @next_reconnect_time = current_time + @reconnect_timeout
325
+ return Log.new
326
+ rescue Exception => e
327
+ @connection.disconnect
328
+ raise e
329
+ end
293
330
  end
294
- return Log.new
295
- end
296
331
  end
297
332
  end
298
333
 
@@ -337,18 +372,23 @@ private
337
372
  end
338
373
  end
339
374
 
340
- class SharedData
375
+ class Connection
341
376
  attr_reader :mutex
342
- attr_accessor :client
377
+ attr_accessor :channel
343
378
 
344
- def initialize
379
+ def initialize(io)
345
380
  @mutex = Mutex.new
346
381
  @refcount = 1
382
+ @channel = MessageChannel.new(io) if io
383
+ end
384
+
385
+ def connected?
386
+ return !!@channel
347
387
  end
348
388
 
349
- def disconnect(check_error_response = false)
350
- # TODO: implement check_error_response support
351
- @client.close if @client
389
+ def disconnect
390
+ @channel.close if @channel
391
+ @channel = nil
352
392
  end
353
393
 
354
394
  def ref
@@ -369,29 +409,46 @@ private
369
409
  end
370
410
  end
371
411
 
372
- def connected?
373
- return @shared_data.client && @shared_data.client.connected?
374
- end
375
-
376
412
  def connect
377
- @shared_data.client = MessageClient.new(@username, @password, @server_address)
378
- @shared_data.client.write("init", @node_name)
379
- args = @shared_data.client.read
413
+ socket = connect_to_server(@server_address)
414
+ channel = MessageChannel.new(socket)
415
+
416
+ result = channel.read
417
+ if result.nil?
418
+ raise EOFError
419
+ elsif result.size != 2 || result[0] != "version"
420
+ raise IOError, "The logging agent didn't sent a valid version identifier"
421
+ elsif result[1] != "1"
422
+ raise IOError, "Unsupported logging agent protocol version #{result[1]}"
423
+ end
424
+
425
+ channel.write_scalar(@username)
426
+ channel.write_scalar(@password)
427
+
428
+ result = channel.read
429
+ if result.nil?
430
+ raise EOFError
431
+ elsif result[0] != "ok"
432
+ raise SecurityError, result[0]
433
+ end
434
+
435
+ channel.write("init", @node_name)
436
+ args = channel.read
380
437
  if !args
381
- raise Errno::ECONNREFUSED, "Cannot connect to logging server"
438
+ raise Errno::ECONNREFUSED, "Cannot connect to logging agent"
382
439
  elsif args.size != 1
383
- raise IOError, "Logging server returned an invalid reply for the 'init' command"
440
+ raise IOError, "Logging agent returned an invalid reply for the 'init' command"
384
441
  elsif args[0] == "server shutting down"
385
- raise Errno::ECONNREFUSED, "Cannot connect to logging server"
442
+ raise Errno::ECONNREFUSED, "Cannot connect to logging agent"
386
443
  elsif args[0] != "ok"
387
- raise IOError, "Logging server returned an invalid reply for the 'init' command"
444
+ raise IOError, "Logging agent returned an invalid reply for the 'init' command"
388
445
  end
389
- end
390
-
391
- def disconnect(check_error_response = false)
392
- @shared_data.disconnect(check_error_response)
393
- @shared_data.unref
394
- @shared_data = SharedData.new
446
+
447
+ @connection.unref
448
+ @connection = Connection.new(socket)
449
+ rescue Exception => e
450
+ socket.close if socket && !socket.closed?
451
+ raise e
395
452
  end
396
453
 
397
454
  def random_token(length)