ronin-web 0.1.3 → 0.2.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.
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