fluent-plugin-websocket 0.1.7 → 0.1.8

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: 88b467a1b71ca69b8a5788e2b8eaf77dc2757e5d
4
- data.tar.gz: d875ee07c22e50bca910a3fde58114ada7cee4ba
3
+ metadata.gz: bed9989f3203afca2a0ecac1ecd6d0155aa6b061
4
+ data.tar.gz: 9fe57af129239dd41520445f6f3d5b0e5f90b71b
5
5
  SHA512:
6
- metadata.gz: 5a94849d7c1120d52cb8ba89f554de622fb7027989e426d76ab103e01ea6021bd1631db2914e09112bad06313f4af63e35e62a78affca0ffceb1e29b060db2db
7
- data.tar.gz: 9373a773cdf5f4cd5bdc0e1d04738f18b2315c3bafcebe72d933a6fd83b5f2a984c298da0a61aebbf571b792078e83374355ea15f6b6cf63da15db1058ffed6e
6
+ metadata.gz: 49300703aa75c86e1a571a5e1bc527bacf735916e8d3c85718e0f400756b920071657528263152248a2b678b546e9c1cd260f062ef2bda49afbbd09cbf49f687
7
+ data.tar.gz: 1446c1902d16db79f4c499c0d68afb5c9e86b0ad418d87073c0acc302652a51c16287cbe29bfe506547c28bbe3fd1c275f629c012c196c8a93701dfbdcfb16a8
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 IZAWA Tetsu (@moccos)
1
+ Copyright (c) 2013 Tetsu Izawa (@moccos)
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
@@ -1,4 +1,5 @@
1
- = Fluent::Plugin::Websocket
1
+ = fluent-plugin-websocket
2
+ {https://badge.fury.io/rb/fluent-plugin-websocket.svg}[https://badge.fury.io/rb/fluent-plugin-websocket]
2
3
 
3
4
  Fluentd websocket output plugin.
4
5
 
@@ -10,17 +11,16 @@ In the current version, emitted data will be broadcasted to the all connected cl
10
11
 
11
12
  gem install fluent-plugin-websocket
12
13
 
13
- This plugin depends on {*em-websocket*}[https://github.com/igrigorik/em-websocket].
14
-
15
14
  == Configuration
16
15
  <match foo.**>
17
16
  type websocket
18
- host 192.168.1.1 # default: 0.0.0.0 (ANY)
19
- port 8080 # default: 8080
20
- use_msgpack false # default: false
21
- add_time false # default: false
22
- add_tag true # default: true
17
+ host 192.168.1.1 # default: 0.0.0.0 (ANY)
18
+ port 8080 # default: 8080
19
+ use_msgpack false # default: false
20
+ add_time false # default: false
21
+ add_tag true # default: true
23
22
  buffered_messages 100 # default: 0
23
+ token SomeToken # default: nil
24
24
  </match>
25
25
 
26
26
  * *host*: WebSocket server IP address.
@@ -29,6 +29,7 @@ This plugin depends on {*em-websocket*}[https://github.com/igrigorik/em-websocke
29
29
  * <b>add_time</b>: Add timestamp to the data.
30
30
  * <b>add_tag</b>: Add fluentd tag to the data.
31
31
  * <b>buffered_messages</b>: The number of messages to be buffered. The new connection receives them.
32
+ * <b>token</b>: Authentication token. Passed as get param. If set to nil, authentication is disabled.
32
33
 
33
34
  If there are no websocket connections, this plugin silently discards data. You may use <em>out_copy</em> plugin like this:
34
35
 
@@ -74,23 +75,33 @@ Extract data by {msgpack.js}[https://github.com/msgpack/msgpack-javascript].
74
75
  ...
75
76
  }
76
77
 
77
- == Contributing
78
+ === Authentication and filtering
79
+
80
+ curl --include \
81
+ --no-buffer \
82
+ --header "Connection: Upgrade" \
83
+ --header "Upgrade: websocket" \
84
+ --header "Host: 127.0.0.1:8080" \
85
+ --header "Origin: http://127.0.0.1:8080" \
86
+ --header "Sec-WebSocket-Key: SGVabG8sIHOvcmxDIQ==" \
87
+ --header "Sec-WebSocket-Version: 13" \
88
+ "http://127.0.0.1:8888/?foo=bar&token=MyT0ken"
78
89
 
79
- 1. Fork it
80
- 2. Create your feature branch (`git checkout -b my-new-feature`)
81
- 3. Commit your changes (`git commit -am 'Add some feature'`)
82
- 4. Push to the branch (`git push origin my-new-feature`)
83
- 5. Create new Pull Request
90
+ * If token setting in config file is not nil, websocket server checks _token_ parameter
91
+ * Client will receive data which include \{"foo": "bar"\}
84
92
 
85
- == Recent changes
86
- * 0.1.7 Add message buffering. (Thanks to {SebastianOsuna}[https://github.com/SebastianOsuna])
93
+ == Changelogs
94
+ * 0.1.8 Add authentication and filtering
95
+ * 0.1.7 Add message buffering.
87
96
  * 0.1.6 Added license to gemspec.
88
- * 0.1.5 Fixed dependencies. (Thanks to {ca-gacky}[https://github.com/ca-gacky])
89
- * 0.1.4 Changed json parser to yajl. (Thanks to {Kogarasi}[https://github.com/Kogarasi])
97
+ * 0.1.5 Fixed dependencies.
98
+ * 0.1.4 Changed json parser to yajl.
90
99
  * 0.1.3 Bug fix.
91
100
  * 0.1.2 Released gem.
92
101
 
102
+ See commit logs about contributors.
103
+
93
104
  == Copyright
94
105
 
95
- Copyright:: Copyright (c) 2013 IZAWA Tetsu (@moccos)
106
+ Copyright:: Copyright (c) 2013 Tetsu Izawa (@moccos)
96
107
  License:: Apache License, Version 2.0
@@ -0,0 +1,646 @@
1
+ /* jshint browser: true */
2
+ /* global define, module */
3
+ ( // Module boilerplate to support browser globals and browserify and AMD.
4
+ typeof define === "function" ? function (m) { define("msgpack-js", m); } :
5
+ typeof exports === "object" ? function (m) { module.exports = m(); } :
6
+ function(m){ this.msgpack = m(); }
7
+ )(function () {
8
+ "use strict";
9
+
10
+ var exports = {};
11
+
12
+ exports.inspect = inspect;
13
+ function inspect(buffer) {
14
+ if (buffer === undefined) return "undefined";
15
+ var view;
16
+ var type;
17
+ if (buffer instanceof ArrayBuffer) {
18
+ type = "ArrayBuffer";
19
+ view = new DataView(buffer);
20
+ }
21
+ else if (buffer instanceof DataView) {
22
+ type = "DataView";
23
+ view = buffer;
24
+ }
25
+ if (!view) return JSON.stringify(buffer);
26
+ var bytes = [];
27
+ for (var i = 0; i < buffer.byteLength; i++) {
28
+ if (i > 20) {
29
+ bytes.push("...");
30
+ break;
31
+ }
32
+ var byte = view.getUint8(i).toString(16);
33
+ if (byte.length === 1) byte = "0" + byte;
34
+ bytes.push(byte);
35
+ }
36
+ return "<" + type + " " + bytes.join(" ") + ">";
37
+ }
38
+
39
+ // Encode string as utf8 into dataview at offset
40
+ exports.utf8Write = utf8Write;
41
+ function utf8Write(view, offset, string) {
42
+ var byteLength = view.byteLength;
43
+ for(var i = 0, l = string.length; i < l; i++) {
44
+ var codePoint = string.charCodeAt(i);
45
+
46
+ // One byte of UTF-8
47
+ if (codePoint < 0x80) {
48
+ view.setUint8(offset++, codePoint >>> 0 & 0x7f | 0x00);
49
+ continue;
50
+ }
51
+
52
+ // Two bytes of UTF-8
53
+ if (codePoint < 0x800) {
54
+ view.setUint8(offset++, codePoint >>> 6 & 0x1f | 0xc0);
55
+ view.setUint8(offset++, codePoint >>> 0 & 0x3f | 0x80);
56
+ continue;
57
+ }
58
+
59
+ // Three bytes of UTF-8.
60
+ if (codePoint < 0x10000) {
61
+ view.setUint8(offset++, codePoint >>> 12 & 0x0f | 0xe0);
62
+ view.setUint8(offset++, codePoint >>> 6 & 0x3f | 0x80);
63
+ view.setUint8(offset++, codePoint >>> 0 & 0x3f | 0x80);
64
+ continue;
65
+ }
66
+
67
+ // Four bytes of UTF-8
68
+ if (codePoint < 0x110000) {
69
+ view.setUint8(offset++, codePoint >>> 18 & 0x07 | 0xf0);
70
+ view.setUint8(offset++, codePoint >>> 12 & 0x3f | 0x80);
71
+ view.setUint8(offset++, codePoint >>> 6 & 0x3f | 0x80);
72
+ view.setUint8(offset++, codePoint >>> 0 & 0x3f | 0x80);
73
+ continue;
74
+ }
75
+ throw new Error("bad codepoint " + codePoint);
76
+ }
77
+ }
78
+
79
+ exports.utf8Read = utf8Read;
80
+ function utf8Read(view, offset, length) {
81
+ var string = "";
82
+ for (var i = offset, end = offset + length; i < end; i++) {
83
+ var byte = view.getUint8(i);
84
+ // One byte character
85
+ if ((byte & 0x80) === 0x00) {
86
+ string += String.fromCharCode(byte);
87
+ continue;
88
+ }
89
+ // Two byte character
90
+ if ((byte & 0xe0) === 0xc0) {
91
+ string += String.fromCharCode(
92
+ ((byte & 0x1f) << 6) |
93
+ (view.getUint8(++i) & 0x3f)
94
+ );
95
+ continue;
96
+ }
97
+ // Three byte character
98
+ if ((byte & 0xf0) === 0xe0) {
99
+ string += String.fromCharCode(
100
+ ((byte & 0x0f) << 12) |
101
+ ((view.getUint8(++i) & 0x3f) << 6) |
102
+ ((view.getUint8(++i) & 0x3f) << 0)
103
+ );
104
+ continue;
105
+ }
106
+ // Four byte character
107
+ if ((byte & 0xf8) === 0xf0) {
108
+ string += String.fromCharCode(
109
+ ((byte & 0x07) << 18) |
110
+ ((view.getUint8(++i) & 0x3f) << 12) |
111
+ ((view.getUint8(++i) & 0x3f) << 6) |
112
+ ((view.getUint8(++i) & 0x3f) << 0)
113
+ );
114
+ continue;
115
+ }
116
+ throw new Error("Invalid byte " + byte.toString(16));
117
+ }
118
+ return string;
119
+ }
120
+
121
+ exports.utf8ByteCount = utf8ByteCount;
122
+ function utf8ByteCount(string) {
123
+ var count = 0;
124
+ for(var i = 0, l = string.length; i < l; i++) {
125
+ var codePoint = string.charCodeAt(i);
126
+ if (codePoint < 0x80) {
127
+ count += 1;
128
+ continue;
129
+ }
130
+ if (codePoint < 0x800) {
131
+ count += 2;
132
+ continue;
133
+ }
134
+ if (codePoint < 0x10000) {
135
+ count += 3;
136
+ continue;
137
+ }
138
+ if (codePoint < 0x110000) {
139
+ count += 4;
140
+ continue;
141
+ }
142
+ throw new Error("bad codepoint " + codePoint);
143
+ }
144
+ return count;
145
+ }
146
+
147
+ exports.encode = function (value) {
148
+ var buffer = new ArrayBuffer(encodedSize(value));
149
+ var view = new DataView(buffer);
150
+ encode(value, view, 0);
151
+ return buffer;
152
+ };
153
+
154
+ exports.decode = decode;
155
+
156
+ // https://github.com/msgpack/msgpack/blob/master/spec.md
157
+ // we reserve extension type 0x00 to encode javascript 'undefined'
158
+
159
+ function Decoder(view, offset) {
160
+ this.offset = offset || 0;
161
+ this.view = view;
162
+ }
163
+ Decoder.prototype.map = function (length) {
164
+ var value = {};
165
+ for (var i = 0; i < length; i++) {
166
+ var key = this.parse();
167
+ value[key] = this.parse();
168
+ }
169
+ return value;
170
+ };
171
+ Decoder.prototype.bin = function (length) {
172
+ var value = new ArrayBuffer(length);
173
+ (new Uint8Array(value)).set(new Uint8Array(this.view.buffer, this.offset, length), 0);
174
+ this.offset += length;
175
+ return value;
176
+ };
177
+ Decoder.prototype.str = function (length) {
178
+ var value = utf8Read(this.view, this.offset, length);
179
+ this.offset += length;
180
+ return value;
181
+ };
182
+ Decoder.prototype.array = function (length) {
183
+ var value = new Array(length);
184
+ for (var i = 0; i < length; i++) {
185
+ value[i] = this.parse();
186
+ }
187
+ return value;
188
+ };
189
+ Decoder.prototype.parse = function () {
190
+ var type = this.view.getUint8(this.offset);
191
+ var value, length;
192
+ // FixStr
193
+ if ((type & 0xe0) === 0xa0) {
194
+ length = type & 0x1f;
195
+ this.offset++;
196
+ return this.str(length);
197
+ }
198
+ // FixMap
199
+ if ((type & 0xf0) === 0x80) {
200
+ length = type & 0x0f;
201
+ this.offset++;
202
+ return this.map(length);
203
+ }
204
+ // FixArray
205
+ if ((type & 0xf0) === 0x90) {
206
+ length = type & 0x0f;
207
+ this.offset++;
208
+ return this.array(length);
209
+ }
210
+ // Positive FixNum
211
+ if ((type & 0x80) === 0x00) {
212
+ this.offset++;
213
+ return type;
214
+ }
215
+ // Negative Fixnum
216
+ if ((type & 0xe0) === 0xe0) {
217
+ value = this.view.getInt8(this.offset);
218
+ this.offset++;
219
+ return value;
220
+ }
221
+ // Undefined as FixExt1
222
+ if (type === 0xd4 && this.view.getUint8(this.offset + 1) === 0x00) {
223
+ this.offset += 3;
224
+ return undefined;
225
+ }
226
+ switch (type) {
227
+ // str 8
228
+ case 0xd9:
229
+ length = this.view.getUint8(this.offset + 1);
230
+ this.offset += 2;
231
+ return this.str(length);
232
+ // str 16
233
+ case 0xda:
234
+ length = this.view.getUint16(this.offset + 1);
235
+ this.offset += 3;
236
+ return this.str(length);
237
+ // str 32
238
+ case 0xdb:
239
+ length = this.view.getUint32(this.offset + 1);
240
+ this.offset += 5;
241
+ return this.str(length);
242
+ // bin 8
243
+ case 0xc4:
244
+ length = this.view.getUint8(this.offset + 1);
245
+ this.offset += 2;
246
+ return this.bin(length);
247
+ // bin 16
248
+ case 0xc5:
249
+ length = this.view.getUint16(this.offset + 1);
250
+ this.offset += 3;
251
+ return this.bin(length);
252
+ // bin 32
253
+ case 0xc6:
254
+ length = this.view.getUint32(this.offset + 1);
255
+ this.offset += 5;
256
+ return this.bin(length);
257
+ // nil
258
+ case 0xc0:
259
+ this.offset++;
260
+ return null;
261
+ // false
262
+ case 0xc2:
263
+ this.offset++;
264
+ return false;
265
+ // true
266
+ case 0xc3:
267
+ this.offset++;
268
+ return true;
269
+ // uint8
270
+ case 0xcc:
271
+ value = this.view.getUint8(this.offset + 1);
272
+ this.offset += 2;
273
+ return value;
274
+ // uint 16
275
+ case 0xcd:
276
+ value = this.view.getUint16(this.offset + 1);
277
+ this.offset += 3;
278
+ return value;
279
+ // uint 32
280
+ case 0xce:
281
+ value = this.view.getUint32(this.offset + 1);
282
+ this.offset += 5;
283
+ return value;
284
+ // uint 64
285
+ case 0xcf:
286
+ var high = this.view.getUint32(this.offset + 1);
287
+ var low = this.view.getUint32(this.offset + 5);
288
+ value = high*0x100000000 + low;
289
+ this.offset += 9;
290
+ return value;
291
+ // int 8
292
+ case 0xd0:
293
+ value = this.view.getInt8(this.offset + 1);
294
+ this.offset += 2;
295
+ return value;
296
+ // int 16
297
+ case 0xd1:
298
+ value = this.view.getInt16(this.offset + 1);
299
+ this.offset += 3;
300
+ return value;
301
+ // int 32
302
+ case 0xd2:
303
+ value = this.view.getInt32(this.offset + 1);
304
+ this.offset += 5;
305
+ return value;
306
+ // int 64
307
+ case 0xd3:
308
+ var high = this.view.getInt32(this.offset + 1);
309
+ var low = this.view.getUint32(this.offset + 5);
310
+ value = high*0x100000000 + low;
311
+ this.offset += 9;
312
+ return value;
313
+ // map 16
314
+ case 0xde:
315
+ length = this.view.getUint16(this.offset + 1);
316
+ this.offset += 3;
317
+ return this.map(length);
318
+ // map 32
319
+ case 0xdf:
320
+ length = this.view.getUint32(this.offset + 1);
321
+ this.offset += 5;
322
+ return this.map(length);
323
+ // array 16
324
+ case 0xdc:
325
+ length = this.view.getUint16(this.offset + 1);
326
+ this.offset += 3;
327
+ return this.array(length);
328
+ // array 32
329
+ case 0xdd:
330
+ length = this.view.getUint32(this.offset + 1);
331
+ this.offset += 5;
332
+ return this.array(length);
333
+ // float
334
+ case 0xca:
335
+ value = this.view.getFloat32(this.offset + 1);
336
+ this.offset += 5;
337
+ return value;
338
+ // double
339
+ case 0xcb:
340
+ value = this.view.getFloat64(this.offset + 1);
341
+ this.offset += 9;
342
+ return value;
343
+ }
344
+ throw new Error("Unknown type 0x" + type.toString(16));
345
+ };
346
+ function decode(buffer) {
347
+ var view = new DataView(buffer);
348
+ var decoder = new Decoder(view);
349
+ var value = decoder.parse();
350
+ if (decoder.offset !== buffer.byteLength) throw new Error((buffer.byteLength - decoder.offset) + " trailing bytes");
351
+ return value;
352
+ }
353
+
354
+ function encode(value, view, offset) {
355
+ var type = typeof value;
356
+
357
+ // Strings Bytes
358
+ if (type === "string") {
359
+ var length = utf8ByteCount(value);
360
+ // fix str
361
+ if (length < 0x20) {
362
+ view.setUint8(offset, length | 0xa0);
363
+ utf8Write(view, offset + 1, value);
364
+ return 1 + length;
365
+ }
366
+ // str 8
367
+ if (length < 0x100) {
368
+ view.setUint8(offset, 0xd9);
369
+ view.setUint8(offset + 1, length);
370
+ utf8Write(view, offset + 2, value);
371
+ return 2 + length;
372
+ }
373
+ // str 16
374
+ if (length < 0x10000) {
375
+ view.setUint8(offset, 0xda);
376
+ view.setUint16(offset + 1, length);
377
+ utf8Write(view, offset + 3, value);
378
+ return 3 + length;
379
+ }
380
+ // str 32
381
+ if (length < 0x100000000) {
382
+ view.setUint8(offset, 0xdb);
383
+ view.setUint32(offset + 1, length);
384
+ utf8Write(view, offset + 5, value);
385
+ return 5 + length;
386
+ }
387
+ }
388
+
389
+ if (value instanceof ArrayBuffer) {
390
+ var length = value.byteLength;
391
+ // bin 8
392
+ if (length < 0x100) {
393
+ view.setUint8(offset, 0xc4);
394
+ view.setUint8(offset + 1, length);
395
+ (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 2);
396
+ return 2 + length;
397
+ }
398
+ // bin 16
399
+ if (length < 0x10000) {
400
+ view.setUint8(offset, 0xc5);
401
+ view.setUint16(offset + 1, length);
402
+ (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 3);
403
+ return 3 + length;
404
+ }
405
+ // bin 32
406
+ if (length < 0x100000000) {
407
+ view.setUint8(offset, 0xc6);
408
+ view.setUint32(offset + 1, length);
409
+ (new Uint8Array(view.buffer)).set(new Uint8Array(value), offset + 5);
410
+ return 5 + length;
411
+ }
412
+ }
413
+
414
+ if (type === "number") {
415
+ // Floating Point
416
+ if ((value << 0) !== value) {
417
+ view.setUint8(offset, 0xcb);
418
+ view.setFloat64(offset + 1, value);
419
+ return 9;
420
+ }
421
+
422
+ // Integers
423
+ if (value >=0) {
424
+ // positive fixnum
425
+ if (value < 0x80) {
426
+ view.setUint8(offset, value);
427
+ return 1;
428
+ }
429
+ // uint 8
430
+ if (value < 0x100) {
431
+ view.setUint8(offset, 0xcc);
432
+ view.setUint8(offset + 1, value);
433
+ return 2;
434
+ }
435
+ // uint 16
436
+ if (value < 0x10000) {
437
+ view.setUint8(offset, 0xcd);
438
+ view.setUint16(offset + 1, value);
439
+ return 3;
440
+ }
441
+ // uint 32
442
+ if (value < 0x100000000) {
443
+ view.setUint8(offset, 0xce);
444
+ view.setUint32(offset + 1, value);
445
+ return 5;
446
+ }
447
+ throw new Error("Number too big 0x" + value.toString(16));
448
+ }
449
+ // negative fixnum
450
+ if (value >= -0x20) {
451
+ view.setInt8(offset, value);
452
+ return 1;
453
+ }
454
+ // int 8
455
+ if (value >= -0x80) {
456
+ view.setUint8(offset, 0xd0);
457
+ view.setInt8(offset + 1, value);
458
+ return 2;
459
+ }
460
+ // int 16
461
+ if (value >= -0x8000) {
462
+ view.setUint8(offset, 0xd1);
463
+ view.setInt16(offset + 1, value);
464
+ return 3;
465
+ }
466
+ // int 32
467
+ if (value >= -0x80000000) {
468
+ view.setUint8(offset, 0xd2);
469
+ view.setInt32(offset + 1, value);
470
+ return 5;
471
+ }
472
+ throw new Error("Number too small -0x" + (-value).toString(16).substr(1));
473
+ }
474
+
475
+ // undefined
476
+ if (type === "undefined") {
477
+ view.setUint8(offset, 0xd4); // fixext 1
478
+ view.setUint8(offset + 1, 0); // type (undefined)
479
+ view.setUint8(offset + 2, 0); // data (ignored)
480
+ return 3;
481
+ }
482
+
483
+ // null
484
+ if (value === null) {
485
+ view.setUint8(offset, 0xc0);
486
+ return 1;
487
+ }
488
+
489
+ // Boolean
490
+ if (type === "boolean") {
491
+ view.setUint8(offset, value ? 0xc3 : 0xc2);
492
+ return 1;
493
+ }
494
+
495
+ // Container Types
496
+ if (type === "object") {
497
+ var length, size = 0;
498
+ var isArray = Array.isArray(value);
499
+
500
+ if (isArray) {
501
+ length = value.length;
502
+ }
503
+ else {
504
+ var keys = Object.keys(value);
505
+ length = keys.length;
506
+ }
507
+
508
+ var size;
509
+ if (length < 0x10) {
510
+ view.setUint8(offset, length | (isArray ? 0x90 : 0x80));
511
+ size = 1;
512
+ }
513
+ else if (length < 0x10000) {
514
+ view.setUint8(offset, isArray ? 0xdc : 0xde);
515
+ view.setUint16(offset + 1, length);
516
+ size = 3;
517
+ }
518
+ else if (length < 0x100000000) {
519
+ view.setUint8(offset, isArray ? 0xdd : 0xdf);
520
+ view.setUint32(offset + 1, length);
521
+ size = 5;
522
+ }
523
+
524
+ if (isArray) {
525
+ for (var i = 0; i < length; i++) {
526
+ size += encode(value[i], view, offset + size);
527
+ }
528
+ }
529
+ else {
530
+ for (var i = 0; i < length; i++) {
531
+ var key = keys[i];
532
+ size += encode(key, view, offset + size);
533
+ size += encode(value[key], view, offset + size);
534
+ }
535
+ }
536
+
537
+ return size;
538
+ }
539
+ throw new Error("Unknown type " + type);
540
+ }
541
+
542
+ function encodedSize(value) {
543
+ var type = typeof value;
544
+
545
+ // Raw Bytes
546
+ if (type === "string") {
547
+ var length = utf8ByteCount(value);
548
+ if (length < 0x20) {
549
+ return 1 + length;
550
+ }
551
+ if (length < 0x100) {
552
+ return 2 + length;
553
+ }
554
+ if (length < 0x10000) {
555
+ return 3 + length;
556
+ }
557
+ if (length < 0x100000000) {
558
+ return 5 + length;
559
+ }
560
+ }
561
+
562
+ if (value instanceof ArrayBuffer) {
563
+ var length = value.byteLength;
564
+ if (length < 0x100) {
565
+ return 2 + length;
566
+ }
567
+ if (length < 0x10000) {
568
+ return 3 + length;
569
+ }
570
+ if (length < 0x100000000) {
571
+ return 5 + length;
572
+ }
573
+ }
574
+
575
+ if (type === "number") {
576
+ // Floating Point
577
+ // double
578
+ if (value << 0 !== value) return 9;
579
+
580
+ // Integers
581
+ if (value >=0) {
582
+ // positive fixnum
583
+ if (value < 0x80) return 1;
584
+ // uint 8
585
+ if (value < 0x100) return 2;
586
+ // uint 16
587
+ if (value < 0x10000) return 3;
588
+ // uint 32
589
+ if (value < 0x100000000) return 5;
590
+ // uint 64
591
+ if (value < 0x10000000000000000) return 9;
592
+ throw new Error("Number too big 0x" + value.toString(16));
593
+ }
594
+ // negative fixnum
595
+ if (value >= -0x20) return 1;
596
+ // int 8
597
+ if (value >= -0x80) return 2;
598
+ // int 16
599
+ if (value >= -0x8000) return 3;
600
+ // int 32
601
+ if (value >= -0x80000000) return 5;
602
+ // int 64
603
+ if (value >= -0x8000000000000000) return 9;
604
+ throw new Error("Number too small -0x" + value.toString(16).substr(1));
605
+ }
606
+
607
+ // undefined
608
+ if (type === "undefined") return 3;
609
+
610
+ // Boolean, null
611
+ if (type === "boolean" || value === null) return 1;
612
+
613
+ // Container Types
614
+ if (type === "object") {
615
+ var length, size = 0;
616
+ if (Array.isArray(value)) {
617
+ length = value.length;
618
+ for (var i = 0; i < length; i++) {
619
+ size += encodedSize(value[i]);
620
+ }
621
+ }
622
+ else {
623
+ var keys = Object.keys(value);
624
+ length = keys.length;
625
+ for (var i = 0; i < length; i++) {
626
+ var key = keys[i];
627
+ size += encodedSize(key) + encodedSize(value[key]);
628
+ }
629
+ }
630
+ if (length < 0x10) {
631
+ return 1 + size;
632
+ }
633
+ if (length < 0x10000) {
634
+ return 3 + size;
635
+ }
636
+ if (length < 0x100000000) {
637
+ return 5 + size;
638
+ }
639
+ throw new Error("Array or object too long 0x" + length.toString(16));
640
+ }
641
+ throw new Error("Unknown type " + type);
642
+ }
643
+
644
+ return exports;
645
+
646
+ });
@@ -0,0 +1,81 @@
1
+ <!DOCTYPE html>
2
+ </head>
3
+ <meta charset="utf-8" />
4
+ <title>WebSocket Test</title>
5
+ </head>
6
+ <!-- based on http://www.websocket.org/echo.html -->
7
+ <body>
8
+ <!-- https://github.com/creationix/msgpack-js-browser --><script src="./msgpack.js"></script>
9
+ <script language="javascript" type="text/javascript">
10
+
11
+ var wsUri = "ws://localhost:38080/";
12
+ var output;
13
+ var latestData; // for debugging
14
+
15
+ function init()
16
+ {
17
+ output = document.getElementById("output");
18
+ testWebSocket();
19
+ }
20
+
21
+ function testWebSocket()
22
+ {
23
+ websocket = new WebSocket(wsUri);
24
+ websocket.binaryType = "arraybuffer";
25
+ websocket.onopen = function(evt) { onOpen(evt) };
26
+ websocket.onclose = function(evt) { onClose(evt) };
27
+ websocket.onmessage = function(evt) { onMessage(evt) };
28
+ websocket.onerror = function(evt) { onError(evt) };
29
+ }
30
+
31
+ function onOpen(evt)
32
+ {
33
+ writeToScreen("CONNECTED");
34
+ doSend("onOpen");
35
+ }
36
+
37
+ function onClose(evt)
38
+ {
39
+ writeToScreen("DISCONNECTED");
40
+ }
41
+
42
+ function onMessage(evt)
43
+ {
44
+ latestData = evt.data
45
+ if (typeof(evt.data) == 'string') {
46
+ text = evt.data;
47
+ } else {
48
+ decoded = msgpack.decode(evt.data);
49
+ text = JSON.stringify(decoded.slice(1));
50
+ }
51
+ writeToScreen('<span style="color: blue;">RESPONSE: ' + text +'</span>');
52
+ }
53
+
54
+ function onError(evt)
55
+ {
56
+ writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
57
+ }
58
+
59
+ function doSend(message)
60
+ {
61
+ writeToScreen("SENT: " + message);
62
+ websocket.send(message);
63
+ }
64
+
65
+ function writeToScreen(message)
66
+ {
67
+ var pre = document.createElement("p");
68
+ pre.style.wordWrap = "break-word";
69
+ pre.innerHTML = message;
70
+ output.appendChild(pre);
71
+ }
72
+
73
+ window.addEventListener("load", init, false);
74
+
75
+ </script>
76
+
77
+ <h2>WebSocket Test</h2>
78
+
79
+ <div id="output"></div>
80
+ </body>
81
+
@@ -3,8 +3,8 @@ $:.push File.expand_path('../lib', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.name = "fluent-plugin-websocket"
6
- gem.version = "0.1.7"
7
- gem.authors = ["IZAWA Tetsu (@moccos)"]
6
+ gem.version = "0.1.8"
7
+ gem.authors = ["Tetsu Izawa (@moccos)"]
8
8
  gem.email = ["tt.izawa@gmail.com"]
9
9
  gem.homepage = "https://github.com/moccos/fluent-plugin-websocket"
10
10
  gem.summary = %q{Fluentd websocket output plugin}
@@ -28,6 +28,7 @@ module Fluent
28
28
  config_param :add_time, :bool, :default => false
29
29
  config_param :add_tag, :bool, :default => true
30
30
  config_param :buffered_messages, :integer, :default => 0
31
+ config_param :token, :string, :default => nil
31
32
 
32
33
  def configure(conf)
33
34
  super
@@ -37,19 +38,28 @@ module Fluent
37
38
  EM.run {
38
39
  EM::WebSocket.run(:host => @host, :port => @port) do |ws|
39
40
  ws.onopen { |handshake|
40
- callback = @use_msgpack ? proc{|msg| ws.send_binary(msg)} : proc{|msg| ws.send(msg)}
41
- $lock.synchronize do
42
- sid = $channel.subscribe callback
43
- $log.trace "WebSocket connection: ID " + sid.to_s
44
- ws.onclose {
45
- $log.trace "Connection closed: ID " + sid.to_s
46
- $lock.synchronize do
47
- $channel.unsubscribe(sid)
41
+ $log.info "WebSocket opened #{{
42
+ :path => handshake.path,
43
+ :query => handshake.query,
44
+ :origin => handshake.origin,
45
+ }}"
46
+ if doAuth(handshake.query)
47
+ callback = @use_msgpack ? proc{|msg| ws.send_binary(msg)} : proc{|msg| sendMsg(handshake.query, ws, msg)}
48
+ $lock.synchronize do
49
+ sid = $channel.subscribe callback
50
+ $log.trace "WebSocket connection: ID " + sid.to_s
51
+ ws.onclose {
52
+ $log.trace "Connection closed: ID " + sid.to_s
53
+ $lock.synchronize do
54
+ $channel.unsubscribe(sid)
55
+ end
56
+ }
57
+ @buffer.each do |msg|
58
+ sendMsg(handshake.query, ws, msg)
48
59
  end
49
- }
50
- @buffer.each do |msg|
51
- ws.send(msg)
52
60
  end
61
+ else
62
+ ws.send("Unauthorized")
53
63
  end
54
64
 
55
65
  #ws.onmessage { |msg|
@@ -60,6 +70,31 @@ module Fluent
60
70
  end
61
71
  end
62
72
 
73
+ def doAuth(query)
74
+ if @token.nil? || ( query.key?("token") && @token == query["token"] )
75
+ $log.trace "Auth OK"
76
+ return true
77
+ end
78
+
79
+ $log.trace "Auth failed"
80
+ return false
81
+ end
82
+
83
+ def sendMsg(filters, ws, msg)
84
+ parser = Yajl::Parser.new
85
+ msgStruct = parser.parse(msg)
86
+ return if msgStruct.length != 2
87
+ msgContent = msgStruct[1]
88
+
89
+ pass = 0
90
+
91
+ filters.each do |key, value|
92
+ pass += 1 if key == 'token' || ( msgContent.key?(key) && msgContent[key] == value )
93
+ end
94
+
95
+ ws.send(msg) if filters.length == pass
96
+ end
97
+
63
98
  def start
64
99
  @buffer = []
65
100
  super
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-websocket
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
- - IZAWA Tetsu (@moccos)
7
+ - Tetsu Izawa (@moccos)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-04 00:00:00.000000000 Z
11
+ date: 2018-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -107,6 +107,8 @@ files:
107
107
  - LICENSE.txt
108
108
  - README.rdoc
109
109
  - Rakefile
110
+ - examples/msgpack.js
111
+ - examples/websocket.html
110
112
  - fluent-plugin-websocket.gemspec
111
113
  - lib/fluent/plugin/out_websocket.rb
112
114
  - test/plugin/test_out_websocket.rb
@@ -130,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
132
  version: '0'
131
133
  requirements: []
132
134
  rubyforge_project:
133
- rubygems_version: 2.2.2
135
+ rubygems_version: 2.6.11
134
136
  signing_key:
135
137
  specification_version: 4
136
138
  summary: Fluentd websocket output plugin