├── .rvmrc ├── lib ├── rack-webconsole.rb └── rack │ ├── webconsole │ ├── version.rb │ ├── railtie.rb │ ├── sandbox.rb │ ├── shell.rb │ ├── asset_helpers.rb │ ├── assets.rb │ └── repl.rb │ └── webconsole.rb ├── public ├── jquery.html ├── webconsole.html ├── webconsole.css └── webconsole.js ├── .gitignore ├── Gemfile ├── spec ├── spec_helper.rb └── rack │ ├── webconsole │ ├── sandbox_spec.rb │ ├── asset_helpers_spec.rb │ ├── shell_spec.rb │ ├── assets_spec.rb │ └── repl_spec.rb │ └── webconsole_spec.rb ├── .travis.yml ├── Rakefile ├── Gemfile.lock ├── History ├── rack-webconsole.gemspec └── Readme.md /.rvmrc: -------------------------------------------------------------------------------- 1 | rvm --create use ruby-1.9.3@rack-webconsole 2 | -------------------------------------------------------------------------------- /lib/rack-webconsole.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | require 'rack' 3 | require 'rack/webconsole' 4 | -------------------------------------------------------------------------------- /public/jquery.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | pkg/* 4 | graph.png 5 | .yardoc/* 6 | doc/* 7 | coverage/* 8 | *.rbc 9 | tags 10 | -------------------------------------------------------------------------------- /lib/rack/webconsole/version.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | module Rack 3 | class Webconsole 4 | # rack-webconsole version number. 5 | VERSION = "0.1.4" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in rack-webconsole.gemspec 4 | gemspec 5 | gem 'rake' 6 | gem 'mocha' #, :git => 'git://github.com/floehopper/mocha.git' 7 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | gem 'minitest' 4 | require 'minitest/spec' 5 | require 'minitest/autorun' 6 | require 'purdytest' 7 | require 'mocha' 8 | 9 | require 'rack-webconsole' 10 | 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/travis-ci/travis-ci/wiki/.travis.yml-options 2 | rvm: 3 | - 1.8.7 # (current default) 4 | - 1.9.2 5 | - 1.9.3 6 | - ree 7 | - ruby-head 8 | - rbx-18mode 9 | - rbx-19mode 10 | -------------------------------------------------------------------------------- /public/webconsole.html: -------------------------------------------------------------------------------- 1 |
16 | -------------------------------------------------------------------------------- /lib/rack/webconsole/railtie.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | module Rack 3 | class Webconsole 4 | # Railtie loaded in Rails applications. Its purpose is to automatically use 5 | # the middleware in development environment, so that Rails users only have 6 | # to require 'rack-webconsole' in their Gemfile and nothing more than that. 7 | # 8 | class Railtie < Rails::Railtie 9 | initializer 'rack-webconsole.add_middleware' do |app| 10 | app.middleware.use Rack::Webconsole if Rails.env.development? 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | 4 | require 'rake/testtask' 5 | desc "Run rack-webconsole specs" 6 | Rake::TestTask.new do |t| 7 | t.libs << "spec" 8 | t.test_files = FileList['spec/**/*_spec.rb'] 9 | t.verbose = true 10 | end 11 | 12 | require 'yard' 13 | YARD::Rake::YardocTask.new(:docs) do |t| 14 | t.files = ['lib/**/*.rb'] 15 | t.options = ['-m', 'markdown', '--no-private', '-r', 'Readme.md', '--title', 'rack-webconsole documentation'] 16 | end 17 | task :doc => [:docs] 18 | 19 | desc "Generate and open class diagram (needs Graphviz installed)" 20 | task :graph do |t| 21 | `bundle exec yard graph -d --full --no-private | dot -Tpng -o graph.png && open graph.png` 22 | end 23 | task :default => [:test] 24 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | rack-webconsole (0.1.4) 5 | multi_json (~> 1.0.3) 6 | rack 7 | ripl (~> 0.5.1) 8 | ripl-multi_line (~> 0.3.0) 9 | 10 | GEM 11 | remote: http://rubygems.org/ 12 | specs: 13 | bluecloth (2.2.0) 14 | bond (0.4.1) 15 | metaclass (0.0.1) 16 | minitest (2.11.4) 17 | mocha (0.10.5) 18 | metaclass (~> 0.0.1) 19 | multi_json (1.0.4) 20 | purdytest (1.0.0) 21 | minitest (~> 2.2) 22 | rack (1.4.1) 23 | rake (0.9.2.2) 24 | ripl (0.5.1) 25 | bond (~> 0.4.0) 26 | ripl-multi_line (0.3.0) 27 | ripl (>= 0.3.6) 28 | yard (0.7.5) 29 | 30 | PLATFORMS 31 | ruby 32 | 33 | DEPENDENCIES 34 | bluecloth 35 | minitest 36 | mocha 37 | purdytest 38 | rack-webconsole! 39 | rake 40 | yard 41 | -------------------------------------------------------------------------------- /History: -------------------------------------------------------------------------------- 1 | === 0.1.4 / 2012-09-14 2 | 3 | + Prepend custom context to the route (Tobias Crawley) 4 | 5 | === 0.1.3 / 2012-03-22 6 | 7 | + Make keycode configurable (Roger Leite) 8 | + Switch to multi_json (Josh Buddy) 9 | ! Fix markup to make it work in more browsers 10 | 11 | === 0.1.2 / 2011-08-01 12 | 13 | + Change field name to avoid conflicts with other forms (Chris Apolzon) 14 | + Prevent visual flash of unstyled content (Rob Cameron) 15 | + Fix minor styling issues (Jeff Kreeftmeijer) 16 | + Avoid conflicts with libraries other than JQuery (Jo Liss) 17 | 18 | === 0.1.1 / 2011-07-27 19 | 20 | ! Fix bug with Content-Length not being calculated appropriately. (Corin Langosch) 21 | + Refactor JavaScript to avoid messing with prototypes (Corin Langosch) 22 | 23 | === 0.1.0 / 2011-07-27 24 | 25 | + The request object is now exposed in the console through #request method 26 | + Various UI enhancements 27 | ! Fix bug where Sandbox locals were much more than those defined by the user. 28 | 29 | === 0.0.5 / 2011-07-26 30 | 31 | ! Protection against CSRF attacks. 32 | -------------------------------------------------------------------------------- /lib/rack/webconsole/sandbox.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | module Rack 3 | class Webconsole 4 | # A sandbox to evaluate Ruby in. It is responsible for retrieving local 5 | # variables stored in `@locals`, and resetting the environment. 6 | # 7 | class Sandbox 8 | # Catches all the undefined local variables and tries to retrieve them 9 | # from `@locals`. If it doesn't find them, it falls back to the default 10 | # method missing behavior. 11 | def method_missing(method, *args, &block) 12 | @locals ||= {} 13 | @locals[method.to_sym] || super(method, *args, &block) 14 | end 15 | 16 | # Makes the console use a fresh, new {Sandbox} with all local variables 17 | # resetted. 18 | # 19 | # @return [String] 'ok' to make the user notice. 20 | def reload! 21 | $sandbox = Sandbox.new 22 | 'ok' 23 | end 24 | 25 | # Returns the current page request object for inspection purposes. 26 | # 27 | # @return [Rack::Request] the current page request object. 28 | def request 29 | Webconsole::Repl.request 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/rack/webconsole/sandbox_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Rack 4 | describe Webconsole::Sandbox do 5 | 6 | describe "#method_missing" do 7 | describe 'when the method exists in @locals' do 8 | it 'retrieves it' do 9 | @sandbox = Webconsole::Sandbox.new 10 | @sandbox.instance_variable_set(:@locals, {:a => 123}) 11 | 12 | @sandbox.a.must_equal 123 13 | end 14 | end 15 | describe 'otherwise' do 16 | it 'raises a NoMethodError' do 17 | @sandbox = Webconsole::Sandbox.new 18 | 19 | lambda { 20 | @sandbox.a 21 | }.must_raise NoMethodError 22 | end 23 | end 24 | end 25 | 26 | describe "#reload!" do 27 | it 'assigns a new, fresh Sandbox to the global variable' do 28 | old_sandbox = $sandbox = Webconsole::Sandbox.new 29 | 30 | $sandbox.reload! 31 | 32 | $sandbox.wont_equal old_sandbox 33 | end 34 | it 'returns a feedback string' do 35 | Webconsole::Sandbox.new.reload!.must_equal 'ok' 36 | end 37 | end 38 | 39 | describe "request" do 40 | it 'returns the request object' do 41 | @sandbox = Webconsole::Sandbox.new 42 | request = Rack::Request.new({'PATH_INFO' => '/some_path'}) 43 | Webconsole::Repl.request = request 44 | 45 | @sandbox.request.must_equal request 46 | end 47 | end 48 | 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /rack-webconsole.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "rack/webconsole/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "rack-webconsole" 7 | s.version = Rack::Webconsole::VERSION 8 | s.authors = ["Josep M. Bach", "Josep Jaume Rey", "Oriol Gual"] 9 | s.email = ["info@codegram.com"] 10 | s.homepage = "http://github.com/codegram/rack-webconsole" 11 | s.summary = %q{Rack-based console inside your web applications} 12 | s.description = %q{Rack-based console inside your web applications} 13 | 14 | s.rubyforge_project = "rack-webconsole" 15 | 16 | s.add_runtime_dependency 'rack' 17 | s.add_runtime_dependency 'multi_json', '>= 1.0.3', '~> 1.0' 18 | s.add_runtime_dependency 'ripl', '~> 0.5.1' 19 | s.add_runtime_dependency 'ripl-multi_line', '~> 0.3.0' 20 | 21 | s.add_development_dependency 'minitest' 22 | s.add_development_dependency 'purdytest' 23 | 24 | # Since we can't have a git dependency in gemspec, we specify this 25 | # dependency directly in the Gemfile. Once a new mocha version is released, 26 | # we should uncomment this line and remove mocha from the Gemfile. 27 | # s.add_development_dependency 'mocha' 28 | 29 | s.add_development_dependency 'yard' 30 | s.add_development_dependency 'bluecloth' 31 | s.add_development_dependency 'rake' 32 | 33 | s.files = `git ls-files`.split("\n") 34 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 35 | s.require_paths = ["lib"] 36 | end 37 | -------------------------------------------------------------------------------- /spec/rack/webconsole/asset_helpers_spec.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | require 'spec_helper' 3 | 4 | class AssetClass 5 | include Rack::Webconsole::AssetHelpers 6 | end 7 | 8 | module Rack 9 | describe Webconsole::AssetHelpers do 10 | 11 | describe '#html_code' do 12 | it 'loads the html code' do 13 | asset_class = AssetClass.new 14 | html = asset_class.html_code 15 | 16 | html.must_match /console/ 17 | html.must_match /results/ 18 | html.must_match /form/ 19 | end 20 | end 21 | 22 | describe '#css_code' do 23 | it 'loads the css code' do 24 | asset_class = AssetClass.new 25 | css = asset_class.css_code 26 | 27 | css.must_match /' 34 | end 35 | 36 | # Loads the JavaScript from a file in `/public`. 37 | # 38 | # It contains the JavaScript logic of the webconsole. 39 | # 40 | # @return [String] the injectable JavaScript. 41 | def js_code 42 | '' 45 | end 46 | 47 | # Inteprolates the given variables inside the javascrpt code 48 | # 49 | # @param [String] javascript The javascript code to insert the variables 50 | # @param [Hash] variables A hash containing the variables names (as keys) 51 | # and its values 52 | # 53 | # @return [String] the javascript code with the interpolated variables 54 | def render(javascript, variables = {}) 55 | javascript_with_variables = javascript.dup 56 | variables.each_pair do |variable, value| 57 | javascript_with_variables.gsub!("$#{variable}", value) 58 | end 59 | javascript_with_variables 60 | end 61 | 62 | private 63 | 64 | def asset(file) 65 | @assets ||= {} 66 | output = ::File.open(::File.join(::File.dirname(__FILE__), '..', '..', '..', 'public', file), 'r:UTF-8') do |f| 67 | f.read 68 | end 69 | @assets[file] ||= output 70 | end 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /lib/rack/webconsole/assets.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | module Rack 3 | class Webconsole 4 | # {Assets} is a Rack middleware responsible for injecting view code for the 5 | # console to work properly. 6 | # 7 | # It intercepts HTTP requests, detects successful HTML responses and 8 | # injects HTML, CSS and JavaScript code into those. 9 | # 10 | class Assets 11 | include Webconsole::AssetHelpers 12 | 13 | # Honor the Rack contract by saving the passed Rack application in an ivar. 14 | # 15 | # @param [Rack::Application] app the previous Rack application in the 16 | # middleware chain. 17 | def initialize(app) 18 | @app = app 19 | end 20 | 21 | # Checks for successful HTML responses and injects HTML, CSS and 22 | # JavaScript code into them. 23 | # 24 | # @param [Hash] env a Rack request environment. 25 | def call(env) 26 | status, headers, response = @app.call(env) 27 | return [status, headers, response] unless check_html?(headers, response) && status == 200 28 | 29 | response_body = full_body(response) 30 | 31 | # Regenerate the security token 32 | Webconsole::Repl.reset_token 33 | 34 | # Expose the request object to the Repl 35 | Webconsole::Repl.request = Rack::Request.new(env) 36 | 37 | # Inject the html, css and js code to the view 38 | response_body.gsub!('