ronin-web 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +25 -0
  3. data/Manifest.txt +36 -4
  4. data/README.txt +67 -64
  5. data/Rakefile +12 -3
  6. data/bin/ronin-web +1 -1
  7. data/lib/ronin/network/helpers/web.rb +221 -0
  8. data/lib/ronin/web.rb +1 -2
  9. data/lib/ronin/web/extensions.rb +0 -2
  10. data/lib/ronin/web/extensions/nokogiri.rb +0 -23
  11. data/lib/ronin/web/proxy.rb +3 -103
  12. data/lib/ronin/web/proxy/app.rb +31 -0
  13. data/lib/ronin/web/proxy/base.rb +41 -0
  14. data/lib/ronin/web/proxy/web.rb +42 -0
  15. data/lib/ronin/web/server.rb +3 -530
  16. data/lib/ronin/web/server/app.rb +31 -0
  17. data/lib/ronin/web/server/base.rb +334 -0
  18. data/lib/ronin/web/server/files.rb +92 -0
  19. data/lib/ronin/web/server/helpers.rb +25 -0
  20. data/lib/ronin/web/server/helpers/files.rb +126 -0
  21. data/lib/ronin/web/server/helpers/hosts.rb +72 -0
  22. data/lib/ronin/web/server/helpers/proxy.rb +153 -0
  23. data/lib/ronin/web/server/helpers/rendering.rb +36 -0
  24. data/lib/ronin/web/server/hosts.rb +86 -0
  25. data/lib/ronin/web/server/proxy.rb +116 -0
  26. data/lib/ronin/web/server/web.rb +62 -0
  27. data/lib/ronin/web/spider.rb +53 -26
  28. data/lib/ronin/web/version.rb +1 -3
  29. data/lib/ronin/web/web.rb +253 -95
  30. data/spec/spec_helper.rb +1 -1
  31. data/spec/web/proxy/base_spec.rb +9 -0
  32. data/spec/web/server/base_spec.rb +86 -0
  33. data/spec/web/server/classes/files/dir/file.txt +1 -0
  34. data/spec/web/server/classes/files/dir/index.html +1 -0
  35. data/spec/web/server/classes/files/dir2/file2.txt +1 -0
  36. data/spec/web/server/classes/files/dir3/page.xml +4 -0
  37. data/spec/web/server/classes/files/file.txt +1 -0
  38. data/spec/web/server/classes/files_app.rb +27 -0
  39. data/spec/web/server/classes/hosts_app.rb +40 -0
  40. data/spec/web/server/classes/proxy_app.rb +45 -0
  41. data/spec/web/server/classes/public1/static1.txt +1 -0
  42. data/spec/web/server/classes/public2/static2.txt +1 -0
  43. data/spec/web/server/classes/sub_app.rb +13 -0
  44. data/spec/web/server/classes/test_app.rb +20 -0
  45. data/spec/web/server/files_spec.rb +74 -0
  46. data/spec/web/server/helpers/server.rb +42 -0
  47. data/spec/web/server/hosts_spec.rb +55 -0
  48. data/spec/web/server/proxy_spec.rb +49 -0
  49. data/tasks/spec.rb +1 -0
  50. data/tasks/yard.rb +13 -0
  51. metadata +76 -17
  52. metadata.gz.sig +0 -0
  53. data/TODO.txt +0 -7
  54. data/lib/ronin/sessions/web.rb +0 -80
  55. data/lib/ronin/web/fingerprint.rb +0 -76
  56. data/spec/web/server_spec.rb +0 -142
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,28 @@
1
+ === 0.2.0 / 2009-09-24
2
+
3
+ * Require ronin >= 0.3.0.
4
+ * Require mechanize >= 0.9.3.
5
+ * Require sinatra >= 0.9.4.
6
+ * Require rspec >= 1.2.8.
7
+ * Require test-unit >= 1.2.3.
8
+ * Require rack-test >= 0.4.1.
9
+ * Require yard >= 0.2.3.5.
10
+ * Added Ronin::Web::Server::Base.
11
+ * Added Ronin::Web::Server::Files.
12
+ * Added Ronin::Web::Server::Hosts.
13
+ * Added Ronin::Web::Server::Proxy.
14
+ * Added Ronin::Web::Server::Helpers.
15
+ * Added Ronin::Web::Server::Helpers::Files.
16
+ * Added Ronin::Web::Server::Helpers::Hosts.
17
+ * Added Ronin::Web::Server::Helpers::Proxy.
18
+ * Added Ronin::Web::Server::App.
19
+ * Added Ronin::Web.server.
20
+ * Renamed Ronin::Sessions::Web to Ronin::Network::Helpers::Web.
21
+ * Moved to YARD based documentation.
22
+ * Updated the project summary and 3-point description for Ronin Web.
23
+ * Refactored the Ronin::Web::Server to build ontop of Sinatra.
24
+ * Refactored Ronin::Network::Helpers::Web.
25
+
1
26
  === 0.1.3 / 2009-07-02
2
27
 
3
28
  * Use Hoe >= 2.0.0.
@@ -1,10 +1,8 @@
1
1
  History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
- TODO.txt
5
4
  Rakefile
6
5
  bin/ronin-web
7
- lib/ronin/sessions/web.rb
8
6
  lib/ronin/web.rb
9
7
  lib/ronin/web/extensions.rb
10
8
  lib/ronin/web/extensions/nokogiri.rb
@@ -14,16 +12,50 @@ lib/ronin/web/extensions/nokogiri/xml/text.rb
14
12
  lib/ronin/web/extensions/nokogiri/xml/attr.rb
15
13
  lib/ronin/web/extensions/nokogiri/xml/element.rb
16
14
  lib/ronin/web/extensions/nokogiri/xml/document.rb
17
- lib/ronin/web/fingerprint.rb
18
15
  lib/ronin/web/server.rb
16
+ lib/ronin/web/server/helpers.rb
17
+ lib/ronin/web/server/helpers/rendering.rb
18
+ lib/ronin/web/server/helpers/files.rb
19
+ lib/ronin/web/server/helpers/hosts.rb
20
+ lib/ronin/web/server/helpers/proxy.rb
21
+ lib/ronin/web/server/helpers/files.rb
22
+ lib/ronin/web/server/helpers/hosts.rb
23
+ lib/ronin/web/server/base.rb
24
+ lib/ronin/web/server/files.rb
25
+ lib/ronin/web/server/hosts.rb
26
+ lib/ronin/web/server/proxy.rb
27
+ lib/ronin/web/server/app.rb
28
+ lib/ronin/web/server/web.rb
19
29
  lib/ronin/web/proxy.rb
30
+ lib/ronin/web/proxy/base.rb
31
+ lib/ronin/web/proxy/app.rb
32
+ lib/ronin/web/proxy/web.rb
20
33
  lib/ronin/web/spider.rb
21
34
  lib/ronin/web/web.rb
22
35
  lib/ronin/web/version.rb
36
+ lib/ronin/network/helpers/web.rb
23
37
  tasks/spec.rb
38
+ tasks/yard.rb
24
39
  spec/spec_helper.rb
25
40
  spec/web/helpers/server.rb
26
41
  spec/web/helpers/root/index.html
27
42
  spec/web/helpers/root/test.txt
28
43
  spec/web/extensions/nokogiri_spec.rb
29
- spec/web/server_spec.rb
44
+ spec/web/server/classes/public1/static1.txt
45
+ spec/web/server/classes/public2/static2.txt
46
+ spec/web/server/classes/files/dir/file.txt
47
+ spec/web/server/classes/files/dir/index.html
48
+ spec/web/server/classes/files/dir2/file2.txt
49
+ spec/web/server/classes/files/dir3/page.xml
50
+ spec/web/server/classes/files/file.txt
51
+ spec/web/server/classes/sub_app.rb
52
+ spec/web/server/classes/test_app.rb
53
+ spec/web/server/classes/files_app.rb
54
+ spec/web/server/classes/hosts_app.rb
55
+ spec/web/server/classes/proxy_app.rb
56
+ spec/web/server/helpers/server.rb
57
+ spec/web/server/base_spec.rb
58
+ spec/web/server/files_spec.rb
59
+ spec/web/server/hosts_spec.rb
60
+ spec/web/server/proxy_spec.rb
61
+ spec/web/proxy/base_spec.rb
data/README.txt CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  * http://ronin.rubyforge.org/web/
4
4
  * http://github.com/postmodern/ronin-web
5
- * irc.freenode.net ##ronin
5
+ * irc.freenode.net #ronin
6
6
  * Postmodern (postmodern.mod3 at gmail.com)
7
7
 
8
8
  == DESCRIPTION:
@@ -10,52 +10,38 @@
10
10
  Ronin Web is a Ruby library for Ronin that provides support for web
11
11
  scraping and spidering functionality.
12
12
 
13
- Ronin is a Ruby platform designed for information security and data
14
- exploration tasks. Ronin allows for the rapid development and distribution
15
- of code over many of the common Source-Code-Management (SCM) systems.
13
+ Ronin is a Ruby platform for exploit development and security research.
14
+ Ronin allows for the rapid development and distribution of code, exploits
15
+ or payloads over many common Source-Code-Management (SCM) systems.
16
16
 
17
- === Free
17
+ === Ruby
18
18
 
19
- All source code within Ronin is licensed under the GPL-2, therefore no user
20
- will ever have to pay for Ronin or updates to Ronin. Not only is the
21
- source code free, the Ronin project will not sell enterprise grade security
22
- snake-oil solutions, give private training classes or later turn Ronin into
23
- commercial software.
19
+ Ronin's Ruby environment allows security researchers to leverage Ruby with
20
+ ease. The Ruby environment contains a multitude of convenience methods
21
+ for working with data in Ruby, a Ruby Object Database, a customized Ruby
22
+ Console and an extendable command-line interface.
24
23
 
25
- === Modular
24
+ === Extend
26
25
 
27
- Ronin was not designed as one monolithic framework but instead as a
28
- collection of libraries which can be individually installed. This allows
29
- users to pick and choose what functionality they want in Ronin.
26
+ Ronin's more specialized features are provided by additional Ronin
27
+ libraries, which users can choose to install. These libraries can allow
28
+ one to write and run Exploits and Payloads, scan for PHP vulnerabilities,
29
+ perform Google Dorks or run 3rd party scanners.
30
30
 
31
- === Decentralized
31
+ === Publish
32
32
 
33
- Ronin does not have a central repository of exploits and payloads which
34
- all developers contribute to. Instead Ronin has Overlays, repositories of
35
- code that can be hosted on any CVS/SVN/Git/Rsync server. Users can then use
36
- Ronin to quickly install or update Overlays. This allows developers and
37
- users to form their own communities, independent of the main developers
38
- of Ronin.
33
+ Ronin allows users to publish and share code, exploits, payloads or other
34
+ data via Overlays. Overlays are directories of code and data that can be
35
+ hosted on any SVN, Hg, Git or Rsync server. Ronin makes it easy to create,
36
+ install or update Overlays.
39
37
 
40
- == FEATURES/PROBLEMS:
38
+ == FEATURES:
41
39
 
42
40
  * Web access (utilizing Mechanize and Nokogiri).
43
41
  * Integrates Spidr into Ronin::Web::Spider.
44
- * Provides Ronin::Web::Server, a customizable Rack based Web Server that
42
+ * Provides Ronin::Web::Server, a customizable Sinatra based Web Server that
45
43
  supports path and host-name routing.
46
- * Provides Ronin::Web::Proxy, a configurable Rack based Web Proxy.
47
-
48
- == REQUIREMENTS:
49
-
50
- * {nokogiri}[http://nokogiri.rubyforge.org/] >= 1.1.0
51
- * {mechanize}[http://mechanize.rubyforge.org/] >= 0.9.0
52
- * {spidr}[http://spidr.rubyforge.org/] >= 0.1.3
53
- * {rack}[http://rack.rubyforge.org/] >= 0.9.1
54
- * {ronin}[http://ronin.rubyforge.org/] >= 0.2.2
55
-
56
- == INSTALL:
57
-
58
- $ sudo gem install ronin-web
44
+ * Provides Ronin::Web::Proxy, a configurable Sinatra based Web Proxy.
59
45
 
60
46
  == SYNOPSIS:
61
47
 
@@ -81,11 +67,11 @@ of Ronin.
81
67
 
82
68
  Web.html(open('some_file.html'))
83
69
  # => <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
84
- <html>
85
- <head>
86
- <script type="text/javascript" src="redirect.js"></script>
87
- </head>
88
- </html>
70
+ # <html>
71
+ # <head>
72
+ # <script type="text/javascript" src="redirect.js"></script>
73
+ # </head>
74
+ # </html>
89
75
 
90
76
  * Build a HTML document:
91
77
 
@@ -98,19 +84,19 @@ of Ronin.
98
84
  end
99
85
 
100
86
  puts doc.to_html
101
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
102
- <html><head><script src="redirect.js" type="text/javascript"></script></head></html>
87
+ # <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
88
+ # <html><head><script src="redirect.js" type="text/javascript"></script></head></html>
103
89
 
104
90
  * Parse XML:
105
91
 
106
92
  Web.xml(some_text)
107
- => <?xml version="1.0"?>
108
- <users>
109
- <user>
110
- <name>admin</name>
111
- <password>0mni</password>
112
- </user>
113
- </users>
93
+ # => <?xml version="1.0"?>
94
+ # <users>
95
+ # <user>
96
+ # <name>admin</name>
97
+ # <password>0mni</password>
98
+ # </user>
99
+ # </users>
114
100
 
115
101
 
116
102
  * Build a XML document:
@@ -127,35 +113,52 @@ of Ronin.
127
113
  end
128
114
 
129
115
  puts doc.to_xml
130
- <?xml version="1.0"?>
131
- <playlist>
132
- <mp3>
133
- <file>02 THE WAIT.mp3</file>
134
- <artist>Evil Nine</artist>
135
- <track>The Wait feat David Autokratz</track>
136
- <duration>1000000000</duration>
137
- </mp3>
138
- </playlist>
116
+ # <?xml version="1.0"?>
117
+ # <playlist>
118
+ # <mp3>
119
+ # <file>02 THE WAIT.mp3</file>
120
+ # <artist>Evil Nine</artist>
121
+ # <track>The Wait feat David Autokratz</track>
122
+ # <duration>1000000000</duration>
123
+ # </mp3>
124
+ # </playlist>
139
125
 
140
126
  * Spider a web site:
141
127
 
142
128
  Web::Spider.host('www.example.com') do |spider|
143
129
  spider.every_url do |url|
144
- ...
130
+ # ...
145
131
  end
146
132
 
147
133
  spider.every_page do |page|
148
- ...
134
+ # ...
149
135
  end
150
136
  end
151
137
 
152
138
  * Serve files via a Web Server:
153
139
 
154
- Web::Server.start do |server|
155
- server.file '/opensearch.xml', '/tmp/test.xml'
156
- server.directory '/download/', '/tmp/download/'
140
+ require 'ronin/web/server'
141
+
142
+ Web.server do
143
+ file '/opensearch.xml', '/tmp/test.xml'
144
+ directory '/download/', '/tmp/download/'
157
145
  end
158
146
 
147
+ Web.server.get '/test' do
148
+ 'Test 1 2 1 2'
149
+ end
150
+
151
+ == REQUIREMENTS:
152
+
153
+ * {mechanize}[http://mechanize.rubyforge.org/] >= 0.9.3
154
+ * {spidr}[http://spidr.rubyforge.org/] >= 0.1.9
155
+ * {sinatra}[http://www.sinatrarb.com/] >= 0.9.4
156
+ * {ronin}[http://ronin.rubyforge.org/] >= 0.3.0
157
+
158
+ == INSTALL:
159
+
160
+ $ sudo gem install ronin-web
161
+
159
162
  == LICENSE:
160
163
 
161
164
  Ronin Web - A Ruby library for Ronin that provides support for web
data/Rakefile CHANGED
@@ -4,17 +4,26 @@ require 'rubygems'
4
4
  require 'hoe'
5
5
  require 'hoe/signing'
6
6
  require './tasks/spec.rb'
7
+ require './tasks/yard.rb'
7
8
 
8
9
  Hoe.spec('ronin-web') do
9
10
  self.rubyforge_name = 'ronin'
10
11
  self.developer('Postmodern', 'postmodern.mod3@gmail.com')
11
12
  self.remote_rdoc_dir = 'docs/ronin-web'
12
13
  self.extra_deps = [
13
- ['mechanize', '>=0.9.0'],
14
+ ['mechanize', '>=0.9.3'],
14
15
  ['spidr', '>=0.1.9'],
15
- ['rack', '>=1.0.0'],
16
- ['ronin', '>=0.2.4']
16
+ ['sinatra', '>=0.9.4'],
17
+ ['ronin', '>=0.3.0']
17
18
  ]
19
+
20
+ self.extra_dev_deps = [
21
+ ['rspec', '>=1.2.8'],
22
+ ['test-unit', '=1.2.3'],
23
+ ['rack-test', '>=0.4.1']
24
+ ]
25
+
26
+ self.spec_extras = {:has_rdoc => 'yard'}
18
27
  end
19
28
 
20
29
  # vim: syntax=Ruby
@@ -11,4 +11,4 @@ require 'ronin/ui/command_line/commands/console'
11
11
  require 'ronin/ui/console'
12
12
 
13
13
  Ronin::UI::Console.auto_load << 'ronin/web'
14
- Ronin::UI::CommandLine::Commands::Console.run(*ARGV)
14
+ Ronin::UI::CommandLine::Commands::Console.start
@@ -0,0 +1,221 @@
1
+ #
2
+ # Ronin Web - A Ruby library for Ronin that provides support for web
3
+ # scraping and spidering functionality.
4
+ #
5
+ # Copyright (c) 2006-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
+ #
21
+
22
+ require 'ronin/network/helpers/helper'
23
+ require 'ronin/network/http/proxy'
24
+ require 'ronin/web/web'
25
+
26
+ module Ronin
27
+ module Network
28
+ module Helpers
29
+ module Web
30
+ include Helper
31
+
32
+ protected
33
+
34
+ #
35
+ # Combines the proxy information set by the +@web_proxy_host+,
36
+ # +@web_proxy_port+, +@web_proxy_user+ and +@web_proxy_password+
37
+ # instance variables.
38
+ #
39
+ # @return [Network::HTTP::Proxy]
40
+ # The current proxy information.
41
+ #
42
+ def web_proxy
43
+ HTTP::Proxy.new(
44
+ :host => @web_proxy_host,
45
+ :port => @web_proxy_port,
46
+ :user => @web_proxy_user,
47
+ :password => @web_proxy_password
48
+ )
49
+ end
50
+
51
+ #
52
+ # Provides a persistant Mechanize agent.
53
+ #
54
+ # @param [Hash] options
55
+ # Additional options for initializing the agent.
56
+ #
57
+ # @option options [Hash] :proxy (web_proxy)
58
+ # Proxy information.
59
+ #
60
+ # @option options [String] :user_agent (+@web_user_agent+)
61
+ # User-Agent string to use.
62
+ #
63
+ # @return [WWW::Mechanize]
64
+ # The agent.
65
+ #
66
+ def web_agent(options={},&block)
67
+ unless @web_agent
68
+ options[:proxy] ||= web_proxy
69
+ options[:user_agent] ||= @web_user_agent
70
+
71
+ @web_agent = Ronin::Web.agent(options,&block)
72
+ end
73
+
74
+ return @web_agent
75
+ end
76
+
77
+ #
78
+ # Creates a Mechanize Page for the contents at a given URL.
79
+ #
80
+ # @param [URI::Generic, String] url
81
+ # The URL to request.
82
+ #
83
+ # @param [Hash] options
84
+ # Additional options to initialize the agent with.
85
+ #
86
+ # @option options [Hash] :proxy (web_proxy)
87
+ # Proxy information.
88
+ #
89
+ # @option options [String] :user_agent (+@web_user_agent+)
90
+ # User-Agent string to use.
91
+ #
92
+ # @yield [page]
93
+ # If a block is given, it will be passed the page for the
94
+ # requested URL.
95
+ #
96
+ # @yieldparam [WWW::Mechanize::Page] page
97
+ # The requested page.
98
+ #
99
+ # @return [WWW::Mechanize::Page]
100
+ # The requested page.
101
+ #
102
+ def web_get(url,options={},&block)
103
+ page = web_agent(options).get(url)
104
+
105
+ block.call(page) if block
106
+ return page
107
+ end
108
+
109
+ #
110
+ # Requests the body of the Mechanize Page created from the response
111
+ # of the given URL.
112
+ #
113
+ # @param [URI::Generic, String] url
114
+ # The URL to request.
115
+ #
116
+ # @param [Hash] options
117
+ # Additional options to initialize the agent with.
118
+ #
119
+ # @option options [Hash] :proxy (web_proxy)
120
+ # Proxy information.
121
+ #
122
+ # @option options [String] :user_agent (+@web_user_agent+)
123
+ # User-Agent string to use.
124
+ #
125
+ # @yield [body]
126
+ # If a block is given, it will be passed the body of the page.
127
+ #
128
+ # @yieldparam [String] body
129
+ # The requested body of the page.
130
+ #
131
+ # @return [String]
132
+ # The requested body of the page.
133
+ #
134
+ def web_get_body(url,options={},&block)
135
+ web_get(url,options) do |page|
136
+ body = page.body
137
+
138
+ block.call(body) if block
139
+ return body
140
+ end
141
+ end
142
+
143
+ #
144
+ # Posts to a given URL and creates a Mechanize Page from the
145
+ # response.
146
+ #
147
+ # @param [URI::Generic, String] url
148
+ # The URL to post to.
149
+ #
150
+ # @param [Hash] options
151
+ # Additional options to initialize the agent with.
152
+ #
153
+ # @option options [Hash] :query
154
+ # Additional query parameters to post with.
155
+ #
156
+ # @option options [Hash] :proxy (web_proxy)
157
+ # Proxy information.
158
+ #
159
+ # @option options [String] :user_agent (+@web_user_agent+)
160
+ # User-Agent string to use.
161
+ #
162
+ # @yield [page]
163
+ # If a block is given, it will be passed the page for the
164
+ # requested URL.
165
+ #
166
+ # @yieldparam [WWW::Mechanize::Page] page
167
+ # The requested page.
168
+ #
169
+ # @return [WWW::Mechanize::Page]
170
+ # The requested page.
171
+ #
172
+ def web_post(url,options={},&block)
173
+ query = {}
174
+ query.merge!(options[:query]) if options[:query]
175
+
176
+ page = web_agent(options).post(url)
177
+
178
+ block.call(page) if block
179
+ return page
180
+ end
181
+
182
+ #
183
+ # Posts to a given URL and returns the body of the Mechanize Page
184
+ # created from the response.
185
+ #
186
+ # @param [URI::Generic, String] url
187
+ # The URL to post to.
188
+ #
189
+ # @param [Hash] options
190
+ # Additional options to initialize the agent with.
191
+ #
192
+ # @option options [Hash] :query
193
+ # Additional query parameters to post with.
194
+ #
195
+ # @option options [Hash] :proxy (web_proxy)
196
+ # Proxy information.
197
+ #
198
+ # @option options [String] :user_agent (+@web_user_agent+)
199
+ # User-Agent string to use.
200
+ #
201
+ # @yield [body]
202
+ # If a block is given, it will be passed the body of the page.
203
+ #
204
+ # @yieldparam [WWW::Mechanize::Page] page
205
+ # The body of the requested page.
206
+ #
207
+ # @return [String]
208
+ # The requested body of the page.
209
+ #
210
+ def web_post_body(url,options={},&block)
211
+ web_post(url,options) do |page|
212
+ body = page.body
213
+
214
+ block.call(body) if block
215
+ return body
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end