request_visualizer 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +10 -0
- data/Gemfile.lock +68 -0
- data/README +0 -0
- data/lib/request_visualizer.rb +70 -0
- data/lib/request_visualizer/version.rb +3 -0
- data/request_visualizer.gemspec +20 -0
- data/spec/sample.rb +93 -0
- data/spec/spec.rb +29 -0
- metadata +87 -0
data/Gemfile
ADDED
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,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
|