proxie 0.1.1
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/README.rdoc +42 -0
- data/Rakefile +3 -0
- data/bin/proxie +49 -0
- data/lib/proxie.rb +8 -0
- data/lib/proxie/logger.rb +40 -0
- data/lib/proxie/proxie.rb +22 -0
- data/lib/proxie/server.rb +54 -0
- data/lib/proxie/version.rb +3 -0
- data/lib/proxie/web.rb +94 -0
- metadata +122 -0
data/README.rdoc
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
= Proxie: HTTP proxy and debugging tool
|
|
2
|
+
|
|
3
|
+
Proxie allows you to setup HTTP proxy server on specified port, filter traffic by type, store information into SQLite3 database.
|
|
4
|
+
Databases web access is powered by Sinatra web framework.
|
|
5
|
+
|
|
6
|
+
= Installation
|
|
7
|
+
|
|
8
|
+
gem install proxie
|
|
9
|
+
|
|
10
|
+
= Usage
|
|
11
|
+
|
|
12
|
+
Just type 'proxie' in your terminal and proxy server will be spawned.
|
|
13
|
+
For additional information type:
|
|
14
|
+
|
|
15
|
+
proxie --help
|
|
16
|
+
|
|
17
|
+
Output:
|
|
18
|
+
|
|
19
|
+
Usage: proxie [options]
|
|
20
|
+
-i, --info Display this information.
|
|
21
|
+
-p, --port PORT Listen on port (8080 default)
|
|
22
|
+
-d, --db NAME Store results to database
|
|
23
|
+
-w, --web Start a Web UI for databases
|
|
24
|
+
-f, --flush Delete all local databases
|
|
25
|
+
|
|
26
|
+
= Examples
|
|
27
|
+
|
|
28
|
+
Setup proxy server on port 9090 and write all http data into 'sample' database
|
|
29
|
+
|
|
30
|
+
proxie -p 9090 -d sample
|
|
31
|
+
|
|
32
|
+
Activate web interface (localhost:4567/):
|
|
33
|
+
|
|
34
|
+
proxie --web
|
|
35
|
+
|
|
36
|
+
Remove all existing databases:
|
|
37
|
+
|
|
38
|
+
proxie --flush
|
|
39
|
+
|
|
40
|
+
= Credits
|
|
41
|
+
|
|
42
|
+
* Dan Sosedoff - http://github.com/sosedoff
|
data/Rakefile
ADDED
data/bin/proxie
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
|
5
|
+
|
|
6
|
+
require 'rubygems'
|
|
7
|
+
require 'sequel'
|
|
8
|
+
require 'optparse'
|
|
9
|
+
require 'cgi'
|
|
10
|
+
require 'proxie'
|
|
11
|
+
|
|
12
|
+
Proxie.init
|
|
13
|
+
|
|
14
|
+
options = {
|
|
15
|
+
:port => 8080,
|
|
16
|
+
:db => "db_#{Time.now.to_i}",
|
|
17
|
+
:listen => true
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
optparse = OptionParser.new do |opts|
|
|
21
|
+
opts.banner = "Proxie v#{Proxie::VERSION}\nUsage: proxie [options]"
|
|
22
|
+
opts.on('-i', '--info', 'Display this information.') { puts opts; exit }
|
|
23
|
+
opts.on('-p', '--port PORT', 'Listen on port') { |v| options[:port] = v }
|
|
24
|
+
opts.on('-d', '--db NAME', 'Store results to database') { |v| options[:db] = v }
|
|
25
|
+
opts.on('-w', '--web', 'Start a Web UI for databases') { options[:listen] = false }
|
|
26
|
+
opts.on('-f', '--flush', 'Delete all local databases') do
|
|
27
|
+
puts "Deleting databases..."
|
|
28
|
+
Dir.glob("#{Proxie.root}/*.sqlite").each do |f|
|
|
29
|
+
puts "-> #{File.basename(f)} : #{File.delete(f)}"
|
|
30
|
+
end
|
|
31
|
+
exit
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
begin
|
|
36
|
+
optparse.parse!
|
|
37
|
+
if options[:listen]
|
|
38
|
+
server = Proxie::Server.new(options[:port])
|
|
39
|
+
server.logger = Proxie::SQLiteLogger.new("#{Proxie.root}/#{options[:db]}.sqlite")
|
|
40
|
+
trap("INT") { server.stop }
|
|
41
|
+
server.start
|
|
42
|
+
end
|
|
43
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
|
44
|
+
puts optparse
|
|
45
|
+
rescue RuntimeError => err
|
|
46
|
+
puts "ERROR: #{err.message}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
require 'proxie/web' if !options[:listen]
|
data/lib/proxie.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Proxie
|
|
2
|
+
class Logger
|
|
3
|
+
def packet(req, resp)
|
|
4
|
+
# DEFAULT LOGGER IS NOT IMPLEMENTED YET
|
|
5
|
+
# OVERRIDE!
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class SQLiteLogger < Logger
|
|
10
|
+
attr_reader :db, :records
|
|
11
|
+
|
|
12
|
+
# Initialize SQLite3 logger
|
|
13
|
+
def initialize(path, overwrite=true)
|
|
14
|
+
raise 'Database file with this name already exists!' if File.exists?(path) && !overwrite
|
|
15
|
+
File.delete(path) if File.exists?(path)
|
|
16
|
+
|
|
17
|
+
@db = Sequel.sqlite(path)
|
|
18
|
+
@db.create_table :requests do
|
|
19
|
+
primary_key :id
|
|
20
|
+
string :request_headers
|
|
21
|
+
string :request_url
|
|
22
|
+
string :request_body
|
|
23
|
+
string :response_headers
|
|
24
|
+
string :response_body
|
|
25
|
+
end
|
|
26
|
+
@records = @db[:requests]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Save request and response data
|
|
30
|
+
def packet(req, resp)
|
|
31
|
+
@records.insert(
|
|
32
|
+
:request_headers => req.header.to_json,
|
|
33
|
+
:request_url => req.request_line,
|
|
34
|
+
:request_body => req.body.inspect,
|
|
35
|
+
:response_headers => resp.header.to_json,
|
|
36
|
+
:response_body => resp.body.inspect
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Proxie
|
|
2
|
+
# Regular expression to detect static
|
|
3
|
+
REGEX_DEFAULT = /\.(png|jpeg|jpg|gif|ico|css|swf)/i
|
|
4
|
+
|
|
5
|
+
# Regular expression to detect javascripts
|
|
6
|
+
REGEX_JS = /\.js/i
|
|
7
|
+
|
|
8
|
+
# Regular expression to detect html
|
|
9
|
+
REGEX_HTML = /(<html>|<body>)/i
|
|
10
|
+
|
|
11
|
+
# Get user work dir
|
|
12
|
+
def self.root
|
|
13
|
+
"#{ENV['HOME']}/.proxie"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Setup Proxie work dir
|
|
17
|
+
def self.init
|
|
18
|
+
unless File.exists?(root) && File.directory?(root)
|
|
19
|
+
Dir.mkdir(root)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Proxie
|
|
2
|
+
class Server
|
|
3
|
+
attr_reader :port
|
|
4
|
+
attr_reader :options
|
|
5
|
+
attr_reader :logger
|
|
6
|
+
|
|
7
|
+
# Initialize server instance
|
|
8
|
+
# Options:
|
|
9
|
+
# :default => true Skip static filess like images, stylesheets, swf, etc
|
|
10
|
+
# :html => true Skip if html in body
|
|
11
|
+
# :js => true Skip javascripts
|
|
12
|
+
def initialize(port=8080, args={})
|
|
13
|
+
@options = {
|
|
14
|
+
:default => args[:default] || true,
|
|
15
|
+
:js => args[:js] || true,
|
|
16
|
+
:images => args[:images] || true
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@server = WEBrick::HTTPProxyServer.new(
|
|
20
|
+
:Port => port,
|
|
21
|
+
:AccessLog => [],
|
|
22
|
+
:ProxyContentHandler => Proc.new { |req, resp| process(req, resp) }
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Setup traffic logger
|
|
27
|
+
def logger=(obj)
|
|
28
|
+
raise ArgumentError, 'Logger required!' if obj.nil?
|
|
29
|
+
raise ArgumentError, 'Logger method [packet] is not defined!' unless obj.respond_to?(:packet)
|
|
30
|
+
@logger = obj
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Start proxy server
|
|
34
|
+
def start
|
|
35
|
+
raise RuntimeError, 'Logger is not defined!' if @logger.nil?
|
|
36
|
+
@server.start
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Stop proxy server
|
|
40
|
+
def stop
|
|
41
|
+
@server.shutdown
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
# Log traffic request-response sequence
|
|
47
|
+
def process(req, resp)
|
|
48
|
+
return if @options[:default] && req.request_line.match(REGEX_DEFAULT)
|
|
49
|
+
return if @options[:js] && req.request_line.match(REGEX_JS)
|
|
50
|
+
return if @options[:html] && resp.body.match(REGEX_HTML)
|
|
51
|
+
@logger.packet(req, resp)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/proxie/web.rb
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'sinatra'
|
|
3
|
+
|
|
4
|
+
enable :run
|
|
5
|
+
set :logging, false
|
|
6
|
+
set :dump_errors, false
|
|
7
|
+
|
|
8
|
+
get '/' do
|
|
9
|
+
@files = Dir.glob("#{Proxie.root}/*.sqlite").map do |f|
|
|
10
|
+
{:name => File.basename(f), :size => File.size(f) / 1024 }
|
|
11
|
+
end
|
|
12
|
+
erb :index
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
get '/db/:name' do
|
|
16
|
+
db = Sequel.sqlite("#{Proxie.root}/#{params[:name]}")
|
|
17
|
+
@rows = db[:requests].all
|
|
18
|
+
erb :records
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
__END__
|
|
22
|
+
|
|
23
|
+
@@ layout
|
|
24
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
25
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
26
|
+
<head>
|
|
27
|
+
<title>Proxie Web</title>
|
|
28
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
29
|
+
<style>
|
|
30
|
+
html { background: #e5e5e5; }
|
|
31
|
+
body { background: transparent; font:13px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; position: relative; }
|
|
32
|
+
.wrapper { padding: 10px; }
|
|
33
|
+
h1 { border-bottom: 2px solid #ccc; }
|
|
34
|
+
.db { padding: 2px 0px; }
|
|
35
|
+
.db span { font-color: #555; font-size: 11px; }
|
|
36
|
+
.req { background: #fff; border: 1px solid #ccc; margin-bottom: 8px; }
|
|
37
|
+
.req .url { padding: 4px; background: #f1f1f1; }
|
|
38
|
+
.req pre { padding: 4px; white-space: normal; overflow-x: auto; }
|
|
39
|
+
table.headers { }
|
|
40
|
+
table.headers td { border-collapse: 0px; padding: 2px; border-right: 1px solid #ccc; border-bottom: 1px solid #ccc; }
|
|
41
|
+
</style>
|
|
42
|
+
</head>
|
|
43
|
+
<body>
|
|
44
|
+
<div class="wrapper">
|
|
45
|
+
<h1>Proxie v<%= Proxie::VERSION %></h1>
|
|
46
|
+
<%= yield %>
|
|
47
|
+
</div>
|
|
48
|
+
</body>
|
|
49
|
+
</html>
|
|
50
|
+
|
|
51
|
+
@@ index
|
|
52
|
+
<h2>Your databases:</h2>
|
|
53
|
+
<% unless @files.empty? %>
|
|
54
|
+
<% @files.each do |f| %>
|
|
55
|
+
<div class="db">
|
|
56
|
+
<a href="/db/<%= f[:name] %>"><%= f[:name] %></a> -
|
|
57
|
+
<span><%= f[:size] %> Kb</span>
|
|
58
|
+
</div>
|
|
59
|
+
<% end %>
|
|
60
|
+
<% else %>
|
|
61
|
+
<p>You dont have any databases yet.</p>
|
|
62
|
+
<% end %>
|
|
63
|
+
|
|
64
|
+
@@records
|
|
65
|
+
<h2><a href="/">Databases</a> :: <%= params[:name] %></h2>
|
|
66
|
+
<% @rows.each do |r| %>
|
|
67
|
+
<div class="req">
|
|
68
|
+
<div class="url"><%= r[:id] %>. <%= r[:request_url] %></div>
|
|
69
|
+
<pre>
|
|
70
|
+
<b>Request Headers:</b><br/>
|
|
71
|
+
<table class="headers">
|
|
72
|
+
<% JSON.parse(r[:request_headers]).each_pair do |k,v| %>
|
|
73
|
+
<tr>
|
|
74
|
+
<td><%= k %></td>
|
|
75
|
+
<td><%= v %></td>
|
|
76
|
+
</tr>
|
|
77
|
+
<% end %>
|
|
78
|
+
</table>
|
|
79
|
+
</pre>
|
|
80
|
+
<pre><b>Request Body:</b><%= r[:request_body] %></pre>
|
|
81
|
+
<pre>
|
|
82
|
+
<b>Request Headers:</b><br/>
|
|
83
|
+
<table class="headers">
|
|
84
|
+
<% JSON.parse(r[:response_headers]).each_pair do |k,v| %>
|
|
85
|
+
<tr>
|
|
86
|
+
<td><%= k %></td>
|
|
87
|
+
<td><%= v %></td>
|
|
88
|
+
</tr>
|
|
89
|
+
<% end %>
|
|
90
|
+
</table>
|
|
91
|
+
</pre>
|
|
92
|
+
<pre><b>Response Body:</b><br/><%= r[:response_body] %></pre>
|
|
93
|
+
</div>
|
|
94
|
+
<% end %>
|
metadata
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: proxie
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 25
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
- 1
|
|
10
|
+
version: 0.1.1
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Dan Sosedoff
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-01-25 00:00:00 -06:00
|
|
19
|
+
default_executable: proxie
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: sinatra
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 51
|
|
30
|
+
segments:
|
|
31
|
+
- 0
|
|
32
|
+
- 9
|
|
33
|
+
- 4
|
|
34
|
+
version: 0.9.4
|
|
35
|
+
type: :runtime
|
|
36
|
+
version_requirements: *id001
|
|
37
|
+
- !ruby/object:Gem::Dependency
|
|
38
|
+
name: sequel
|
|
39
|
+
prerelease: false
|
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - "="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
hash: 75
|
|
46
|
+
segments:
|
|
47
|
+
- 3
|
|
48
|
+
- 19
|
|
49
|
+
- 0
|
|
50
|
+
version: 3.19.0
|
|
51
|
+
type: :runtime
|
|
52
|
+
version_requirements: *id002
|
|
53
|
+
- !ruby/object:Gem::Dependency
|
|
54
|
+
name: json
|
|
55
|
+
prerelease: false
|
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - "="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
hash: 11
|
|
62
|
+
segments:
|
|
63
|
+
- 1
|
|
64
|
+
- 4
|
|
65
|
+
- 6
|
|
66
|
+
version: 1.4.6
|
|
67
|
+
type: :runtime
|
|
68
|
+
version_requirements: *id003
|
|
69
|
+
description: Proxie is a HTTP proxy server with sqlite-powered storage and web interface for debugging.
|
|
70
|
+
email: dan.sosedoff@gmail.com
|
|
71
|
+
executables:
|
|
72
|
+
- proxie
|
|
73
|
+
extensions: []
|
|
74
|
+
|
|
75
|
+
extra_rdoc_files: []
|
|
76
|
+
|
|
77
|
+
files:
|
|
78
|
+
- Rakefile
|
|
79
|
+
- bin/proxie
|
|
80
|
+
- lib/proxie/logger.rb
|
|
81
|
+
- lib/proxie/proxie.rb
|
|
82
|
+
- lib/proxie/server.rb
|
|
83
|
+
- lib/proxie/version.rb
|
|
84
|
+
- lib/proxie/web.rb
|
|
85
|
+
- lib/proxie.rb
|
|
86
|
+
- README.rdoc
|
|
87
|
+
has_rdoc: true
|
|
88
|
+
homepage: http://github.com/sosedoff/proxie
|
|
89
|
+
licenses: []
|
|
90
|
+
|
|
91
|
+
post_install_message:
|
|
92
|
+
rdoc_options: []
|
|
93
|
+
|
|
94
|
+
require_paths:
|
|
95
|
+
- lib
|
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
|
+
none: false
|
|
98
|
+
requirements:
|
|
99
|
+
- - ">="
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
hash: 3
|
|
102
|
+
segments:
|
|
103
|
+
- 0
|
|
104
|
+
version: "0"
|
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
|
+
none: false
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
hash: 3
|
|
111
|
+
segments:
|
|
112
|
+
- 0
|
|
113
|
+
version: "0"
|
|
114
|
+
requirements: []
|
|
115
|
+
|
|
116
|
+
rubyforge_project:
|
|
117
|
+
rubygems_version: 1.4.1
|
|
118
|
+
signing_key:
|
|
119
|
+
specification_version: 3
|
|
120
|
+
summary: Proxie - Simple http proxy server
|
|
121
|
+
test_files: []
|
|
122
|
+
|