request_visualizer 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'ey_api_hmac', '>= 0.4.0'
7
+ gem "sinatra"
8
+ gem 'rspec'
9
+ gem 'capybara'
10
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,68 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ request_visualizer (0.0.1)
5
+ colored
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ capybara (1.1.2)
11
+ mime-types (>= 1.16)
12
+ nokogiri (>= 1.3.3)
13
+ rack (>= 1.0.0)
14
+ rack-test (>= 0.5.4)
15
+ selenium-webdriver (~> 2.0)
16
+ xpath (~> 0.1.4)
17
+ childprocess (0.3.1)
18
+ ffi (~> 1.0.6)
19
+ colored (1.2)
20
+ diff-lcs (1.1.3)
21
+ ey_api_hmac (0.4.4)
22
+ json
23
+ rack-client
24
+ rack-idempotent (>= 0.0.3)
25
+ ffi (1.0.11)
26
+ json (1.6.5)
27
+ mime-types (1.17.2)
28
+ multi_json (1.1.0)
29
+ nokogiri (1.5.2)
30
+ rack (1.4.1)
31
+ rack-client (0.4.0)
32
+ rack (>= 1.0.0)
33
+ rack-idempotent (0.0.3)
34
+ rack-protection (1.2.0)
35
+ rack
36
+ rack-test (0.6.1)
37
+ rack (>= 1.0)
38
+ rspec (2.8.0)
39
+ rspec-core (~> 2.8.0)
40
+ rspec-expectations (~> 2.8.0)
41
+ rspec-mocks (~> 2.8.0)
42
+ rspec-core (2.8.0)
43
+ rspec-expectations (2.8.0)
44
+ diff-lcs (~> 1.1.2)
45
+ rspec-mocks (2.8.0)
46
+ rubyzip (0.9.6.1)
47
+ selenium-webdriver (2.20.0)
48
+ childprocess (>= 0.2.5)
49
+ ffi (~> 1.0)
50
+ multi_json (~> 1.0)
51
+ rubyzip
52
+ sinatra (1.3.2)
53
+ rack (~> 1.3, >= 1.3.6)
54
+ rack-protection (~> 1.2)
55
+ tilt (~> 1.3, >= 1.3.3)
56
+ tilt (1.3.3)
57
+ xpath (0.1.4)
58
+ nokogiri (~> 1.3)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ capybara
65
+ ey_api_hmac (>= 0.4.0)
66
+ request_visualizer!
67
+ rspec
68
+ sinatra
data/README ADDED
File without changes
@@ -0,0 +1,70 @@
1
+ require 'colored'
2
+ class RequestVisualizer
3
+ def initialize(app, &lookup)
4
+ @app = app
5
+ @lookup = lookup
6
+ end
7
+
8
+ def parse(string)
9
+ colorize((@lookup && @lookup.call(string.to_s)) || string.to_s)
10
+ end
11
+
12
+ def colorize(string)
13
+ @@colors ||= [:black_on_cyan, :black_on_magenta, :black_on_yellow, :black_on_green]
14
+ @@colorized_before ||= {}
15
+ @@colorized_before[string] ||= string.send(@@colors.pop || :black_on_white)
16
+ @@colorized_before[string]
17
+ end
18
+
19
+ def indent
20
+ " "*@@indent
21
+ end
22
+
23
+ def log_request(request)
24
+ from = parse(request.user_agent.to_s)
25
+ to = parse(request.url.to_s)
26
+ puts "#{self.indent}#{from} -> #{request.request_method.upcase.bold} (#{request.url.underline}) -> #{to}"
27
+ request.body.rewind
28
+ req_body = request.body.read
29
+ begin
30
+ json = JSON.parse(req_body)
31
+ indent_prefix = self.indent
32
+ puts indent_prefix + json.pretty_inspect.gsub("\n","\n#{indent_prefix}")
33
+ rescue => e
34
+ # puts "WARN: JSON request with non-json body! (#{req_body})"
35
+ end
36
+ request.body.rewind
37
+ [from, to]
38
+ end
39
+
40
+ def log_response(from, to, headers, body, status)
41
+ location = headers["Location"]
42
+ if location
43
+ puts "#{self.indent}#{from} <--#{status}-- #{location.underline} <- #{to}"
44
+ else
45
+ puts "#{self.indent}#{from} <--#{status}-- #{to}"
46
+ end
47
+ do_inspect = true
48
+ if headers["Content-Type"].to_s.match(/json/) && do_inspect
49
+ body.each do |bod|
50
+ begin
51
+ json = JSON.parse(bod)
52
+ indent_prefix = self.indent
53
+ puts indent_prefix + json.pretty_inspect.gsub("\n","\n#{indent_prefix}")
54
+ rescue => e
55
+ puts "WARN: JSON response with non-json body! (#{bod})"
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ def call(env)
62
+ @@indent ||= 0
63
+ @@indent += 5
64
+ from, to = log_request(Rack::Request.new(env))
65
+ status, headers, body = @app.call(env)
66
+ log_response(from, to, headers, body, status)
67
+ @@indent -= 5
68
+ [status, headers, body]
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ class RequestVisualizer
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "request_visualizer/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "request_visualizer"
7
+ s.version = RequestVisualizer::VERSION
8
+ s.authors = ["Jacob Burkhart"]
9
+ s.email = ["jacob@engineyard.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Rack middleware for visualizing HTTP/JSON requests}
12
+ s.description = %q{Rack middleware for visualizing HTTP/JSON requests, and stuff}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency 'colored'
20
+ end
data/spec/sample.rb ADDED
@@ -0,0 +1,93 @@
1
+ require 'ey_api_hmac'
2
+ class Connection < EY::ApiHMAC::BaseConnection
3
+
4
+ def initialize(user_agent, app)
5
+ super(user_agent)
6
+ self.backend = app
7
+ end
8
+
9
+ def get(url)
10
+ super(url) do |json_body, location|
11
+ json_body
12
+ end
13
+ end
14
+
15
+ def post(url, params)
16
+ super(url, params) do |json_body, location|
17
+ json_body
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ require 'sinatra/base'
24
+ class Service < Sinatra::Base
25
+ enable :raise_errors
26
+ disable :dump_errors
27
+ disable :show_exceptions
28
+
29
+ def conn
30
+ @conn ||= Connection.new(self.class.to_s, Capybara.app)
31
+ end
32
+ end
33
+
34
+ class Lookup
35
+ def self.services
36
+ @services ||= {}
37
+ end
38
+
39
+ def self.lookup(service_url)
40
+ services.each do |base_url, service|
41
+ if service_url.match base_url
42
+ return service.to_s
43
+ end
44
+ end
45
+ service_url
46
+ end
47
+
48
+ end
49
+
50
+ class SandwhichMaker < Service
51
+ BASE_URL = "https://sandwhichmaker.example.com/"
52
+ Lookup.services[BASE_URL] = self
53
+
54
+ get "/" do
55
+ bread = conn.get("#{Baker::BASE_URL}get_loaf")
56
+ conn.post("#{BreadSlicer::BASE_URL}slice", {:bread_url => bread["url"]})
57
+ content_type "application/json"
58
+ {:sandwhich => true}.to_json
59
+ end
60
+
61
+ end
62
+
63
+ class BreadSlicer < Service
64
+ BASE_URL = "https://breadslicer.example.com/"
65
+ Lookup.services[BASE_URL] = self
66
+
67
+ post "/slice" do
68
+ post_body = JSON.parse(request.body.read)
69
+ bread = conn.get(post_body["bread_url"])
70
+ content_type "application/json"
71
+ {:slices => ["heel","slice","slice","slice","heel"]}.to_json
72
+ end
73
+
74
+ end
75
+
76
+ class Baker < Service
77
+ BASE_URL = "https://bakery.example.com/"
78
+ Lookup.services[BASE_URL] = self
79
+
80
+ get "/loaves/1" do
81
+ content_type "application/json"
82
+ {:type => "sourdough"}.to_json
83
+ end
84
+
85
+ get "/get_loaf" do
86
+ content_type "application/json"
87
+ {:url => "#{BASE_URL}loaves/1"}.to_json
88
+ end
89
+
90
+ end
91
+
92
+
93
+
data/spec/spec.rb ADDED
@@ -0,0 +1,29 @@
1
+ require File.expand_path("../sample", __FILE__)
2
+ require 'request_visualizer'
3
+ require 'capybara/rspec'
4
+
5
+ RSpec.configure do |config|
6
+ config.include(Capybara::RSpecMatchers)
7
+ config.include(Capybara::DSL)
8
+ end
9
+
10
+ describe "things" do
11
+ before do
12
+ Capybara.app = Rack::Builder.new do
13
+ use RequestVisualizer do |string|
14
+ Lookup.lookup(string.to_s)
15
+ end
16
+ Lookup.services.each do |url, service|
17
+ map url do
18
+ run service
19
+ end
20
+ end
21
+ end
22
+ page.driver.header 'User-Agent', "Capybara"
23
+ end
24
+
25
+ it "makes a sandwhich" do
26
+ visit SandwhichMaker::BASE_URL
27
+ end
28
+
29
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: request_visualizer
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Jacob Burkhart
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-16 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: colored
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: Rack middleware for visualizing HTTP/JSON requests, and stuff
35
+ email:
36
+ - jacob@engineyard.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - Gemfile
45
+ - Gemfile.lock
46
+ - README
47
+ - lib/request_visualizer.rb
48
+ - lib/request_visualizer/version.rb
49
+ - request_visualizer.gemspec
50
+ - spec/sample.rb
51
+ - spec/spec.rb
52
+ homepage: ""
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options: []
57
+
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ requirements: []
79
+
80
+ rubyforge_project:
81
+ rubygems_version: 1.8.10
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Rack middleware for visualizing HTTP/JSON requests
85
+ test_files:
86
+ - spec/sample.rb
87
+ - spec/spec.rb