自己写一个小型的Proxy,Part I(2)

写完get,该写post了,我们使用Mechanize,
gem install Mechanize,

定义如下方法:
def initialize_agent
   if session[:agent_id].nil?
    @agent = new_www_agent

    @agent.model = Agent.new
    @agent.model.save!
    session[:agent_id] = @agent.model.id
   else
    model = Agent.find(session[:agent_id])
    @agent = new_www_agent
    @agent.model = model #is this necessary?
    #todo,otherwise should reset cookie_jar?
    if @agent.model.cookie_jar.nil? or @agent.model.cookie_jar.empty?
      @agent.cookie_jar.clear!
    else
      @agent.cookie_jar = YAML.load(@agent.model.cookie_jar)
    end
   end

  end

  def new_www_agent
   agent = WWW::Mechanize.new
   agent.log = logger
   agent.user_agent_alias = 'Windows IE 6'
   agent.max_history = 1 #should be per user agent?
   agent.redirect_ok = true
   class << agent
    attr_accessor :model
   end
   agent
  end

  def dump_agent
   @agent.model.cookie_jar = @agent.cookie_jar
   @agent.model.save! #default use YAML format
   #puts YAML.dump(@agent)
  end
(生成一个agent model: ruby script/generate model agent)
来保存agent的相关状态.

ok,开始do_post,前面我们已经用get取回相关的代码页了:

def do_post

   puts "posting #{@url}"
   @url = "http://"+ @url unless URI(@url).scheme

   fix_params #去除action,controller,id这些特定的php?name=rails" onclick="tagshow(event)" class="t_tag">rails参数

   @page = @agent.post(@url, params) #调用Mechanize本身的post方法,把其他的参数forward过去

   @doc = @page.search("")


   rewrite_link_for_doc(@doc)

   url_handle(@url, @doc, self)

   render :text=>fix_result,
      :content_type => fix_contentType

  end
该写一下get,也用Mechanize,:
def index
   #test_akismet
   @url = params[:id] || params[:q]

   if request.post?
    do_post()
   else
    do_get()
   end

  end

def do_get
   puts "fetching #{@url}" #if request.get?
   @url = "http://"+ @url unless URI(@url).scheme


   @page = @agent.get(@url)
   @doc = @page.search("")


   rewrite_link_for_doc(@doc)
   url_handle(@url, @doc, self)


   render :text=>fix_result,
      :content_type => fix_contentType
  end
接下来就该定义url_handler方法了