auto_response 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +12 -0
- data/Gemfile.lock +16 -0
- data/bin/ar +6 -0
- data/bin/start_ar.rb +5 -0
- data/lib/ar/parser.rb +50 -0
- data/lib/ar/proxyserver.rb +102 -0
- data/lib/ar/rule_dsl.rb +16 -0
- data/lib/ar/rule_manager.rb +45 -0
- data/lib/autoresponse.rb +118 -0
- data/readme.md +87 -0
- data/rules.sample +63 -0
- data/test/all-test.rb +32 -0
- data/test/fixture/hello_world.txt +1 -0
- data/test/fixture/passwd +3 -0
- data/test/helper.rb +32 -0
- data/test/match_with_reg_test.rb +19 -0
- data/test/respond_with_array_test.rb +29 -0
- data/test/respond_with_file_test.rb +16 -0
- data/test/respond_with_number_test.rb +25 -0
- data/test/respond_with_string_test.rb +39 -0
- data/test/respond_with_url_test.rb +18 -0
- data/test/response_text_parser_test.rb +38 -0
- metadata +71 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/bin/ar
ADDED
data/bin/start_ar.rb
ADDED
data/lib/ar/parser.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module AutoResp
|
2
|
+
|
3
|
+
module Parser
|
4
|
+
|
5
|
+
require 'net/http'
|
6
|
+
|
7
|
+
def parse( str )
|
8
|
+
|
9
|
+
headers, body = {}, []
|
10
|
+
to_find_header, body_start = true, false
|
11
|
+
|
12
|
+
str.lines.each_with_index do |line, idx|
|
13
|
+
if to_find_header and not body_start
|
14
|
+
if line =~ /^\s*$/
|
15
|
+
if idx == 0
|
16
|
+
to_find_header = false
|
17
|
+
body << line
|
18
|
+
else
|
19
|
+
body_start = true
|
20
|
+
body = []
|
21
|
+
end
|
22
|
+
else
|
23
|
+
body << line
|
24
|
+
name, value = parse_header_item(line)
|
25
|
+
if name
|
26
|
+
headers[name] = value
|
27
|
+
else
|
28
|
+
to_find_header = false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
else
|
32
|
+
body << line
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
headers = nil unless to_find_header and body_start
|
37
|
+
res_body = body.join
|
38
|
+
|
39
|
+
[headers, res_body]
|
40
|
+
end
|
41
|
+
|
42
|
+
def parse_header_item(str)
|
43
|
+
mtc = str.match /^\s*(\S+)\s*:\s*(\S.*)$/
|
44
|
+
[mtc[1], mtc[2]] if mtc
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'webrick/httpproxy'
|
2
|
+
require 'webrick/log'
|
3
|
+
|
4
|
+
require_relative 'rule_manager'
|
5
|
+
require_relative 'parser'
|
6
|
+
|
7
|
+
module AutoResp
|
8
|
+
|
9
|
+
class ProxyServer < WEBrick::HTTPProxyServer
|
10
|
+
|
11
|
+
include Parser
|
12
|
+
|
13
|
+
def initialize(core, config={})
|
14
|
+
@core = core
|
15
|
+
super(config.update({
|
16
|
+
:AccessLog => [],
|
17
|
+
:Logger => WEBrick::Log.new("/dev/null")
|
18
|
+
}))
|
19
|
+
end
|
20
|
+
|
21
|
+
def service(req, res)
|
22
|
+
header, body, status = find_auto_res(req.unparsed_uri)
|
23
|
+
res.status = status if status
|
24
|
+
|
25
|
+
if header or body
|
26
|
+
puts "match".ljust(8) << ": #{req.unparsed_uri}"
|
27
|
+
puts "header".ljust(8) << ": #{header}"
|
28
|
+
puts "body".ljust(8) << ": \n#{body}"
|
29
|
+
puts "-"*50
|
30
|
+
res.header.merge!(header || {})
|
31
|
+
res.body = body
|
32
|
+
else
|
33
|
+
super(req, res)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_auto_res(url)
|
38
|
+
@core.rules.find do |tar, map|
|
39
|
+
if trim_url(tar) === trim_url(url)
|
40
|
+
return fetch(map, tar, url)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch(txt, declare, uri)
|
46
|
+
|
47
|
+
case txt
|
48
|
+
when Proc
|
49
|
+
mtc = uri.match(declare) if Regexp === declare
|
50
|
+
fetch( txt.call(*mtc), declare, uri )
|
51
|
+
when String
|
52
|
+
if goto = redirect_path(txt)
|
53
|
+
if is_uri?(goto)
|
54
|
+
Net::HTTP.get_response(URI(goto)) do |res|
|
55
|
+
return [nil, res.body]
|
56
|
+
end
|
57
|
+
elsif File.exist?(goto)
|
58
|
+
return parse(IO.read(goto))
|
59
|
+
end
|
60
|
+
else
|
61
|
+
parse(txt)
|
62
|
+
end
|
63
|
+
when Fixnum
|
64
|
+
[{}, "", txt]
|
65
|
+
when Array
|
66
|
+
[txt[1], txt[2], txt[0]]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def redirect_path(t)
|
72
|
+
if is_single_line?(t)
|
73
|
+
(t.match(/^=GOTO=> (\S.*?)\s*$/) || [] )[1]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def is_uri?(txt)
|
78
|
+
/^[A-Za-z][A-Za-z0-9+\-\.]*:\/\/.+/ =~ txt
|
79
|
+
end
|
80
|
+
|
81
|
+
def header_hash(header)
|
82
|
+
h = header.to_hash
|
83
|
+
h.each do |n,v|
|
84
|
+
h[n] = v.join if Array === v
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def trim_url(url)
|
89
|
+
if url.is_a? String
|
90
|
+
url.sub(/\/$/, '')
|
91
|
+
else
|
92
|
+
url
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def is_single_line?(text)
|
97
|
+
text.count("\n") < 2
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
data/lib/ar/rule_dsl.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative 'rule_dsl'
|
2
|
+
|
3
|
+
module AutoResp
|
4
|
+
|
5
|
+
class RuleManager
|
6
|
+
|
7
|
+
include RuleDSL
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
end
|
11
|
+
|
12
|
+
def rules
|
13
|
+
@rules ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def clear
|
17
|
+
@rules.clear
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_handler( handler )
|
21
|
+
if @last_rule
|
22
|
+
rules[@last_rule] = handler
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_rule(*args, &block)
|
27
|
+
@last_rule = target = args.first
|
28
|
+
case target
|
29
|
+
when Hash
|
30
|
+
@last_rule = target.keys.first
|
31
|
+
rules.merge! target
|
32
|
+
when String
|
33
|
+
rules[target] = args[1]
|
34
|
+
when Regexp
|
35
|
+
if block_given?
|
36
|
+
rules[target] = block
|
37
|
+
else
|
38
|
+
rules[target] = args[1]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/lib/autoresponse.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'xmlrpc/httpserver'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'listen'
|
5
|
+
require 'colorize'
|
6
|
+
|
7
|
+
require_relative 'ar/proxyserver'
|
8
|
+
require_relative 'ar/rule_manager'
|
9
|
+
require_relative 'ar/parser'
|
10
|
+
|
11
|
+
module AutoResp
|
12
|
+
|
13
|
+
|
14
|
+
class AutoResponder
|
15
|
+
|
16
|
+
ARHOME = "#{ENV["HOME"]}/.auto_response"
|
17
|
+
RULES = "#{ARHOME}/rules"
|
18
|
+
|
19
|
+
def initialize(config={})
|
20
|
+
@config = config
|
21
|
+
@rule_manager = RuleManager.new
|
22
|
+
init_autoresponse_home
|
23
|
+
init_proxy_server
|
24
|
+
load_rules
|
25
|
+
monitor_rules_change
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
def init_autoresponse_home
|
30
|
+
unless File.exist?(RULES)
|
31
|
+
pwd = File.expand_path('..', File.dirname(__FILE__))
|
32
|
+
FileUtils.mkdir_p(ARHOME)
|
33
|
+
FileUtils.cp "#{pwd}/rules.sample", RULES
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
def init_proxy_server
|
39
|
+
@server = ProxyServer.new(
|
40
|
+
self,
|
41
|
+
:BindAddress => @config[:host] || '0.0.0.0',
|
42
|
+
:Port => @config[:port] || 9000
|
43
|
+
)
|
44
|
+
trap('INT') { stop_and_exit }
|
45
|
+
end
|
46
|
+
|
47
|
+
public
|
48
|
+
def start
|
49
|
+
@thread = Thread.new { @server.start }
|
50
|
+
@thread.join
|
51
|
+
end
|
52
|
+
|
53
|
+
def stop_and_exit
|
54
|
+
stop
|
55
|
+
exit
|
56
|
+
end
|
57
|
+
|
58
|
+
def stop
|
59
|
+
puts "\nshuting down"
|
60
|
+
@server.shutdown
|
61
|
+
@thread.kill
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_rule(*args, &block)
|
65
|
+
case args.first
|
66
|
+
when Hash
|
67
|
+
rules.merge! args.first
|
68
|
+
when String
|
69
|
+
rules[args[0]] = args[1]
|
70
|
+
when Regexp
|
71
|
+
if block_given?
|
72
|
+
rules[args[0]] = block
|
73
|
+
else
|
74
|
+
rules[args[0]] = args[1]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def rules
|
80
|
+
@rule_manager.rules
|
81
|
+
end
|
82
|
+
|
83
|
+
def clear_rules
|
84
|
+
rules.clear
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
def load_rules(path=nil)
|
89
|
+
path ||= @config[:rule_config]
|
90
|
+
path ||= "#{ARHOME}/rules"
|
91
|
+
if File.readable?(path)
|
92
|
+
@rule_manager.instance_eval File.read(path)
|
93
|
+
end
|
94
|
+
log_rules
|
95
|
+
end
|
96
|
+
|
97
|
+
def log_rules
|
98
|
+
puts "mapping rules:"
|
99
|
+
rules.each do |n,v|
|
100
|
+
puts n.to_s.ljust(30).green << "=> #{v}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def monitor_rules_change
|
105
|
+
listener = Listen.to(ARHOME)
|
106
|
+
listener.change { reload_rules }
|
107
|
+
Thread.new { listener.start }
|
108
|
+
end
|
109
|
+
|
110
|
+
def reload_rules
|
111
|
+
@rule_manager.clear
|
112
|
+
load_rules
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
data/readme.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# AutoResponse - HTTP debugging tool for Linux and Mac
|
2
|
+
|
3
|
+
## What's auto_response for?
|
4
|
+
|
5
|
+
[Fiddler](http://www.fiddler2.com) is the favor tool of many web developers for debugging HTTP web apps. However it is only available on Windows. AutoResponse ports the most used feature of fiddler, 'auto respond', to Linux and Mac world.
|
6
|
+
|
7
|
+
Auto_response acts as a proxy server like Fiddler does, allowing you to modify the content of HTTP response.
|
8
|
+
|
9
|
+
## Quick start
|
10
|
+
|
11
|
+
1. Install and run
|
12
|
+
|
13
|
+
gem install 'auto_response'
|
14
|
+
ar start
|
15
|
+
|
16
|
+
ar status #check server status
|
17
|
+
ar stop #stop proxy server
|
18
|
+
|
19
|
+
2. Set your browser proxy to 'http://127.0.0.1:9000'
|
20
|
+
3. Edit the configuration file to modify the urls you want change the response.
|
21
|
+
|
22
|
+
By default, the configuration file is located at:
|
23
|
+
`$HOME/.auto_response/rules`
|
24
|
+
|
25
|
+
## Response rules
|
26
|
+
|
27
|
+
~~~ruby
|
28
|
+
# Examples:
|
29
|
+
|
30
|
+
# just respond with status number
|
31
|
+
url "http://www.catchme.com"
|
32
|
+
r 404
|
33
|
+
|
34
|
+
# if you want to respond all requests with url
|
35
|
+
# equals "http://www.1688.com" with "Hello world!" :
|
36
|
+
url "http://www.1688.com"
|
37
|
+
r "Hello world"
|
38
|
+
|
39
|
+
# or you can respond with Array
|
40
|
+
url "http://china.alibaba.com"
|
41
|
+
r [200, {}, "Got replaced"] #[status, header, body]
|
42
|
+
|
43
|
+
# if you want to respond these requests with a file:
|
44
|
+
# this url will be responded with content of somefile.txt
|
45
|
+
# you can set headers and body in 'somefile.txt'
|
46
|
+
url "http://www.yousite.com"
|
47
|
+
goto "/home/youruser/somefile.txt"
|
48
|
+
|
49
|
+
# redirect to another url
|
50
|
+
url "http://www.targetsite.com"
|
51
|
+
goto "http://www.real-request-target.com/test.html"
|
52
|
+
|
53
|
+
# respond with text setting headers
|
54
|
+
url "http://www.target-site.com/target-url"
|
55
|
+
r <<-RESP
|
56
|
+
Test-Msg : http-header-example
|
57
|
+
header-server : Auto-Responder
|
58
|
+
Content-Type : text/html; charset=utf-8
|
59
|
+
|
60
|
+
<!Doctype html>
|
61
|
+
<html><body><h1>Hello world!</h1></body></html>
|
62
|
+
RESP
|
63
|
+
|
64
|
+
# match with regexp
|
65
|
+
url %r{http://pnq\.cc}
|
66
|
+
r "Any request made to pnq.cc will be responded with this message."
|
67
|
+
|
68
|
+
# regular expression and params
|
69
|
+
url %r{http://anysite\.cc(.*)} do |uri, path|
|
70
|
+
<<-RESP
|
71
|
+
Content-Type : text/html; charset=utf-8
|
72
|
+
|
73
|
+
<style>
|
74
|
+
body { font-size: 50pt; }
|
75
|
+
em { color: #ff7300; }
|
76
|
+
small { color: #ccc; }
|
77
|
+
</style>
|
78
|
+
|
79
|
+
With regular expression, you can do more powerful things. <br/>
|
80
|
+
You're requesting <em>#{path}</em> <br/>
|
81
|
+
<small>Server time is #{Time.now} now. </small>
|
82
|
+
RESP
|
83
|
+
end
|
84
|
+
~~~
|
85
|
+
|
86
|
+
## TODO:
|
87
|
+
* GUI monitor showing sessions
|
data/rules.sample
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is the AutoResponse rule config file
|
3
|
+
# using ruby syntax
|
4
|
+
|
5
|
+
# Examples:
|
6
|
+
|
7
|
+
# if you want to respond all requests with url
|
8
|
+
# equals "http://www.1688.com" with "Hello world!" :
|
9
|
+
url "http://www.1688.com"
|
10
|
+
r "Hello world"
|
11
|
+
|
12
|
+
# or you can respond with Array
|
13
|
+
url "http://china.alibaba.com"
|
14
|
+
r [200, {}, "Got replaced"] #[status, header, body]
|
15
|
+
|
16
|
+
# if you want to respond these requests with a file:
|
17
|
+
url "http://www.yousite.com"
|
18
|
+
goto "/home/youruser/somefile.txt"
|
19
|
+
|
20
|
+
# on Windows:
|
21
|
+
url "http://www.another-site.com"
|
22
|
+
goto "C:/Program\ Files/proj/test.txt"
|
23
|
+
|
24
|
+
# if you want to respond with another remote url:
|
25
|
+
url "http://www.targetsite.com"
|
26
|
+
goto "http://www.real-request-target.com/test.html"
|
27
|
+
|
28
|
+
# you can set response headers in the returned string
|
29
|
+
# e.g.
|
30
|
+
url "http://www.target-site.com/target-url"
|
31
|
+
r <<-RESP
|
32
|
+
Test-Msg : http-header-example
|
33
|
+
header-server : Auto-Responder
|
34
|
+
Content-Type : text/html; charset=utf-8
|
35
|
+
|
36
|
+
<!Doctype html>
|
37
|
+
<html><body><h1>Hello world!</h1></body></html>
|
38
|
+
RESP
|
39
|
+
|
40
|
+
# just respond with status number
|
41
|
+
url "http://www.catchme.com"
|
42
|
+
r 404
|
43
|
+
|
44
|
+
# Example of using regexp
|
45
|
+
url %r{http://pnq\.cc}
|
46
|
+
r "Any request made to pnq.cc will be responded with this message."
|
47
|
+
|
48
|
+
# Regular expression and params
|
49
|
+
url %r{http://anysite\.cc(.*)} do |uri, path|
|
50
|
+
<<-RESP
|
51
|
+
Content-Type : text/html; charset=utf-8
|
52
|
+
|
53
|
+
<style>
|
54
|
+
body { font-size: 50pt; }
|
55
|
+
em { color: #ff7300; }
|
56
|
+
small { color: #ccc; }
|
57
|
+
</style>
|
58
|
+
|
59
|
+
With regular expression, you can do more powerful things. <br/>
|
60
|
+
You're requesting <em>#{path}</em> <br/>
|
61
|
+
<small>Server time is #{Time.now} now. </small>
|
62
|
+
RESP
|
63
|
+
end
|
data/test/all-test.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
gem 'test-unit'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'test/unit/testsuite'
|
4
|
+
require 'test/unit/ui/console/testrunner'
|
5
|
+
|
6
|
+
require_relative 'respond_with_file_test'
|
7
|
+
require_relative 'respond_with_string_test'
|
8
|
+
require_relative 'respond_with_url_test'
|
9
|
+
require_relative 'respond_with_array_test'
|
10
|
+
require_relative 'respond_with_number_test'
|
11
|
+
require_relative 'match_with_reg_test'
|
12
|
+
require_relative 'response_text_parser_test'
|
13
|
+
|
14
|
+
class ALLTests < Test::Unit::TestSuite
|
15
|
+
|
16
|
+
def self.suite
|
17
|
+
tests = Test::Unit::TestSuite.new
|
18
|
+
|
19
|
+
tests << ParserTest.suite
|
20
|
+
tests << TestRespondWithString.suite
|
21
|
+
tests << TestRespondWithFile.suite
|
22
|
+
tests << TestRespondWithURL.suite
|
23
|
+
tests << TestRespondWithArray.suite
|
24
|
+
tests << TestRespondWithStatusCode.suite
|
25
|
+
tests << TestMatchWithReg.suite
|
26
|
+
|
27
|
+
tests
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
Test::Unit::UI::Console::TestRunner.run( ALLTests )
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello world!
|
data/test/fixture/passwd
ADDED
data/test/helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'net/http'
|
3
|
+
require_relative '../lib/autoresponse'
|
4
|
+
|
5
|
+
FIXTURE = File.expand_path("fixture", File.dirname(__FILE__))
|
6
|
+
|
7
|
+
module ARProxyTest
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@ar = start_proxy_server('127.0.0.1', 8764)
|
11
|
+
@req = Net::HTTP::Proxy('127.0.0.1', 8764)
|
12
|
+
end
|
13
|
+
|
14
|
+
def start_proxy_server(host, port)
|
15
|
+
@ar = AutoResp::AutoResponder.new :host => host, :port => port
|
16
|
+
Thread.new {
|
17
|
+
@ar.start
|
18
|
+
@ar.clear_rules
|
19
|
+
}
|
20
|
+
sleep 0.1
|
21
|
+
@ar
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
stop_proxy_server
|
26
|
+
end
|
27
|
+
|
28
|
+
def stop_proxy_server
|
29
|
+
@ar.stop
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestMatchWithReg < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include ARProxyTest
|
6
|
+
|
7
|
+
def test_with_parts
|
8
|
+
@ar.add_rule %r(http://books.cc/(.*)/(.*)) do |uri, cat, page|
|
9
|
+
"cat: #{cat}; page: #{page}"
|
10
|
+
end
|
11
|
+
@req.start('books.cc') do |http|
|
12
|
+
http.request_get('/books/1') do |res|
|
13
|
+
assert_equal 'cat: books; page: 1', res.body
|
14
|
+
assert_equal "200", res.code
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestRespondWithArray < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include ARProxyTest
|
6
|
+
|
7
|
+
def test_respond_with_good_status_array
|
8
|
+
@ar.add_rule 'http://www.test.com/' => [200, nil, 'test']
|
9
|
+
@req.start('www.test.com') do |http|
|
10
|
+
http.request_get('/') do |res|
|
11
|
+
assert_equal( nil, res.header["test"])
|
12
|
+
assert_equal 'test', res.body
|
13
|
+
assert_equal "200", res.code
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_respond_with_404_status_array
|
19
|
+
@ar.add_rule 'http://www.1688.com' => [404, nil, 'test']
|
20
|
+
@req.start('www.1688.com') do |http|
|
21
|
+
http.request_get('/') do |res|
|
22
|
+
assert_equal( nil, res.header["test"])
|
23
|
+
assert_equal 'test', res.body
|
24
|
+
assert_equal "404", res.code
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestRespondWithFile < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include ARProxyTest
|
6
|
+
|
7
|
+
def test_respond_with_simple_file
|
8
|
+
@ar.add_rule 'http://www.test.com/' => "=GOTO=> #{FIXTURE}/passwd"
|
9
|
+
@req.start('www.test.com') do |http|
|
10
|
+
http.request_get('/') do |res|
|
11
|
+
assert_equal IO.read("#{FIXTURE}/passwd"), res.body
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestRespondWithStatusCode < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include ARProxyTest
|
6
|
+
|
7
|
+
def test_respond_with_500
|
8
|
+
@ar.add_rule 'http://www.163.com/' => 500
|
9
|
+
@req.start('www.163.com') do |http|
|
10
|
+
http.request_get('/') do |res|
|
11
|
+
assert_equal "500", res.code
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_respond_with_404
|
17
|
+
@ar.add_rule 'http://www.163.com' => 404
|
18
|
+
@req.start('www.163.com') do |http|
|
19
|
+
http.request_get('/') do |res|
|
20
|
+
assert_equal "404", res.code
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestRespondWithString < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include ARProxyTest
|
6
|
+
|
7
|
+
def test_respond_with_simple_string
|
8
|
+
@ar.add_rule 'http://www.test.com/' => 'test'
|
9
|
+
@req.start('www.test.com') do |http|
|
10
|
+
http.request_get('/') do |res|
|
11
|
+
assert_equal( nil, res.header["test"])
|
12
|
+
assert_equal 'test', res.body
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_respond_uri_without_slash_with_simple_string
|
18
|
+
@ar.add_rule 'http://www.1688.com' => 'test'
|
19
|
+
@req.start('www.1688.com') do |http|
|
20
|
+
http.request_get('/') do |res|
|
21
|
+
assert_equal( nil, res.header["test"])
|
22
|
+
assert_equal 'test', res.body
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_respond_with_header_and_body
|
28
|
+
response = %Q(server: autoresponder\nname: hello\n \ntest)
|
29
|
+
@ar.add_rule 'http://www.1688.com/test' => response
|
30
|
+
@req.start('www.1688.com') do |http|
|
31
|
+
http.request_get('/test') do |res|
|
32
|
+
assert_equal( "autoresponder", res.header["server"])
|
33
|
+
assert_equal( "hello", res.header["name"])
|
34
|
+
assert_equal 'test', res.body
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class TestRespondWithURL < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include ARProxyTest
|
6
|
+
|
7
|
+
def test_respond_with_simple_file
|
8
|
+
@ar.add_rule 'http://www.test.com/' => '=GOTO=> http://www.1688.com/crossdomain.xml'
|
9
|
+
@req.start('www.test.com') do |http|
|
10
|
+
http.request_get('/') do |res|
|
11
|
+
open("http://www.1688.com/crossdomain.xml") do |file|
|
12
|
+
assert_equal file.read, res.read_body
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
class ParserTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include AutoResp::Parser
|
6
|
+
|
7
|
+
def test_parse_only_body
|
8
|
+
headers, body = parse("test")
|
9
|
+
assert_equal nil, headers
|
10
|
+
assert_equal "test", body
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_parse_only_header
|
14
|
+
headers, body = parse("test: good\n\n")
|
15
|
+
assert_equal({"test" => "good"}, headers)
|
16
|
+
assert body.empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_parse_header
|
20
|
+
headers, body = parse("test: good\n\ncontent")
|
21
|
+
assert_equal({"test"=>"good"}, headers)
|
22
|
+
assert_equal "content", body
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_first_line_empty
|
26
|
+
headers, body = parse(" \ntest: good\n\ncontent")
|
27
|
+
assert_equal nil, headers
|
28
|
+
assert_equal " \ntest: good\n\ncontent", body
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_empty_line_in_middle
|
32
|
+
response = %Q(server: autoresponder\ntest: hello\n \ntest)
|
33
|
+
headers, body = parse(response)
|
34
|
+
assert_equal({"server" => "autoresponder", "test" => "hello"}, headers)
|
35
|
+
assert_equal "test", body
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: auto_response
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- qhwa,,,
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-23 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email: qhwa@163.com
|
16
|
+
executables:
|
17
|
+
- ar
|
18
|
+
- start_ar.rb
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files:
|
21
|
+
- readme.md
|
22
|
+
files:
|
23
|
+
- readme.md
|
24
|
+
- rules.sample
|
25
|
+
- Gemfile
|
26
|
+
- Gemfile.lock
|
27
|
+
- bin/start_ar.rb
|
28
|
+
- bin/ar
|
29
|
+
- test/all-test.rb
|
30
|
+
- test/response_text_parser_test.rb
|
31
|
+
- test/respond_with_number_test.rb
|
32
|
+
- test/respond_with_url_test.rb
|
33
|
+
- test/respond_with_string_test.rb
|
34
|
+
- test/respond_with_array_test.rb
|
35
|
+
- test/fixture/passwd
|
36
|
+
- test/fixture/hello_world.txt
|
37
|
+
- test/respond_with_file_test.rb
|
38
|
+
- test/helper.rb
|
39
|
+
- test/match_with_reg_test.rb
|
40
|
+
- lib/autoresponse.rb
|
41
|
+
- lib/ar/parser.rb
|
42
|
+
- lib/ar/proxyserver.rb
|
43
|
+
- lib/ar/rule_manager.rb
|
44
|
+
- lib/ar/rule_dsl.rb
|
45
|
+
homepage: http://yoursite.example.com
|
46
|
+
licenses: []
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --main
|
50
|
+
- readme.md
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.24
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: What this thing does
|
71
|
+
test_files: []
|