jls-lumberjack 0.0.20 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 257e7277d9d370246671e1a117e9102674386177
4
- data.tar.gz: be48c31b83ccecc610c152a1c928f8040dd3a1dd
3
+ metadata.gz: 9a5fbaaf0c05070435f5ce9299ef8b4d67309f0a
4
+ data.tar.gz: 8b382ea94f4dc405580cad2477c3209a59c6b95e
5
5
  SHA512:
6
- metadata.gz: 998a1720267a70608f3061a661624d420875e66bef41eba4193047815319023da6de7365d0b934ee1983f96c4ee8e28e6730af77e687ab5dd5accca2294141f9
7
- data.tar.gz: 698db79fc9618f656d4767baa2bbbf058268d768744e9d38d75841acca8af4b6fcad9908221c63fff589289516ea77387822b3438346487428d932df70079874
6
+ metadata.gz: d05766693143ceb79ab82872c82acd904d9004e73fcefa769393c623d029e0731f7153522ade00709cde4b475a9a0c8d667e5a39cd51e9dc514053864cfb5ede
7
+ data.tar.gz: eca095412e36b14c8a6a71f4bf1961ddfbf849f34b1ddadbc9e283427205a1566743d047ded06bb288461d24b70471441fa6039905a75bb73df85cb6a21e23d0
@@ -4,8 +4,8 @@ require "openssl"
4
4
  require "zlib"
5
5
 
6
6
  module Lumberjack
7
-
8
- SEQUENCE_MAX = (2**(0.size * 8 -2) -1)
7
+
8
+ SEQUENCE_MAX = (2**32-1).freeze
9
9
 
10
10
  class Client
11
11
  def initialize(opts={})
@@ -73,44 +73,64 @@ module Lumberjack
73
73
  @host = @opts[:address]
74
74
  @window_size = @opts[:window_size]
75
75
 
76
- tcp_socket = TCPSocket.new(@opts[:address], @opts[:port])
77
- openssl_cert = OpenSSL::X509::Certificate.new(File.read(@opts[:ssl_certificate]))
76
+ connection_start(opts)
77
+ end
78
+
79
+ private
80
+ def connection_start(opts)
81
+ tcp_socket = TCPSocket.new(opts[:address], opts[:port])
78
82
  @socket = OpenSSL::SSL::SSLSocket.new(tcp_socket)
79
83
  @socket.connect
80
-
81
- #if @socket.peer_cert.to_s != openssl_cert.to_s
82
- # raise "Client and server certificates do not match."
83
- #end
84
-
85
84
  @socket.syswrite(["1", "W", @window_size].pack("AAN"))
86
85
  end
87
86
 
88
87
  private
89
88
  def inc
90
- @sequence = 0 if @sequence+1 > Lumberjack::SEQUENCE_MAX
91
- @sequence += 1
89
+ @sequence = 0 if @sequence + 1 > Lumberjack::SEQUENCE_MAX
90
+ @sequence = @sequence + 1
92
91
  end
93
92
 
94
93
  private
95
94
  def write(msg)
96
95
  compress = Zlib::Deflate.deflate(msg)
97
- @socket.syswrite(["1","C",compress.length,compress].pack("AANA#{compress.length}"))
96
+ payload = ["1","C",compress.length,compress].pack("AANA#{compress.length}")
97
+ # SSLSocket has a limit of 16k per message
98
+ # execute multiple writes if needed
99
+ bytes_written = 0
100
+ while bytes_written < payload.bytesize
101
+ bytes_written += @socket.syswrite(payload.byteslice(bytes_written..-1))
102
+ end
98
103
  end
99
104
 
100
105
  public
101
106
  def write_hash(hash)
102
- frame = to_frame(hash, inc)
103
- ack if (@sequence - (@last_ack + 1)) >= @window_size
107
+ frame = Encoder.to_compressed_frame(hash, inc)
108
+ ack if unacked_sequence_size >= @window_size
104
109
  write frame
105
110
  end
106
111
 
107
112
  private
108
113
  def ack
109
- version = @socket.read(1)
110
- type = @socket.read(1)
114
+ _, type = read_version_and_type
111
115
  raise "Whoa we shouldn't get this frame: #{type}" if type != "A"
112
- @last_ack = @socket.read(4).unpack("N").first
113
- ack if (@sequence - (@last_ack + 1)) >= @window_size
116
+ @last_ack = read_last_ack
117
+ ack if unacked_sequence_size >= @window_size
118
+ end
119
+
120
+ private
121
+ def unacked_sequence_size
122
+ sequence - (@last_ack + 1)
123
+ end
124
+
125
+ private
126
+ def read_version_and_type
127
+ version = @socket.read(1)
128
+ type = @socket.read(1)
129
+ [version, type]
130
+ end
131
+ private
132
+ def read_last_ack
133
+ @socket.read(4).unpack("N").first
114
134
  end
115
135
 
116
136
  private
@@ -122,8 +142,8 @@ module Lumberjack
122
142
  pack << "N"
123
143
  keys.each do |k|
124
144
  val = deep_get(hash,k)
125
- key_length = k.length
126
- val_length = val.length
145
+ key_length = k.bytesize
146
+ val_length = val.bytesize
127
147
  frame << key_length
128
148
  pack << "N"
129
149
  frame << k
@@ -155,4 +175,51 @@ module Lumberjack
155
175
  keys.flatten
156
176
  end
157
177
  end
178
+
179
+ module Encoder
180
+ def self.to_compressed_frame(hash, sequence)
181
+ compress = Zlib::Deflate.deflate(to_frame(hash, sequence))
182
+ ["1", "C", compress.bytesize, compress].pack("AANA#{compress.length}")
183
+ end
184
+
185
+ def self.to_frame(hash, sequence)
186
+ frame = ["1", "D", sequence]
187
+ pack = "AAN"
188
+ keys = deep_keys(hash)
189
+ frame << keys.length
190
+ pack << "N"
191
+ keys.each do |k|
192
+ val = deep_get(hash,k)
193
+ key_length = k.bytesize
194
+ val_length = val.bytesize
195
+ frame << key_length
196
+ pack << "N"
197
+ frame << k
198
+ pack << "A#{key_length}"
199
+ frame << val_length
200
+ pack << "N"
201
+ frame << val
202
+ pack << "A#{val_length}"
203
+ end
204
+ frame.pack(pack)
205
+ end
206
+
207
+ private
208
+ def self.deep_get(hash, key="")
209
+ return hash if key.nil?
210
+ deep_get(
211
+ hash[key.split('.').first],
212
+ key[key.split('.').first.length+1..key.length]
213
+ )
214
+ end
215
+ private
216
+ def self.deep_keys(hash, prefix="")
217
+ keys = []
218
+ hash.each do |k,v|
219
+ keys << "#{prefix}#{k}" if v.class == String
220
+ keys << deep_keys(hash[k], "#{k}.") if v.class == Hash
221
+ end
222
+ keys.flatten
223
+ end
224
+ end # module Encoder
158
225
  end
@@ -22,7 +22,7 @@ module Lumberjack
22
22
  :address => "0.0.0.0",
23
23
  :ssl_certificate => nil,
24
24
  :ssl_key => nil,
25
- :ssl_key_passphrase => nil,
25
+ :ssl_key_passphrase => nil
26
26
  }.merge(options)
27
27
 
28
28
  [:ssl_certificate, :ssl_key].each do |k|
@@ -31,7 +31,8 @@ module Lumberjack
31
31
  end
32
32
  end
33
33
 
34
- @tcp_server = TCPServer.new(@options[:port])
34
+ @tcp_server = TCPServer.new(@options[:address], @options[:port])
35
+
35
36
  # Query the port in case the port number is '0'
36
37
  # TCPServer#addr == [ address_family, port, address, address ]
37
38
  @port = @tcp_server.addr[1]
@@ -44,22 +45,26 @@ module Lumberjack
44
45
 
45
46
  def run(&block)
46
47
  while true
47
- # NOTE: This means ssl accepting is single-threaded.
48
- begin
49
- client = @ssl_server.accept
50
- rescue EOFError, OpenSSL::SSL::SSLError, IOError
51
- # ssl handshake failure or other issue, skip it.
52
- # TODO(sissel): log the error
53
- # TODO(sissel): try to identify what client was connecting that failed.
54
- client.close rescue nil
55
- next
56
- end
57
-
58
- Thread.new(client) do |fd|
59
- Connection.new(fd).run(&block)
48
+ connection = accept
49
+ Thread.new(connection) do |connection|
50
+ connection.run(&block)
60
51
  end
61
52
  end
62
53
  end # def run
54
+
55
+ def accept(&block)
56
+ begin
57
+ fd = @ssl_server.accept
58
+ rescue EOFError, OpenSSL::SSL::SSLError, IOError
59
+ # ssl handshake or other accept-related failure.
60
+ # TODO(sissel): Make it possible to log this.
61
+ end
62
+ if block_given?
63
+ block.call(fd)
64
+ else
65
+ Connection.new(fd)
66
+ end
67
+ end
63
68
  end # class Server
64
69
 
65
70
  class Parser
@@ -92,16 +97,16 @@ module Lumberjack
92
97
  while have?(@need)
93
98
  send(@state, &block)
94
99
  #case @state
95
- #when :header; header(&block)
96
- #when :window_size; window_size(&block)
97
- #when :data_lead; data_lead(&block)
98
- #when :data_field_key_len; data_field_key_len(&block)
99
- #when :data_field_key; data_field_key(&block)
100
- #when :data_field_value_len; data_field_value_len(&block)
101
- #when :data_field_value; data_field_value(&block)
102
- #when :data_field_value; data_field_value(&block)
103
- #when :compressed_lead; compressed_lead(&block)
104
- #when :compressed_payload; compressed_payload(&block)
100
+ #when :header; header(&block)
101
+ #when :window_size; window_size(&block)
102
+ #when :data_lead; data_lead(&block)
103
+ #when :data_field_key_len; data_field_key_len(&block)
104
+ #when :data_field_key; data_field_key(&block)
105
+ #when :data_field_value_len; data_field_value_len(&block)
106
+ #when :data_field_value; data_field_value(&block)
107
+ #when :data_field_value; data_field_value(&block)
108
+ #when :compressed_lead; compressed_lead(&block)
109
+ #when :compressed_payload; compressed_payload(&block)
105
110
  #end # case @state
106
111
  end
107
112
  return nil
@@ -136,10 +141,10 @@ module Lumberjack
136
141
  version, frame_type = get.bytes.to_a[0..1]
137
142
 
138
143
  case frame_type
139
- when FRAME_WINDOW; transition(:window_size, 4)
140
- when FRAME_DATA; transition(:data_lead, 8)
141
- when FRAME_COMPRESSED; transition(:compressed_lead, 4)
142
- else; raise "Unknown frame type: #{frame_type}"
144
+ when FRAME_WINDOW; transition(:window_size, 4)
145
+ when FRAME_DATA; transition(:data_lead, 8)
146
+ when FRAME_COMPRESSED; transition(:compressed_lead, 4)
147
+ else; raise "Unknown frame type: #{frame_type}"
143
148
  end
144
149
  end
145
150
 
@@ -189,7 +194,7 @@ module Lumberjack
189
194
  length = get.unpack("N").first
190
195
  transition(:compressed_payload, length)
191
196
  end
192
-
197
+
193
198
  def compressed_payload(&block)
194
199
  original = Zlib::Inflate.inflate(get)
195
200
  transition(:header, 2)
@@ -219,8 +224,8 @@ module Lumberjack
219
224
  # X: too many events after errors.
220
225
  @parser.feed(@fd.sysread(16384)) do |event, *args|
221
226
  case event
222
- when :window_size; window_size(*args, &block)
223
- when :data; data(*args, &block)
227
+ when :window_size; window_size(*args, &block)
228
+ when :data; data(*args, &block)
224
229
  end
225
230
  #send(event, *args)
226
231
  end # feed
@@ -229,16 +234,19 @@ module Lumberjack
229
234
  # EOF or other read errors, only action is to shutdown which we'll do in
230
235
  # 'ensure'
231
236
  ensure
232
- # Try to ensure it's closed, but if this fails I don't care.
233
- @fd.close rescue nil
237
+ close rescue 'Already closed stream'
234
238
  end # def run
235
239
 
240
+ def close
241
+ @fd.close
242
+ end
243
+
236
244
  def window_size(size)
237
245
  @window_size = size
238
246
  end
239
247
 
240
248
  def data(sequence, map, &block)
241
- block.call(map)
249
+ block.call(map) if block_given?
242
250
  if (sequence - @last_ack) >= @window_size
243
251
  @fd.syswrite(["1A", sequence].pack("A*N"))
244
252
  @last_ack = sequence
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jls-lumberjack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20
4
+ version: 0.0.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sissel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-12 00:00:00.000000000 Z
11
+ date: 2015-02-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: lumberjack log transport library
14
14
  email:
@@ -17,11 +17,10 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - lib/lumberjack/server.rb
21
20
  - lib/lumberjack/client.rb
21
+ - lib/lumberjack/server.rb
22
22
  homepage: https://github.com/jordansissel/lumberjack
23
- licenses:
24
- - Apache 2.0
23
+ licenses: []
25
24
  metadata: {}
26
25
  post_install_message:
27
26
  rdoc_options: []
@@ -29,17 +28,17 @@ require_paths:
29
28
  - lib
30
29
  required_ruby_version: !ruby/object:Gem::Requirement
31
30
  requirements:
32
- - - '>='
31
+ - - ">="
33
32
  - !ruby/object:Gem::Version
34
33
  version: '0'
35
34
  required_rubygems_version: !ruby/object:Gem::Requirement
36
35
  requirements:
37
- - - '>='
36
+ - - ">="
38
37
  - !ruby/object:Gem::Version
39
38
  version: '0'
40
39
  requirements: []
41
40
  rubyforge_project:
42
- rubygems_version: 2.1.11
41
+ rubygems_version: 2.4.3
43
42
  signing_key:
44
43
  specification_version: 4
45
44
  summary: lumberjack log transport library