Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Rewrite masking function in Java for JRuby.

  • Loading branch information...
commit 83059e59b11e960e056a229dc013e77123f780ed 1 parent 10d8518
@jcoglan jcoglan authored
View
1  .gitignore
@@ -4,5 +4,6 @@ pkg
tmp
*.bundle
*.gem
+*.jar
*.o
*.so
View
2  .travis.yml
@@ -8,6 +8,6 @@ rvm:
before_script:
- git submodule update --init --recursive
- - (ruby -v | grep jruby > /dev/null) || rake compile
+ - rake compile
script: bundle exec rspec spec/
View
8 Rakefile
@@ -5,10 +5,10 @@ spec = Gem::Specification.load('faye-websocket.gemspec')
Gem::PackageTask.new(spec) do |pkg|
end
-unless RUBY_PLATFORM =~ /java/
- require 'rake/extensiontask'
- Rake::ExtensionTask.new('faye_websocket_mask', spec)
-end
+require 'rake/extensiontask'
+Rake::ExtensionTask.new('faye_websocket_mask', spec)
+require 'rake/javaextensiontask'
+Rake::JavaExtensionTask.new('faye_websocket_mask', spec)
task :clean do
Dir['./**/*.{bundle,o,so}'].each do |path|
View
63 ext/faye_websocket_mask/FayeWebsocketMaskService.java
@@ -0,0 +1,63 @@
+package com.jcoglan.faye;
+
+import java.io.IOException;
+import java.lang.Long;
+
+import org.jruby.Ruby;
+import org.jruby.RubyArray;
+import org.jruby.RubyClass;
+import org.jruby.RubyFixnum;
+import org.jruby.RubyModule;
+import org.jruby.RubyObject;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.ObjectAllocator;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.load.BasicLibraryService;
+
+import java.lang.System;
+
+public class FayeWebsocketMaskService implements BasicLibraryService {
+ private Ruby runtime;
+
+ public boolean basicLoad(Ruby runtime) throws IOException {
+ this.runtime = runtime;
+ RubyModule faye = runtime.defineModule("Faye");
+
+ RubyModule webSocketMask = faye.defineClassUnder("WebSocketMask", runtime.getObject(), new ObjectAllocator() {
+ public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) {
+ return new WebsocketMask(runtime, rubyClass);
+ }
+ });
+
+ webSocketMask.defineAnnotatedMethods(WebsocketMask.class);
+ return true;
+ }
+
+ public class WebsocketMask extends RubyObject {
+ public WebsocketMask(final Ruby runtime, RubyClass rubyClass) {
+ super(runtime, rubyClass);
+ }
+
+ @JRubyMethod
+ public IRubyObject mask(ThreadContext context, IRubyObject payload, IRubyObject mask) {
+ int n = ((RubyArray)payload).getLength(), i;
+ long p, m;
+ RubyArray unmasked = RubyArray.newArray(runtime, n);
+
+ long[] maskArray = {
+ (Long)((RubyArray)mask).get(0),
+ (Long)((RubyArray)mask).get(1),
+ (Long)((RubyArray)mask).get(2),
+ (Long)((RubyArray)mask).get(3)
+ };
+
+ for (i = 0; i < n; i++) {
+ p = (Long)((RubyArray)payload).get(i);
+ m = maskArray[i % 4];
+ unmasked.set(i, p ^ m);
+ }
+ return unmasked;
+ }
+ }
+}
View
4 ext/faye_websocket_mask/faye_websocket_mask.c
@@ -1,7 +1,6 @@
#include <ruby.h>
VALUE Faye = Qnil;
-VALUE FayeWebSocket = Qnil;
VALUE FayeWebSocketMask = Qnil;
void Init_faye_websocket_mask();
@@ -9,8 +8,7 @@ VALUE method_faye_websocket_mask(VALUE self, VALUE payload, VALUE mask);
void Init_faye_websocket_mask() {
Faye = rb_define_module("Faye");
- FayeWebSocket = rb_define_class_under(Faye, "WebSocket", rb_cObject);
- FayeWebSocketMask = rb_define_module_under(FayeWebSocket, "Mask");
+ FayeWebSocketMask = rb_define_module_under(Faye, "WebSocketMask");
rb_define_singleton_method(FayeWebSocketMask, "mask", method_faye_websocket_mask, 2);
}
View
6 faye-websocket.gemspec
@@ -15,11 +15,7 @@ Gem::Specification.new do |s|
Dir.glob("lib/**/*.rb") +
Dir.glob("{examples,spec}/**/*")
- if RUBY_PLATFORM =~ /java/
- s.platform = 'java'
- else
- s.extensions << "ext/faye_websocket_mask/extconf.rb"
- end
+ s.extensions << "ext/faye_websocket_mask/extconf.rb"
s.add_dependency "eventmachine", ">= 0.12.0"
View
15 lib/faye/websocket.rb
@@ -21,11 +21,18 @@ module Faye
class WebSocket
root = File.expand_path('../websocket', __FILE__)
-
+ require root + '/../../faye_websocket_mask'
+
if RUBY_PLATFORM =~ /java/
- autoload :Mask, root + '/mask'
- else
- require root + '/../../faye_websocket_mask'
+ require 'jruby'
+ com.jcoglan.faye.FayeWebsocketMaskService.new.basicLoad(JRuby.runtime)
+ end
+
+ unless WebSocketMask.respond_to?(:mask)
+ def WebSocketMask.mask(payload, mask)
+ @instance ||= new
+ @instance.mask(payload, mask)
+ end
end
unless String.instance_methods.include?(:force_encoding)
View
4 lib/faye/websocket/hybi_parser.rb
@@ -170,7 +170,7 @@ def frame(data, type = nil, code = nil)
if @masking
mask = [rand(256), rand(256), rand(256), rand(256)]
frame[header...offset] = mask
- buffer = Mask.mask(buffer, mask)
+ buffer = WebSocketMask.mask(buffer, mask)
end
frame.concat(buffer)
@@ -235,7 +235,7 @@ def parse_extended_length(buffer)
end
def emit_frame
- payload = @masked ? Mask.mask(@payload, @mask) : @payload
+ payload = @masked ? WebSocketMask.mask(@payload, @mask) : @payload
case @opcode
when OPCODES[:continuation] then
View
17 lib/faye/websocket/mask.rb
@@ -1,17 +0,0 @@
-# This file is only loaded and used when on JRuby, to avoid
-# depending on a C extension on that platform.
-
-module Faye
- class WebSocket
- module Mask
- def self.mask(payload, mask)
- unmasked = []
- payload.each_with_index do |byte, i|
- byte = byte ^ mask[i % 4] if mask.size > 0
- unmasked << byte
- end
- unmasked
- end
- end
- end
-end
Please sign in to comment.
Something went wrong with that request. Please try again.