lib/tap/mechanize/capture.rb in tap-mechanize-0.5.1 vs lib/tap/mechanize/capture.rb in tap-mechanize-0.6.0
- old
+ new
@@ -1,71 +1,72 @@
require 'tap/controller'
require 'tap/mechanize/utils'
require 'tap/ubiquity/utils'
+require 'uri'
module Tap
module Mechanize
# :startdoc::controller
# :startdoc::ubiquity
class Capture < Tap::Controller
include Tap::Mechanize::Utils
include Tap::Ubiquity::Utils
PREFIX = '__redirect_http_'
- REDIRECT_PARAMETER = '__redirect_http_original_action'
# Brings up the tutorial.
def index
- render 'index.erb', :locals => {:captures => persistence.index }
+ render 'index.erb', :locals => {:captures => data.index(:data) }
end
- def create(id, keep_content=true)
- persistence.create(id) do |io|
- io << YAML.dump([parse_request(keep_content)])
+ def create(id)
+ data.create(:data, id) do |io|
+ io << YAML.dump([parse_request])
end
download(id)
end
def show(id)
response['Content-Type'] = "text/plain"
- persistence.read(id)
+ data.read(:data, id)
end
def download(id)
- path = persistence.path(id)
+ path = data.path(:data, id)
filename = id
filename += ".yml" if File.extname(id) == ""
response['Content-Type'] = "text/plain"
response['Content-Disposition'] = "attachment; filename=#{filename};"
- persistence.read(id)
+ data.read(:data, id)
end
- def update(id="request", keep_content=true)
- path = persistence.path(id)
+ def update(id="request")
+ path = data.path(:data, id)
requests = File.exists?(path) ? YAML.load_file(path) : []
- requests << parse_request(keep_content)
+ requests << parse_request
- persistence.update(id) do |io|
+ data.create_or_update(:data, id) do |io|
io << YAML.dump(requests)
end
download(id)
end
def destroy(id)
- persistence.destroy(id)
+ data.destroy(:data, id)
redirect uri(:index)
end
# Brings up a tutorial teaching how to capture and resubmit forms.
def tutorial
- serve js_injection(:redirect_http) do |link|
- content = render 'tutorial.erb'
- content + link
- end
+ render 'tutorial.erb'
end
+ def command
+ serve js_injection(:redirect_http)
+ end
+
def test
render 'test.erb'
end
# Say is the target of the tutorial.
@@ -73,19 +74,30 @@
"<pre>#{request.params['words']}</pre>"
end
# Returns the redirection script.
def redirect_http
+
+ # note configs are formatted into the javascript; keys MUST be valid
+ # names, but values can be anything that converts to json
+ configs = [
+ [:submit_request, false],
+ [:keep_content, false],
+ [:keep_headers, false],
+ [:name, 'request']
+ ]
+
css = render 'redirect.css'
script = render 'redirect.js', :locals => {
- :redirect_parameter => REDIRECT_PARAMETER,
:redirect_action => uri(:update),
+ :configs => configs
}
content = render 'redirect_http.erb', :locals => {
:css => css,
- :script => script
+ :script => script,
+ :configs => configs
}
if request.get?
response['Content-Type'] = 'text/plain'
%Q{
@@ -135,38 +147,85 @@
# :locals => {:prefix => PREFIX}
def prefix # :nodoc:
PREFIX
end
- def capture_overloaded_parameters # :nodoc:
- # perform the actions of Rack::Request::POST, but capture
- # overloaded parameter names
+ def data
+ server.data
+ end
+
+ def uri(*args)
+ "http://#{server.host}:#{server.port}#{super}"
+ end
+
+ # Returns the data recieved in the query string.
+ def get_params
env = request.env
- env["rack.request.form_input"] = env["rack.input"]
- unless env["rack.request.form_hash"] = parse_multipart(env)
- env["rack.request.form_vars"] = env["rack.input"].read
- env["rack.request.form_hash"] = Rack::Utils.parse_query(env["rack.request.form_vars"])
- env["rack.input"].rewind if env["rack.input"].respond_to?(:rewind)
+ if env["rack.request.query_string"] == request.query_string
+ env["rack.request.query_hash"]
+ else
+ env["rack.request.query_string"] = request.query_string
+ env["rack.request.query_hash"] =
+ parse_query(request.query_string)
end
end
+ # Returns the data recieved in the request body.
+ #
+ # This method support both application/x-www-form-urlencoded and
+ # multipart/form-data.
+ def post_params
+ env = request.env
+ if env["rack.request.form_input"].eql? env["rack.input"]
+ env["rack.request.form_hash"]
+ elsif request.form_data?
+ env["rack.request.form_input"] = env["rack.input"]
+ unless env["rack.request.form_hash"] =
+ Rack::Utils::Multipart.parse_multipart(env)
+ form_vars = env["rack.input"].read
+
+ # Fix for Safari Ajax postings that always append \0
+ form_vars.sub!(/\0\z/, '')
+
+ env["rack.request.form_vars"] = form_vars
+ env["rack.request.form_hash"] = parse_query(form_vars)
+
+ begin
+ env["rack.input"].rewind if env["rack.input"].respond_to?(:rewind)
+ rescue Errno::ESPIPE
+ # Handles exceptions raised by input streams that cannot be rewound
+ # such as when using plain CGI under Apache
+ end
+ end
+ env["rack.request.form_hash"]
+ else
+ {}
+ end
+ end
+
+ def capture_parameters # :nodoc:
+ get_params.update(post_params)
+ end
+
# helper to parse the request into a request hash for
# use by a Tap::Mechanize::Submit task
- def parse_request(keep_content=true) # :nodoc:
- if keep_content.kind_of?(String)
- keep_content = keep_content =~ /true/i
+ def parse_request
+ params = capture_parameters
+ capture_params = {}
+ params.each_key do |key|
+ if key =~ /#{prefix}/
+ normalize_params(capture_params, key, params.delete(key))
+ end
end
+ capture_params = capture_params[prefix]
- capture_overloaded_parameters
-
hash = {}
- parse_rack_request(request, keep_content).each_pair do |key, value|
+ parse_rack_request(request, params, capture_params['keep_content'] == "true").each_pair do |key, value|
hash[key.to_s] = value
end
- action = hash['params'].delete(REDIRECT_PARAMETER)
-
+ action = capture_params['original_action']
hash['uri'] = case action
when /^http/
# action is an href already
action
when /^\//
@@ -180,11 +239,13 @@
# make action relative to Referer
base = File.dirname(hash['headers']['Referer'].to_s)
File.join(base, action)
end
- # remove extranous data
- hash.delete('headers')
+ # remove extra data
+ unless capture_params['keep_headers'] == 'true'
+ hash.delete('headers')
+ end
hash.delete('version')
hash
end
\ No newline at end of file