#coding:utf-8
class DCPatronClient < Patron::Session
  attr_accessor :get_header,:post_header,:cookie,:cookie_hash
  private:initialize
  def initialize
    super
    @cookie_hash = {"SINFORSESSID"=>"","LifeTime"=>"3600","PHPSESSID"=>""}
  end
  def DCPatronClient.get_client(url, connect_timeout=120000, insecure=true)
    @sess = DCPatronClient.new
    @sess.insecure = insecure
    @sess.base_url = url
    @sess.connect_timeout = connect_timeout
    @sess.timeout = connect_timeout/1000
    #@sess.handle_cookies  # req.headers = self.headers.merge(headers),由于需要手动维护cookie,因此这里不需要加上内部的维护
    @sess.get_header={"User-Agent"=>" Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.0C; .NET4.0E)"}
    @sess.post_header={"User-Agent"=>" Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.0C; .NET4.0E)"}
    return @sess
  end
  #构造post请求
  def form_post(uri, data)
    @post_header["Content-Type"]= "application/x-www-form-urlencoded"
   # ATT::KeyLog::debug "uri:#{uri},data:#{data}"
    ret=nil
    times = 0
    2.times do
      begin
        ret = super_post(uri, data, @post_header)
        times +=1
      rescue Patron::Error
        ret=nil
        if $!.to_s.include?("transfer closed with outstanding read data remaining")#修改登录端口会返回此错误,实际修改成功
          ret.body = "{\"success\":true,\"data\":[],\"total\":4,\"time\":0,\"img\":null}"
        end
        ATT::KeyLog.info("#{$!.to_s},http error,retrying...")
      rescue JSON::ParserError
        ATT::KeyLog.info("#{$!.to_s},need to login,retrying...")
        if not islogin?(ret) && times >0
          relogin
        else
          ATT::KeyLog.error("json parse error,server response:#{ret.body[0..20]}")
        end
        ret=nil
      rescue
        ret=nil
        sleep(10)
        ATT::KeyLog.info("#{$!.to_s},other error,retrying...")
      end
      break unless ret==nil
    end
    res = OpenStruct.new
    res.url = ret.url
    res.status = ret.status
    res.status_line = ret.status_line
    res.redirect_count = ret.redirect_count
    res.headers = ret.headers
    if res.status.to_s[0,1] != "2"
      res.body = "{\"success\":false, \"msg\":\"response error, code: #{ret.status}\", \"errorno\":-8}"
    else
      if ret.body.index(":undefined")#修正json返回不标准的情况
        ret.body.gsub!(":undefined",":false")
      end
         #ATT::KeyLog::debug  "status_line:#{ret.status_line},header:#{ret.headers},body:#{ret.body}"
      hash = JSON.parse(ret.body)
      if hash["success"] == true
        hash.store("errorno", 0)
        hash.store("msg", "default success msg while original msg is null") if hash["data"].nil?
      elsif hash["success"] == false && hash["msg"].to_s ==""
        hash.store("errorno", -255)
        hash.store("success", false)
        hash.store("msg", "unknow error type")
      end
      res.body = hash.to_json
    end
    return res
  end
  def islogin?(ret)
    begin
      if ret.body.include?("ActiveX")&&ret.body.include?("Dkey")
        return false
      else
        return true
      end
    rescue
      return false
    end
  end
  def hash_to_comma(hash)
    ret = ""
    hash.each {|key, value| ret = "#{key}=#{value};#{ret}"}
    return ret
  end
  def super_post(uri, data, header={})
    #ATT::KeyLog::debug "uri:#{uri},data:#{data}"
    Patron::Session.instance_method("post").bind(self).call(uri, data, header)
  end
  def relogin
    passwd=Digest::MD5.hexdigest($dcpasswd)
    ATT::KeyLog.info("relogin user:#{$user} password:#{$dcpasswd},MD5:#{passwd}")
    login_query = "login_user=#{$user}&login_password=#{passwd}&login_pin=&in=&pwd=&dkey=&login=true"
    ret =  super_post("/src/acloglogin.php",login_query,@get_header)
    #如果有set cookie,则表示需要提取cookie啦!~
    #    @cookie = ret.headers["Set-Cookie"].to_s=="" ? @cookie : ret.headers["Set-Cookie"].split(";")[0]  #PHPSESSID=d1a4cfefb265cc2cb1f3ccdd7cdb437e; path=/
    #    @cookie += ";LifeTime=3600; SINFORSESSID="
    #    @post_header["Cookie"] = @cookie+Time.now.to_i.to_s
    @cookie_hash = {"SINFORSESSID"=>"","LifeTime"=>"3600","PHPSESSID"=>""}
    @cookie_hash["PHPSESSID"] = ret.headers["Set-Cookie"].to_s=="" ? @cookie_hash["PHPSESSID"] : ret.headers["Set-Cookie"].split(";")[0]
    @cookie_hash["PHPSESSID"] = @cookie_hash["PHPSESSID"].split("=")[1] if @cookie_hash["PHPSESSID"].include?("PHPSESSID")
    @cookie_hash["SINFORSESSID"] = Time.now.to_i.to_s
    @post_header["Cookie"] = hash_to_comma(@cookie_hash) 
    @post_header["Content-Type"]= "application/json"
    @post_header["x-requested-with"]= "XMLHttpRequest"
    if islogin?(ret)
      ATT::KeyLog.info "Login datacenter ok..."
      return true
    else
      ATT::KeyLog.error "Login datacenter error:#{ret.body[0..20]}..."
      return false
    end
  end
  def logout
    ret = get("/src/acloglogin.php?in=1&logout=1",@get_header)
    ATT::KeyLog.info "logout query ret:#{ret}"
  end
  def hash_to_and(hash)
    ret = ""
    hash.each do |key, value|
      if value.class == String
        ret = "#{key}=#{URI.encode(value)}&#{ret}"
      else
        ret = "#{key}=#{value}&#{ret}"
      end
    end
    ret
  end
  #封装get请求
  def get(url, data)
    get_header = @post_header
    get_header["Content-Type"]= "application/x-www-form-urlencoded"
    get_header.delete("x-requested-with")
    uri = nil
    uri = url
    if data != nil
      if uri.to_s.include?("?")
        uri << "&"
      else
        uri << "?"
      end
      uri << hash_to_and(data)
    end
    ATT::KeyLog.info("uri:#{uri}")
    return super(uri,get_header)   //问题
  end
end
在调用 get 的方法后,重复调用,uri 的值会重复累加,请问该如何解决保证每次处理 uri 的值不累加?