0
@@ -15,8 +15,9 @@ require 'net/http'
0
require 'web/htmltools/xmltree' # narf
0
require 'mechanize/module'
0
require 'mechanize/mech_version'
0
@@ -134,7 +135,9 @@ class Mechanize
0
cur_page = current_page || Page.new( nil, {'content-type'=>'text/html'})
0
- page = fetch_page(to_absolute_uri(url, cur_page), :get, cur_page)
0
+ abs_uri = to_absolute_uri(url, cur_page)
0
+ request = fetch_request(abs_uri)
0
+ page = fetch_page(abs_uri, request, cur_page)
0
@@ -218,6 +221,17 @@ class Mechanize
0
! @history.find { |h| h.uri.to_s == uri.to_s }.nil?
0
+ # Runs given block, then resets the page history as it was before. self is
0
+ # given as a parameter to the block. Returns the value of the block.
0
+ history_backup = @history.dup
0
+ @history = history_backup
0
alias :page :current_page
0
@@ -244,30 +258,40 @@ class Mechanize
0
def post_form(url, form)
0
cur_page = current_page || Page.new(nil, {'content-type'=>'text/html'})
0
- request_data =
[form.request_data]0
+ request_data =
form.request_data0
- # this is called before the request is sent
0
- pre_request_hook = proc {|request|
0
- log.debug("query: #{ request_data.inspect }")
0
- request.add_field('Content-Type', form.enctype)
0
- request.add_field('Content-Length', request_data[0].size.to_s)
0
+ abs_url = to_absolute_uri(url, cur_page)
0
+ request = fetch_request(abs_url, :post)
0
+ request.add_field('Content-Type', form.enctype)
0
+ request.add_field('Content-Length', request_data.size.to_s)
0
+ log.debug("query: #{ request_data.inspect }") if log
0
- page = fetch_page(
to_absolute_uri(url, cur_page), :post, cur_page, pre_request_hook, request_data)
0
+ page = fetch_page(
abs_url, request, cur_page, [request_data])
0
+ # Creates a new request object based on the scheme and type
0
+ def fetch_request(uri, type = :get)
0
+ raise "unsupported scheme" unless ['http', 'https'].include?(uri.scheme)
0
+ Net::HTTP::Get.new(uri.request_uri)
0
+ Net::HTTP::Post.new(uri.request_uri)
0
# uri is an absolute URI
0
- def fetch_page(uri,
method=:get, cur_page=current_page(), pre_request_hook=nil, request_data=[])
0
+ def fetch_page(uri,
request, cur_page=current_page(), request_data=[])
0
raise "unsupported scheme" unless ['http', 'https'].include?(uri.scheme)
0
- log.info("#{
method.to_s.upcase }: #{ uri.to_s }")0
+ log.info("#{
request.class }: #{ uri.to_s }") if log0
- http
= Net::HTTP.new( uri.host,
0
+ http
_obj = Net::HTTP.new( uri.host,
0
@@ -276,68 +300,55 @@ class Mechanize
0
if uri.scheme == 'https'
0
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
0
+ http_obj.use_ssl = true
0
+ http_obj.verify_mode = OpenSSL::SSL::VERIFY_NONE
0
- http.ca_file = @ca_file
0
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
0
+ http_obj.ca_file = @ca_file
0
+ http_obj.verify_mode = OpenSSL::SSL::VERIFY_PEER
0
- http.cert = OpenSSL::X509::Certificate.new(::File.read(@cert))
0
- http.key = OpenSSL::PKey::RSA.new(::File.read(@key), @pass)
0
+ http_obj.cert = OpenSSL::X509::Certificate.new(::File.read(@cert))
0
+ http_obj.key = OpenSSL::PKey::RSA.new(::File.read(@key), @pass)
0
+ request.add_field('Accept-Encoding', 'gzip,identity')
0
- request = Net::HTTP::Get.new(uri.request_uri)
0
- request = Net::HTTP::Post.new(uri.request_uri)
0
- unless @cookie_jar.empty?(uri)
0
- cookies = @cookie_jar.cookies(uri)
0
- cookie = cookies.length > 0 ? cookies.join("; ") : nil
0
- log.debug("use cookie: #{ cookie }")
0
- request.add_field('Cookie', cookie)
0
- # Add Referer header to request
0
- unless cur_page.uri.nil?
0
- request.add_field('Referer', cur_page.uri.to_s)
0
+ unless @cookie_jar.empty?(uri)
0
+ cookies = @cookie_jar.cookies(uri)
0
+ cookie = cookies.length > 0 ? cookies.join("; ") : nil
0
+ log.debug("using cookie: #{c}")
0
+ request.add_field('Cookie', cookie)
0
- # Add User-Agent header to request
0
- request.add_field('User-Agent', @user_agent) if @user_agent
0
- request.basic_auth(@user, @password) if @user
0
- # Invoke pre-request-hook (use it to add custom headers or content)
0
+ # Add Referer header to request
0
+ unless cur_page.uri.nil?
0
+ request.add_field('Referer', cur_page.uri.to_s)
0
- pre_request_hook.call(request) if pre_request_hook
0
+ # Add User-Agent header to request
0
+ request.add_field('User-Agent', @user_agent) if @user_agent
0
-
# Log specified headers for the request0
+
request.basic_auth(@user, @password) if @user0
+ # Log specified headers for the request
0
request.each_header do |k, v|
0
log.debug("request-header: #{ k } => #{ v }")
0
+ http_obj.start { |http|
0
# Specify timeouts if given
0
http.open_timeout = @open_timeout if @open_timeout
0
http.read_timeout = @read_timeout if @read_timeout
0
http.request(request, *request_data) {|response|
0
(response.get_fields('Set-Cookie')||[]).each do |cookie|
0
log.debug("cookie received: #{ cookie }")
0
Cookie::parse(uri, cookie) { |c| @cookie_jar.add(c) }
0
@@ -355,12 +366,24 @@ class Mechanize
0
content_type = data[1].downcase unless data.nil?
0
+ if encoding = response['Content-Encoding']
0
+ case encoding.downcase
0
+ log.debug('gunzip body') if log
0
+ Zlib::GzipReader.new(StringIO.new(response.body)).read
0
+ raise 'Unsupported content encoding'
0
# Find our pluggable parser
0
page = @pluggable_parser.parser(content_type).new(
0
@@ -375,11 +398,15 @@ class Mechanize
0
log.info("follow redirect to: #{ response['Location'] }")
0
- return fetch_page(to_absolute_uri(URI.parse(response['Location'].gsub(/ /, '%20')), page), :get, page)
0
+ abs_uri = to_absolute_uri(
0
+ URI.escape(URI.unescape(response['Location'].to_s))), page)
0
+ request = fetch_request(abs_uri)
0
+ return fetch_page(abs_uri, request, page)
0
raise ResponseCodeError.new(page.code), "Unhandled response", caller