-
-
Save igrigorik/675667 to your computer and use it in GitHub Desktop.
require 'rubygems' | |
require 'rack' | |
class Object | |
def webapp | |
class << self | |
define_method :call do |env| | |
func, *attrs = env['PATH_INFO'].split('/').reject(&:empty?) | |
[200, {}, send(func, *attrs)] | |
end | |
end | |
self | |
end | |
end | |
Rack::Handler::Mongrel.run [].webapp, :Port => 9292 | |
# ^^^^^^^^^^^ | |
# | (x) | |
# ROFLSCALE DB ---/ | |
# | |
# http://localhost:9292/push/1 -> 1 | |
# http://localhost:9292/push/2 -> 12 | |
# http://localhost:9292/push/3 -> 123 | |
# http://localhost:9292/to_a -> 123 | |
# http://localhost:9292/pop -> 3 | |
# http://localhost:9292/shift -> 1 | |
# Implementations in other languages (thanks guys!): | |
# Node.js: https://gist.github.com/700995 | |
# Groovy: https://gist.github.com/702337 | |
# Python: https://gist.github.com/702001 | |
# Perl w/ plack: https://gist.github.com/703620 | |
# Perl w/ continuity: https://gist.github.com/703651 | |
# Io: https://gist.github.com/703431 | |
# Great explanation of how this works in Ruby on Stackoverflow: | |
# http://stackoverflow.com/questions/4198883/exposing-any-ruby-object-over-the-web |
J2EE version at http://bit.ly/YjoRf
@JamieFlournoy
Damnit.
@JamieFlournoy J2EE had these kind of security feature a long time ago if i remember correctly the spring bean introspector feature(http://www.springsource.com/security/cve-2010-1622) and it was more lines of code, so better
RickRoll spoiler: Don't click on the trollish "J2EE version" link from @JamieFlournoy
Seriously, the roflcopter is amazing.
Here's a groovy version: https://gist.github.com/702337
what about this hehehe:
class Object
DANGEROUS_METHODS = methods.grep(/eval|instance|module|method|send|taint|extend|include|freeze/)
def webapp
class << self
define_method :call do |env|
func, *attrs = env['PATH_INFO'].split('/').reject(&:empty?)
result = DANGEROUS_METHODS.include?(func) ? 'METHOD NOT ALLOWED' : send(func, *attrs).to_s
[200, {}, [result]]
end
end
self
end
end
@rafmagana
`
alias (unsure)
It should be a whitelist instead of black list, I believe.
mmm, well, yes, it might be, the only thing is that we'd need an ALLOWED_METHODS per class or something like that, I mean, I wouldn't do the following in the Object class:
ALLOWED_METHODS = w%[a lot of methods of different classes]
well, I don't know, maybe, hehe
Might take some inspiration from this to make it actually possible to expose objects as Rack endpoints in Grape...still thinking of how to make it work exactly.
$SAFE = 1 would disable a lot of the nastier methods. You'd still have to undef them in JRuby, though.
woow ROaaS = Ruby Objects as a Service hehehe
ROFLSCALE! \m/
Rack::ObjectApp
- https://gist.github.com/701304#file_object_app.rb
Enjoy. :)
@Oshuma: Nice! :-)
nice!
Very nice. Here are some implementations I did in Perl & Io:
https://gist.github.com/703620 - Perl using plack
https://gist.github.com/703651 - Perl using Continuity
https://gist.github.com/703431 - Io
@draegtun: awesome, thanks! Added your gist links to the one above.
Hello, this is really great but there are some things I am not really sure. For instance, I cannot get the object class with http://localhost:9292/class.
After:
http://localhost:9292/push/1 -> 1
http://localhost:9292/push/2 -> 12
http://localhost:9292/push/3 -> 123
http://localhost:9292/to_a -> 123
I would expect
http://localhost:9292/class -> Array
Sorry if I'm wrong, just trying to understand :)
Regards,
Luc
Luc, you have to be careful with your version of Ruby. Rack expects an object on which you can call "each". Under Ruby 1.9, String does not have an .each method. Chances are, Rack is erroring out because of that. A simple workaround would be wrap every returned object into a "StringIO.new(send(...).to_s))".
Hello,
Hmm, sounds strange. In fact I'm using Ruby 1.8.7
luc@venus:~/Projects/rubyobject ruby --version
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
Should it work with this version ?
Thanks a lot for your help.
Regards,
Luc
Yep, 1.8.7 should work. What does your console output when you run the server and make that request?
hmmm, you'r right, it's talking about the each method... but I'm running ruby 1.8.7
config.ru:1:in new' config.ru:1 Wed Nov 24 16:03:46 +0100 2010: Read error: #<NoMethodError: undefined method
each' for Array:Class>
/Library/Ruby/Gems/1.8/gems/rack-1.2.1/lib/rack/chunked.rb:37:in each' /Library/Ruby/Gems/1.8/gems/rack-1.2.1/lib/rack/handler/mongrel.rb:80:in
process'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:in process_client' /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in
each'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `process_cli
Right, you're seeing the problem I described below. You need to convert everything to a StringIO and then you're good to go.
So I updated it a bit in my fork; it removes url encoding and returns json serialization of results
@danny: nice!
How come you didn’t settle with def self.call(env)
instead?
require 'rack'
class Object
def to_webapp
def self.call(env)
func, *attrs = env['PATH_INFO'].split('/').reject(&:empty?)
[200, {}, send(func || :inspect, *attrs)]
end
self
end
end
Rack::Handler::WEBrick.run [].to_webapp, :Port => 9292
node.js version woo https://gist.github.com/700995