ruby-gobuster 0.1.0
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.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +13 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +20 -0
- data/README.md +67 -0
- data/Rakefile +23 -0
- data/gemspec.yml +27 -0
- data/lib/gobuster/command.rb +169 -0
- data/lib/gobuster/hostname.rb +33 -0
- data/lib/gobuster/output_file.rb +99 -0
- data/lib/gobuster/parsers/dir.rb +38 -0
- data/lib/gobuster/parsers/dns.rb +35 -0
- data/lib/gobuster/parsers/fuzz.rb +38 -0
- data/lib/gobuster/parsers/s3.rb +34 -0
- data/lib/gobuster/response.rb +68 -0
- data/lib/gobuster/s3_bucket.rb +33 -0
- data/lib/gobuster/version.rb +4 -0
- data/ruby-gobuster.gemspec +61 -0
- data/spec/command_spec.rb +58 -0
- data/spec/fixtures/dir_output.txt +3 -0
- data/spec/fixtures/dns_output.txt +2 -0
- data/spec/fixtures/fuzz_output.txt +5 -0
- data/spec/fixtures/s3_output.txt +5 -0
- data/spec/hostname_spec.rb +26 -0
- data/spec/output_file_spec.rb +174 -0
- data/spec/parsers/dir_spec.rb +30 -0
- data/spec/parsers/dns_spec.rb +25 -0
- data/spec/parsers/fuzz_spec.rb +31 -0
- data/spec/parsers/s3_bucket_spec.rb +25 -0
- data/spec/response_spec.rb +87 -0
- data/spec/s3_bucket_spec.rb +26 -0
- data/spec/spec_helper.rb +3 -0
- metadata +122 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
module Gobuster
|
2
|
+
#
|
3
|
+
# Represents a HTTP resposne found by `gobuster dir` or `gobuster fuzz`.
|
4
|
+
#
|
5
|
+
class Response
|
6
|
+
|
7
|
+
# The path of the response.
|
8
|
+
#
|
9
|
+
# @return [String, nil]
|
10
|
+
attr_reader :path
|
11
|
+
|
12
|
+
# The URL of the response.
|
13
|
+
#
|
14
|
+
# @return [String, nil]
|
15
|
+
attr_reader :url
|
16
|
+
|
17
|
+
# The HTTP status code.
|
18
|
+
#
|
19
|
+
# @return [Integer]
|
20
|
+
attr_reader :status
|
21
|
+
|
22
|
+
# The size of the response.
|
23
|
+
#
|
24
|
+
# @return [Integer]
|
25
|
+
attr_reader :size
|
26
|
+
|
27
|
+
#
|
28
|
+
# Initializes the HTTP response.
|
29
|
+
#
|
30
|
+
# @param [String, nil] path
|
31
|
+
#
|
32
|
+
# @param [String, nil] url
|
33
|
+
#
|
34
|
+
# @param [Integer] status
|
35
|
+
#
|
36
|
+
# @param [Integer] size
|
37
|
+
#
|
38
|
+
# @raise [ArgumentError]
|
39
|
+
# The `path:` or `url:` keyword argument is required.
|
40
|
+
#
|
41
|
+
def initialize(path: nil, url: nil, status: , size: )
|
42
|
+
if url
|
43
|
+
@url = url
|
44
|
+
@path = nil
|
45
|
+
elsif path
|
46
|
+
@url = nil
|
47
|
+
@path = path
|
48
|
+
else
|
49
|
+
raise(ArgumentError,"path: or url: keyword argument must be given")
|
50
|
+
end
|
51
|
+
|
52
|
+
@status = status
|
53
|
+
@size = size
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Converts the response to a String.
|
58
|
+
#
|
59
|
+
# @return [String]
|
60
|
+
#
|
61
|
+
def to_s
|
62
|
+
@path || @url
|
63
|
+
end
|
64
|
+
|
65
|
+
alias to_str to_s
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Gobuster
|
2
|
+
#
|
3
|
+
# Represents an S3 bucket found by `gobuster s3`.
|
4
|
+
#
|
5
|
+
class S3Bucket
|
6
|
+
|
7
|
+
# The URL to the S3 bucket.
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :url
|
11
|
+
|
12
|
+
#
|
13
|
+
# Initializes the S3 bucket.
|
14
|
+
#
|
15
|
+
# @param [String] url
|
16
|
+
#
|
17
|
+
def initialize(url)
|
18
|
+
@url = url
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Converts the S3 bucket to a String.
|
23
|
+
#
|
24
|
+
# @return [String]
|
25
|
+
#
|
26
|
+
def to_s
|
27
|
+
@url
|
28
|
+
end
|
29
|
+
|
30
|
+
alias to_str to_s
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gemspec = YAML.load_file('gemspec.yml')
|
7
|
+
|
8
|
+
gem.name = gemspec.fetch('name')
|
9
|
+
gem.version = gemspec.fetch('version') do
|
10
|
+
lib_dir = File.join(File.dirname(__FILE__),'lib')
|
11
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
12
|
+
|
13
|
+
require 'gobuster/version'
|
14
|
+
Gobuster::VERSION
|
15
|
+
end
|
16
|
+
|
17
|
+
gem.summary = gemspec['summary']
|
18
|
+
gem.description = gemspec['description']
|
19
|
+
gem.licenses = Array(gemspec['license'])
|
20
|
+
gem.authors = Array(gemspec['authors'])
|
21
|
+
gem.email = gemspec['email']
|
22
|
+
gem.homepage = gemspec['homepage']
|
23
|
+
gem.metadata = gemspec['metadata'] if gemspec['metadata']
|
24
|
+
|
25
|
+
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
26
|
+
|
27
|
+
gem.files = `git ls-files`.split($/)
|
28
|
+
gem.files = glob[gemspec['files']] if gemspec['files']
|
29
|
+
|
30
|
+
gem.executables = gemspec.fetch('executables') do
|
31
|
+
glob['bin/*'].map { |path| File.basename(path) }
|
32
|
+
end
|
33
|
+
gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
|
34
|
+
|
35
|
+
gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
|
36
|
+
gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
|
37
|
+
gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
|
38
|
+
|
39
|
+
gem.require_paths = Array(gemspec.fetch('require_paths') {
|
40
|
+
%w[ext lib].select { |dir| File.directory?(dir) }
|
41
|
+
})
|
42
|
+
|
43
|
+
gem.requirements = Array(gemspec['requirements'])
|
44
|
+
gem.required_ruby_version = gemspec['required_ruby_version']
|
45
|
+
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
46
|
+
gem.post_install_message = gemspec['post_install_message']
|
47
|
+
|
48
|
+
split = lambda { |string| string.split(/,\s*/) }
|
49
|
+
|
50
|
+
if gemspec['dependencies']
|
51
|
+
gemspec['dependencies'].each do |name,versions|
|
52
|
+
gem.add_dependency(name,split[versions])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if gemspec['development_dependencies']
|
57
|
+
gemspec['development_dependencies'].each do |name,versions|
|
58
|
+
gem.add_development_dependency(name,split[versions])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/command'
|
3
|
+
|
4
|
+
describe Gobuster::Command do
|
5
|
+
describe described_class::Duration do
|
6
|
+
describe "#validate" do
|
7
|
+
context "when given nil" do
|
8
|
+
let(:value) { nil }
|
9
|
+
|
10
|
+
it "must return [false, \"cannot be nil\"]" do
|
11
|
+
expect(subject.validate(value)).to eq(
|
12
|
+
[false, "cannot be nil"]
|
13
|
+
)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when given a String" do
|
18
|
+
context "when given an empty String" do
|
19
|
+
let(:value) { "" }
|
20
|
+
|
21
|
+
it "must return [false, \"does not allow an empty value\"]" do
|
22
|
+
expect(subject.validate(value)).to eq(
|
23
|
+
[false, "does not allow an empty value"]
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when given a number" do
|
29
|
+
let(:value) { "10" }
|
30
|
+
|
31
|
+
it "must return [false, \"must be a number and end with 'm', 's', 'ms', or 'ns'\"]" do
|
32
|
+
expect(subject.validate(value)).to eq(
|
33
|
+
[false, "must be a number and end with 'm', 's', 'ms', or 'ns'"]
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when given a number that ends with a unit" do
|
39
|
+
let(:value) { "10s" }
|
40
|
+
|
41
|
+
it "must return true" do
|
42
|
+
expect(subject.validate(value)).to be(true)
|
43
|
+
end
|
44
|
+
|
45
|
+
context "but the unit isn't recognized" do
|
46
|
+
let(:value) { "10x" }
|
47
|
+
|
48
|
+
it "must return [false, \"must be a number and end with 'm', 's', 'ms', or 'ns'\"]" do
|
49
|
+
expect(subject.validate(value)).to eq(
|
50
|
+
[false, "must be a number and end with 'm', 's', 'ms', or 'ns'"]
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
Found: [Status=200] [Length=1256] http://example.com
|
2
|
+
Found: [Status=200] [Length=1256] http://example.com
|
3
|
+
Found: [Status=200] [Length=1256] http://example.com
|
4
|
+
Found: [Status=200] [Length=1256] http://example.com
|
5
|
+
Found: [Status=200] [Length=1256] http://example.com
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/hostname'
|
3
|
+
|
4
|
+
describe Gobuster::Hostname do
|
5
|
+
let(:name) { 'www.example.com' }
|
6
|
+
|
7
|
+
subject { described_class.new(name) }
|
8
|
+
|
9
|
+
describe "#initialize" do
|
10
|
+
it "must set #name" do
|
11
|
+
expect(subject.name).to eq(name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#to_s" do
|
16
|
+
it "must return #name" do
|
17
|
+
expect(subject.to_s).to eq(name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#to_str" do
|
22
|
+
it "must return #name" do
|
23
|
+
expect(subject.to_str).to eq(name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/output_file'
|
3
|
+
|
4
|
+
describe Gobuster::OutputFile do
|
5
|
+
let(:fixtures_dir) { File.expand_path(File.join(__dir__,'fixtures')) }
|
6
|
+
|
7
|
+
describe "PARSERS" do
|
8
|
+
subject { described_class::PARSERS }
|
9
|
+
|
10
|
+
describe ":dir" do
|
11
|
+
it { expect(subject[:dir]).to eq(Gobuster::Parsers::Dir) }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ":dns" do
|
15
|
+
it { expect(subject[:dns]).to eq(Gobuster::Parsers::DNS) }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ":fuzz" do
|
19
|
+
it { expect(subject[:fuzz]).to eq(Gobuster::Parsers::Fuzz) }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ":s3" do
|
23
|
+
it { expect(subject[:s3]).to eq(Gobuster::Parsers::S3) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#initialize" do
|
28
|
+
let(:path) { "/path/to/file.txt" }
|
29
|
+
let(:format) { :dir }
|
30
|
+
|
31
|
+
subject { described_class.new(path, format: format) }
|
32
|
+
|
33
|
+
it "must set #path" do
|
34
|
+
expect(subject.path).to eq(path)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "must set #format" do
|
38
|
+
expect(subject.format).to be(format)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "must set #parser based on #format" do
|
42
|
+
expect(subject.parser).to eq(described_class::PARSERS[subject.format])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
let(:path) { File.join(fixtures_dir,'dir_output.txt') }
|
47
|
+
|
48
|
+
subject { described_class.new(path) }
|
49
|
+
|
50
|
+
describe "#each" do
|
51
|
+
context "when initialized with `gobuster dir` output file" do
|
52
|
+
let(:path) { File.join(fixtures_dir,'dir_output.txt') }
|
53
|
+
|
54
|
+
subject { described_class.new(path, format: :dir) }
|
55
|
+
|
56
|
+
context "and when a block is given" do
|
57
|
+
it "must yield each parsed Response object" do
|
58
|
+
yielded_responses = []
|
59
|
+
|
60
|
+
subject.each do |response|
|
61
|
+
yielded_responses << response
|
62
|
+
end
|
63
|
+
|
64
|
+
expect(yielded_responses).to_not be_empty
|
65
|
+
expect(yielded_responses).to all(be_kind_of(Gobuster::Response))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "and when no block is given" do
|
70
|
+
it "must return an Enumerator of the parsed Response objects" do
|
71
|
+
responses = subject.each.to_a
|
72
|
+
|
73
|
+
expect(responses).to_not be_empty
|
74
|
+
expect(responses).to all(be_kind_of(Gobuster::Response))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when initialized with `gobuster dns` output file" do
|
80
|
+
let(:path) { File.join(fixtures_dir,'dns_output.txt') }
|
81
|
+
|
82
|
+
subject { described_class.new(path, format: :dns) }
|
83
|
+
|
84
|
+
context "and when a block is given" do
|
85
|
+
it "must yield each parsed Hostname object" do
|
86
|
+
yielded_hostnames = []
|
87
|
+
|
88
|
+
subject.each do |hostname|
|
89
|
+
yielded_hostnames << hostname
|
90
|
+
end
|
91
|
+
|
92
|
+
expect(yielded_hostnames).to_not be_empty
|
93
|
+
expect(yielded_hostnames).to all(be_kind_of(Gobuster::Hostname))
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "and when no block is given" do
|
98
|
+
it "must return an Enumerator of the parsed Hostname objects" do
|
99
|
+
hostnames = subject.each.to_a
|
100
|
+
|
101
|
+
expect(hostnames).to_not be_empty
|
102
|
+
expect(hostnames).to all(be_kind_of(Gobuster::Hostname))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when initialized with `gobuster fuzz` output file" do
|
108
|
+
let(:path) { File.join(fixtures_dir,'fuzz_output.txt') }
|
109
|
+
|
110
|
+
subject { described_class.new(path, format: :fuzz) }
|
111
|
+
|
112
|
+
context "and when a block is given" do
|
113
|
+
it "must yield each parsed Response object" do
|
114
|
+
yielded_responses = []
|
115
|
+
|
116
|
+
subject.each do |response|
|
117
|
+
yielded_responses << response
|
118
|
+
end
|
119
|
+
|
120
|
+
expect(yielded_responses).to_not be_empty
|
121
|
+
expect(yielded_responses).to all(be_kind_of(Gobuster::Response))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "and when no block is given" do
|
126
|
+
it "must return an Enumerator of the parsed Response objects" do
|
127
|
+
responses = subject.each.to_a
|
128
|
+
|
129
|
+
expect(responses).to_not be_empty
|
130
|
+
expect(responses).to all(be_kind_of(Gobuster::Response))
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when initialized with `gobuster s3` output file" do
|
136
|
+
let(:path) { File.join(fixtures_dir,'s3_output.txt') }
|
137
|
+
|
138
|
+
subject { described_class.new(path, format: :s3) }
|
139
|
+
|
140
|
+
context "and when a block is given" do
|
141
|
+
it "must yield each parsed S3Bucket object" do
|
142
|
+
yielded_s3_buckets = []
|
143
|
+
|
144
|
+
subject.each do |s3_bucket|
|
145
|
+
yielded_s3_buckets << s3_bucket
|
146
|
+
end
|
147
|
+
|
148
|
+
expect(yielded_s3_buckets).to_not be_empty
|
149
|
+
expect(yielded_s3_buckets).to all(be_kind_of(Gobuster::S3Bucket))
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "and when no block is given" do
|
154
|
+
it "must return an Enumerator of the parsed S3Bucket objects" do
|
155
|
+
s3_buckets = subject.each.to_a
|
156
|
+
|
157
|
+
expect(s3_buckets).to_not be_empty
|
158
|
+
expect(s3_buckets).to all(be_kind_of(Gobuster::S3Bucket))
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "#to_s" do
|
165
|
+
let(:path) { "/path/to/file.txt" }
|
166
|
+
let(:format) { :dir }
|
167
|
+
|
168
|
+
subject { described_class.new(path, format: format) }
|
169
|
+
|
170
|
+
it "must return #path" do
|
171
|
+
expect(subject.to_s).to eq(path)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/parsers/dir'
|
3
|
+
|
4
|
+
describe Gobuster::Parsers::Dir do
|
5
|
+
describe ".parse" do
|
6
|
+
let(:path) { '/test' }
|
7
|
+
let(:status) { 200 }
|
8
|
+
let(:size) { 176368 }
|
9
|
+
|
10
|
+
let(:line) { "#{path} (Status: #{status}) [Size: #{size}]" }
|
11
|
+
let(:io) { StringIO.new(line + $/) }
|
12
|
+
|
13
|
+
it "must parse each line and yield Gobuster::Response objects" do
|
14
|
+
yielded_responses = []
|
15
|
+
|
16
|
+
subject.parse(io) do |response|
|
17
|
+
yielded_responses << response
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(yielded_responses.length).to eq(1)
|
21
|
+
expect(yielded_responses.first).to be_kind_of(Gobuster::Response)
|
22
|
+
|
23
|
+
yielded_response = yielded_responses.first
|
24
|
+
|
25
|
+
expect(yielded_response.path).to eq(path)
|
26
|
+
expect(yielded_response.status).to eq(status)
|
27
|
+
expect(yielded_response.size).to eq(size)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/parsers/dns'
|
3
|
+
|
4
|
+
describe Gobuster::Parsers::DNS do
|
5
|
+
describe ".parse" do
|
6
|
+
let(:name) { "www.twitter.com" }
|
7
|
+
let(:line) { "Found: #{name}" }
|
8
|
+
let(:io) { StringIO.new(line + $/) }
|
9
|
+
|
10
|
+
it "must parse each line and yield Gobuster::Hostname objects" do
|
11
|
+
yielded_hostnames = []
|
12
|
+
|
13
|
+
subject.parse(io) do |hostname|
|
14
|
+
yielded_hostnames << hostname
|
15
|
+
end
|
16
|
+
|
17
|
+
expect(yielded_hostnames.length).to eq(1)
|
18
|
+
expect(yielded_hostnames.first).to be_kind_of(Gobuster::Hostname)
|
19
|
+
|
20
|
+
yielded_hostname = yielded_hostnames.first
|
21
|
+
|
22
|
+
expect(yielded_hostname.name).to eq(name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/parsers/fuzz'
|
3
|
+
|
4
|
+
describe Gobuster::Parsers::Fuzz do
|
5
|
+
describe ".parse" do
|
6
|
+
let(:url) { '/test' }
|
7
|
+
let(:status) { 200 }
|
8
|
+
let(:size) { 176368 }
|
9
|
+
|
10
|
+
let(:line) { "Found: [Status=#{status}] [Length=#{size}] #{url}" }
|
11
|
+
let(:io) { StringIO.new(line + $/) }
|
12
|
+
|
13
|
+
it "must parse each line and yield Gobuster::Response objects" do
|
14
|
+
yielded_responses = []
|
15
|
+
|
16
|
+
subject.parse(io) do |response|
|
17
|
+
yielded_responses << response
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(yielded_responses.length).to eq(1)
|
21
|
+
expect(yielded_responses.first).to be_kind_of(Gobuster::Response)
|
22
|
+
|
23
|
+
yielded_response = yielded_responses.first
|
24
|
+
|
25
|
+
expect(yielded_response.url).to eq(url)
|
26
|
+
expect(yielded_response.path).to be(nil)
|
27
|
+
expect(yielded_response.status).to eq(status)
|
28
|
+
expect(yielded_response.size).to eq(size)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/parsers/s3'
|
3
|
+
|
4
|
+
describe Gobuster::Parsers::S3 do
|
5
|
+
describe ".parse" do
|
6
|
+
let(:url) { "http://test.s3.amazonaws.com/" }
|
7
|
+
let(:line) { url }
|
8
|
+
let(:io) { StringIO.new(line + $/) }
|
9
|
+
|
10
|
+
it "must parse each line and yield Gobuster::S3Bucket objects" do
|
11
|
+
yielded_s3_buckets = []
|
12
|
+
|
13
|
+
subject.parse(io) do |s3_bucket|
|
14
|
+
yielded_s3_buckets << s3_bucket
|
15
|
+
end
|
16
|
+
|
17
|
+
expect(yielded_s3_buckets.length).to eq(1)
|
18
|
+
expect(yielded_s3_buckets.first).to be_kind_of(Gobuster::S3Bucket)
|
19
|
+
|
20
|
+
yielded_s3_bucket = yielded_s3_buckets.first
|
21
|
+
|
22
|
+
expect(yielded_s3_bucket.url).to eq(url)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/response'
|
3
|
+
|
4
|
+
describe Gobuster::Response do
|
5
|
+
let(:path) { '/test' }
|
6
|
+
let(:url) { "https://example.com#{path}" }
|
7
|
+
let(:status) { 200 }
|
8
|
+
let(:size) { 176368 }
|
9
|
+
|
10
|
+
describe "#initialize" do
|
11
|
+
context "when initialized with the path: keyword argument" do
|
12
|
+
subject { described_class.new(path: path, status: status, size: size) }
|
13
|
+
|
14
|
+
it "must set #path" do
|
15
|
+
expect(subject.path).to eq(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must set #url to nil" do
|
19
|
+
expect(subject.url).to be(nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "must set #status" do
|
23
|
+
expect(subject.status).to eq(status)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "must set #size" do
|
27
|
+
expect(subject.size).to eq(size)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when initialized with the url: keyword argument" do
|
32
|
+
subject { described_class.new(url: url, status: status, size: size) }
|
33
|
+
|
34
|
+
it "must set #url" do
|
35
|
+
expect(subject.url).to eq(url)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must set #path to nil" do
|
39
|
+
expect(subject.path).to be(nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "must set #status" do
|
43
|
+
expect(subject.status).to eq(status)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "must set #size" do
|
47
|
+
expect(subject.size).to eq(size)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#to_s" do
|
53
|
+
context "when initialized with the path: keyword argument" do
|
54
|
+
subject { described_class.new(path: path, status: status, size: size) }
|
55
|
+
|
56
|
+
it "must return #path" do
|
57
|
+
expect(subject.to_s).to eq(path)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when initialized with the url: keyword argument" do
|
62
|
+
subject { described_class.new(url: url, status: status, size: size) }
|
63
|
+
|
64
|
+
it "must return #url" do
|
65
|
+
expect(subject.to_s).to eq(url)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#to_str" do
|
71
|
+
context "when initialized with the path: keyword argument" do
|
72
|
+
subject { described_class.new(path: path, status: status, size: size) }
|
73
|
+
|
74
|
+
it "must return #path" do
|
75
|
+
expect(subject.to_s).to eq(path)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when initialized with the url: keyword argument" do
|
80
|
+
subject { described_class.new(url: url, status: status, size: size) }
|
81
|
+
|
82
|
+
it "must return #url" do
|
83
|
+
expect(subject.to_s).to eq(url)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gobuster/s3_bucket'
|
3
|
+
|
4
|
+
describe Gobuster::S3Bucket do
|
5
|
+
let(:url) { 'http://test.s3.amazonaws.com/' }
|
6
|
+
|
7
|
+
subject { described_class.new(url) }
|
8
|
+
|
9
|
+
describe "#initialize" do
|
10
|
+
it "must set #url" do
|
11
|
+
expect(subject.url).to eq(url)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#to_s" do
|
16
|
+
it "must return #url" do
|
17
|
+
expect(subject.to_s).to eq(url)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#to_str" do
|
22
|
+
it "must return #url" do
|
23
|
+
expect(subject.to_str).to eq(url)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED