import httplib, urllib

class HTTPAppTester:
    def __init__(self,host, debug=0, secure=0):
        self.__cookies = {}
        self.__h=None
        self.__host=host
        self.__debug=debug
        self.__use_https = secure
        self.__last_response_headers = None


    # POST data to a url
    def post_form(self, url, params, send_cookies=0):
       
        self.__connect()

        params = self.__encode_params(params)

        self.__h.putrequest('POST',url)
        self.__h.putheader("Content-type", "application/x-www-form-urlencoded")
        self.__h.putheader("Content-length", "%d" % len(params))
        self.__h.putheader('Accept', '*/*')
        self.__h.putheader('Host', self.__host)

        if send_cookies:
            self.__send_cookies()

        self.__h.endheaders()
        self.__h.send(params)
        data = self.__get_response()
        return data


    # GET a url
    def get_page(self, url, params, send_cookies=0):

        self.__connect()

        params = self.__encode_params(params)
   
        if params:
            url = "%s?%s" %(url,params)
        self.__h.putrequest('GET',url)
        self.__h.putheader('Accept', '*/*')
        self.__h.putheader('Host', self.__host)

        if send_cookies:
            self.__send_cookies()

        self.__h.endheaders()
        data = self.__get_response()
        return data


    # return list of stored cookies
    def getCookies(self):
        return self.__cookies


    def getLastResponseHeaders(self, usemime=0):
    
        # usemime means that you want a mimetools.Message instance back
        if usemime:
            return self.__last_response_headers
            
        # this returns a list of headers as strings
        return self.__last_response_headers.headers



    # ============ internal-only methods ======

    def __connect(self, server=''):

        self.__last_response_headers = None
        
        # determine which host to which to connect
        if not server:
            server=self.__host

        # either secure or insecure http protocol
        if self.__use_https:
            self.__h = httplib.HTTPS(server)
        else:
            self.__h = httplib.HTTP(server)

        # add debug, if requested
        if self.__debug:
            self.__h.set_debuglevel(99)


    # mimetools.Message expected
    def __parse_headers(self):

        for header in self.__last_response_headers.headers:
            param, value = header.split(': ', 1) 
                
            # pull out any cookies
            if param.find('Set-Cookie') == 0:
                base_cookie = value.split('; ')[0]
                name,value = base_cookie.split('=',1)
                self.__cookies[name] = value
               
     
    # get http response from server
    def __get_response(self):

        reply, message, self.__last_response_headers = self.__h.getreply()
        self.__parse_headers()
        data = self.__h.getfile().read() # get the raw HTML
        return data


    def __send_cookies(self):
            
        cookie_headers = []
        for cookie in self.__cookies.keys():
            name = cookie
            value = self.__cookies[name]
            cookie_headers.append('%s=%s' %(name,value))

        if len(cookie_headers):
            self.__h.putheader('Cookie', '; '.join(cookie_headers))


    def __encode_params(self,params={}):
        return urllib.urlencode(params)
