home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / util / asynchttp.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  19.3 KB  |  554 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. __author__ = '\nDownright Software LLC\nhttp://www.downright.com\n'
  5. __copyright__ = "\nCopyright (c) 2001 Downright Software LLC. All Rights Reserved.\n\nDistributed and Licensed under the provisions of the Python Open Source License\nAgreement which is included by reference. (See 'Front Matter' in the latest\nPython documentation)\n\nWARRANTIES\nYOU UNDERSTAND AND AGREE THAT:\n\na. YOUR USE OF THE PACKAGE IS AT YOUR SOLE RISK.  THE PACKAGE IS PROVIDED ON\nAN 'AS IS' AND 'AS AVAILABLE' BASIS.  DOWNRIGHT EXPRESSLY DISCLAIMS ALL\nWARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED\nTO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE\nAND NON-INFRINGEMENT.\n\nb. DOWNRIGHT MAKES NO WARRANTY THAT (1) THE PACKAGE WILL MEET YOUR\nREQUIREMENTS, (2) THE PACKAGE WILL BE UNINTERRUPTED, TIMELY, SECURE, OR\nERROR-FREE, (3) THE RESULTS THAT MAY BE OBTAINED FROM THE USE OF THE PACKAGE\nWILL BE ACCURATE OR RELIABLE, (4) THE OTHER MATERIAL PURCHASED OR OBTAINED BY\nYOU THROUGH THE PACKAGE WILL MEET YOUR EXPECTATIONS,, AND (5) ANY ERRORS IN\nTHE PACKAGE WILL BE CORRECTED.\n\nc. ANY MATERIALS DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE\nPACKAGE IS DONE AT YOUR OWN DISCRETION AND RISK AND THAT YOU WILL BE SOLELY\nRESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT\nRESULTS FROM THE DOWNLOAD OF ANY SUCH MATERIAL.\n\nd. NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM\nDOWNRIGHT OR THROUGH OR FROM THE PACKAGE SHALL CREATE ANY WARRANTY NOT\nEXPRESSLY STATED IN THE TOS.\n\nLIMITATION OF LIABILITY\nYOU EXPRESSLY UNDERSTAND AND AGREE THAT DOWNRIGHT SHALL NOT BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES,\nINCLUDING BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE,\nDATA OR OTHER INTANGIBLE LOSSES (EVEN IF DOWNRIGHT HAS BEEN ADVISED OF SUCH\nDAMAGES), RESULTING FROM:\n(1) THE USE OR THE INABILITY TO USE THE PACKAGE;\n(2) THE COST OF PROCUREMENT OF SUBSTITUTE GOODS AND SERVICES RESULTING FROM\nANY GOODS, DATA, INFORMATION OR SERVICES PURCHASED OR OBTAINED OR MESSAGES\nRECEIVED OR TRANSACTIONS ENTERED INTO THROUGH OR FROM THE PACKAGE;\n(3) UNAUTHORIZED ACCESS TO OR ALTERATION OF YOUR TRANSMISSIONS OR DATA;\n(4) STATEMENTS OF CONDUCT OF ANY THIRD PARTY ON THE PACKAGE; OR\n(5) ANY OTHER MATTER RELATING TO THE PACKAGE.\n"
  6. __version__ = '0.20'
  7. import sys
  8. import asynchat
  9. import asyncore
  10. import socket
  11. import time
  12. import string
  13. import StringIO
  14. import mimetools
  15. HTTP_PORT = 80
  16. HTTPS_PORT = 443
  17. import common
  18.  
  19. class AsyncHTTPResponse:
  20.     
  21.     def __init__(self, fp, debuglevel = 0):
  22.         self.fp = fp
  23.         self.debuglevel = debuglevel
  24.         self.msg = None
  25.         self._replyline = ''
  26.         self.status = None
  27.         self.reason = None
  28.         self.version = None
  29.  
  30.     
  31.     def _process_response(self):
  32.         self._replyline = self.fp.readline()
  33.         if self.debuglevel > 0:
  34.             print 'reply: %s' % self._replyline
  35.         
  36.         replylist = string.split(self._replyline, None, 2)
  37.         if len(replylist) == 3:
  38.             (version, status, reason) = replylist
  39.         elif len(replylist) == 2:
  40.             (version, status) = replylist
  41.             reason = ''
  42.         else:
  43.             raise BadStatusLine(self._replyline, name = str(self))
  44.         if len(replylist) == 3[:5] != 'HTTP/':
  45.             raise BadStatusLine(self._replyline, name = str(self))
  46.         len(replylist) == 3[:5] != 'HTTP/'
  47.         
  48.         try:
  49.             self.code = self.status = int(status)
  50.         except:
  51.             raise BadStatusLine(self._replyline, name = str(self))
  52.  
  53.         self.reason = string.strip(reason)
  54.         if version == 'HTTP/1.0':
  55.             self.version = 10
  56.         elif version.startswith('HTTP/1.'):
  57.             self.version = 11
  58.         else:
  59.             raise UnknownProtocol(self._replyline, name = str(self))
  60.         self.msg = (version == 'HTTP/1.0').Message(self.fp, 0)
  61.         if self.debuglevel > 0:
  62.             for hdr in self.msg.headers:
  63.                 print 'header: %s' % string.strip(hdr)
  64.             
  65.         
  66.         self.error = self.code // 100 != 2
  67.         self.body = None
  68.  
  69.     
  70.     def __str__(self):
  71.         return 'AsyncHTTPResponse %r' % self._replyline
  72.  
  73.     
  74.     def getheader(self, name, default = None):
  75.         if self.msg is None:
  76.             raise ResponseNotReady(name = str(self))
  77.         self.msg is None
  78.         return self.msg.getheader(name, default)
  79.  
  80.     
  81.     def getbody(self):
  82.         if self.body is None:
  83.             raise ResponseNotReady(name = str(self))
  84.         self.body is None
  85.         return self.body
  86.  
  87.     
  88.     def read(self, howmuch = -1):
  89.         return self.fp.read(howmuch)
  90.  
  91.     
  92.     def info(self):
  93.         return self.msg
  94.  
  95.  
  96. _CHUNK_REQUEST_SIZE = 8192
  97. _STATE_IDLE = 'asynchttp._STATE_IDLE'
  98. _STATE_CONNECTING = 'asynchttp._STATE_CONNECTING'
  99. _STATE_ACTIVE = 'asynchttp._STATE_ACTIVE'
  100. _STATE_ACCEPTING_HEADERS = 'asynchttp._STATE_ACCEPTING_HEADERS'
  101. _STATE_REQUESTING_BODY = 'asynchttp._STATE_REQUESTING_BODY'
  102. _STATE_CHUNK_START = 'asynchttp._STATE_CHUNK_START'
  103. _STATE_CHUNK_BODY = 'asynchttp._STATE_CHUNK_BODY'
  104. _STATE_CHUNK_RESIDUE = 'asynchttp._STATE_CHUNK_RESIDUE'
  105.  
  106. class AsyncHTTPConnection(common.socket):
  107.     _http_vsn = 11
  108.     _http_vsn_str = 'HTTP/1.1'
  109.     response_class = AsyncHTTPResponse
  110.     default_port = HTTP_PORT
  111.     auto_open = 1
  112.     debuglevel = 0
  113.     
  114.     def __init__(self, host = None, port = None):
  115.         self._TERMINATOR_MAP = {
  116.             _STATE_IDLE: self._no_action,
  117.             _STATE_CONNECTING: self._no_action,
  118.             _STATE_ACTIVE: self._no_action,
  119.             _STATE_ACCEPTING_HEADERS: self._header_data,
  120.             _STATE_REQUESTING_BODY: self._body_data,
  121.             _STATE_CHUNK_START: self._chunk_start_data,
  122.             _STATE_CHUNK_BODY: self._chunk_body_data,
  123.             _STATE_CHUNK_RESIDUE: self._chunk_residue_data }
  124.         self._AsyncHTTPConnection__state = None
  125.         self._AsyncHTTPConnection__set_state(_STATE_IDLE)
  126.         self._headerdict = { }
  127.         self._requestfp = None
  128.         self._responsefp = StringIO.StringIO()
  129.         self._chunkfp = None
  130.         self.response = self.response_class(self._responsefp, self.debuglevel)
  131.         self._set_hostport(host, port)
  132.         self._willclose = 0
  133.         import primitives.funcs as funcs
  134.         self._on_connect = funcs.Delegate()
  135.         common.socket.__init__(self, False)
  136.  
  137.     
  138.     def _set_hostport(self, host, port):
  139.         if host and port is None:
  140.             i = string.find(host, ':')
  141.             if i >= 0:
  142.                 port = int(host[i + 1:])
  143.                 host = host[:i]
  144.             else:
  145.                 port = self.default_port
  146.         
  147.         self.host = host
  148.         self.port = port
  149.  
  150.     
  151.     def set_debuglevel(self, level):
  152.         self.debuglevel = level
  153.  
  154.     
  155.     def connect(self):
  156.         self._AsyncHTTPConnection__set_state(_STATE_CONNECTING)
  157.         self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
  158.         if self.debuglevel > 0:
  159.             print 'connecting: (%s, %s)' % (self.host, self.port)
  160.         
  161.         import util.net as net
  162.         import socks
  163.         pi = net.GetProxyInfo()
  164.         use_proxy = True
  165.         host = self.host
  166.         port = self.port
  167.         if pi.get('proxytype', 0) == socks.PROXY_TYPE_HTTP:
  168.             use_proxy = False
  169.         
  170.         common.socket.connect(self, (host, port), use_proxy = use_proxy, error = self.handle_error)
  171.  
  172.     
  173.     def close(self):
  174.         if self.debuglevel > 0:
  175.             print 'asynchttp.close() (%s, %s)' % (self.host, self.port)
  176.         
  177.         self.connected = 0
  178.         if self.socket:
  179.             common.socket.close(self)
  180.         
  181.         self._set_hostport(None, None)
  182.  
  183.     
  184.     def send_entity(self, str):
  185.         if self.debuglevel > 0:
  186.             print 'send_entity %r' % str
  187.         
  188.         self._requestfp.write(str)
  189.  
  190.     
  191.     def putrequest(self, method, url):
  192.         if self.debuglevel > 0:
  193.             print 'putrequest %s %s' % (method, url)
  194.         
  195.         if self._AsyncHTTPConnection__state is not _STATE_ACTIVE:
  196.             raise RequestNotReady('Invalid putrequest() %s' % self._AsyncHTTPConnection__state, name = str(self))
  197.         self._AsyncHTTPConnection__state is not _STATE_ACTIVE
  198.         self._requestfp = StringIO.StringIO()
  199.         if not url:
  200.             url = '/'
  201.         
  202.         self._requestfp.write('%s %s %s\r\n' % (method, url, self._http_vsn_str))
  203.         if self._http_vsn == 11:
  204.             self.putheader('Host', self.host)
  205.             self.putheader('Accept-Encoding', 'identity')
  206.         
  207.  
  208.     
  209.     def putheader(self, header, value):
  210.         if self.debuglevel > 0:
  211.             print 'putheader %s: %s' % (header, value)
  212.         
  213.         self._headerdict[header] = value
  214.  
  215.     
  216.     def endheaders(self):
  217.         if self._AsyncHTTPConnection__state is not _STATE_ACTIVE:
  218.             self._on_connect += self.endheaders
  219.             return None
  220.         for header, value in self._headerdict.items():
  221.             self._requestfp.write('%s: %s\r\n' % (header, value))
  222.         
  223.         self._requestfp.write('\r\n')
  224.  
  225.     
  226.     def request(self, method, url, body = None, headers = { }):
  227.         if self.debuglevel > 0:
  228.             print 'request'
  229.         
  230.         if self._AsyncHTTPConnection__state is not _STATE_ACTIVE:
  231.             (None, None, self, self, self._on_connect) += (lambda : self.request(method, url, body, headers))
  232.             return None
  233.         self._send_request(method, url, body, headers)
  234.  
  235.     
  236.     def _send_request(self, method, url, body, headers):
  237.         if self.debuglevel > 0:
  238.             print '_send_request'
  239.         
  240.         self.putrequest(method, url)
  241.         if body:
  242.             self.putheader('Content-Length', str(len(body)))
  243.         
  244.         for hdr, value in headers.items():
  245.             self.putheader(hdr, value)
  246.         
  247.         self.endheaders()
  248.         if body:
  249.             self.send_entity(body)
  250.         
  251.  
  252.     
  253.     def getresponse(self):
  254.         if self._AsyncHTTPConnection__state is not _STATE_ACTIVE:
  255.             self._on_connect += self.getresponse
  256.             return self.response
  257.         self._AsyncHTTPConnection__set_state(_STATE_ACCEPTING_HEADERS)
  258.         self.push(self._requestfp.getvalue())
  259.         self._requestfp = None
  260.         self.set_terminator('\r\n\r\n')
  261.         return self.response
  262.  
  263.     
  264.     def handle_connect(self):
  265.         self._AsyncHTTPConnection__set_state(_STATE_ACTIVE)
  266.         if self.debuglevel > 0:
  267.             print 'connected: (%s, %s)' % (self.host, self.port)
  268.         
  269.         self._on_connect.call_and_clear()
  270.  
  271.     
  272.     def handle_close(self):
  273.         if self.debuglevel > 0:
  274.             print 'closed by server: (%s, %s) %s' % (self.host, self.port, self._AsyncHTTPConnection__state)
  275.         
  276.         common.socket.handle_close(self)
  277.         self.close()
  278.         if self._AsyncHTTPConnection__state in [
  279.             _STATE_REQUESTING_BODY,
  280.             _STATE_CHUNK_BODY,
  281.             _STATE_CHUNK_RESIDUE]:
  282.             self.found_terminator()
  283.             return None
  284.  
  285.     
  286.     def handle_error(self, why = None):
  287.         self._AsyncHTTPConnection__set_state(_STATE_IDLE)
  288.         common.socket.handle_error(self, why)
  289.  
  290.     
  291.     def collect_incoming_data(self, data):
  292.         if not self._responsefp:
  293.             raise UnexpectedData("%s '%s' '%s' '%s'" % (self._AsyncHTTPConnection__state, data, self.get_terminator(), self.ac_in_buffer), name = str(self))
  294.         self._responsefp
  295.         self._responsefp.write(data)
  296.  
  297.     
  298.     def _no_action(self):
  299.         raise UnexpectedTerminator("%s '%s'" % (self._AsyncHTTPConnection__state, self.get_terminator()), name = str(self))
  300.  
  301.     
  302.     def _header_data(self):
  303.         self._responsefp.seek(0)
  304.         self.response._process_response()
  305.         self._willclose = string.lower(self.response.getheader('connection', '')) == 'close'
  306.         transferencoding = string.lower(self.response.getheader('transfer-encoding', ''))
  307.         self._responsefp = StringIO.StringIO()
  308.         if transferencoding:
  309.             if transferencoding == 'chunked':
  310.                 self._chunkfp = StringIO.StringIO()
  311.                 self.set_terminator('\r\n')
  312.                 self._AsyncHTTPConnection__set_state(_STATE_CHUNK_START)
  313.                 return None
  314.             raise UnknownTransferEncoding(self.response.getheader('transfer-encoding', ''), name = str(self))
  315.         transferencoding
  316.         contentlengthstr = self.response.getheader('content-length', None)
  317.         if contentlengthstr:
  318.             contentlength = int(contentlengthstr)
  319.         else:
  320.             contentlength = None
  321.         self.set_terminator(contentlength)
  322.         self._AsyncHTTPConnection__set_state(_STATE_REQUESTING_BODY)
  323.  
  324.     
  325.     def _body_data(self):
  326.         self.response.body = self._responsefp.getvalue()
  327.         self._responsefp = None
  328.         if self._willclose:
  329.             self.close()
  330.         
  331.         self._AsyncHTTPConnection__set_state(_STATE_ACTIVE)
  332.         self.handle_response()
  333.  
  334.     
  335.     def _get_chunk_size(self):
  336.         splitlist = self._chunkbuffer.lstrip().split('\r\n', 1)
  337.         if len(splitlist) == 1:
  338.             chunkline = splitlist[0]
  339.             self._chunkbuffer = ''
  340.         else:
  341.             (chunkline, self._chunkbuffer) = splitlist
  342.         i = string.find(chunkline, ';')
  343.         if i >= 0:
  344.             chunkline = chunkline[:i]
  345.         
  346.         
  347.         try:
  348.             chunksize = string.atoi(chunkline, 16)
  349.         except:
  350.             raise InvalidChunk("Can't compute chunk size from '%s' '%s'" % (chunkline, self._chunkbuffer))
  351.  
  352.         if self.debuglevel > 0:
  353.             print "chunksize = '%d" % chunksize
  354.         
  355.         return chunksize
  356.  
  357.     
  358.     def _chunk_start_data(self):
  359.         self._chunkbuffer = self._responsefp.getvalue()
  360.         self._chunksize = self._get_chunk_size()
  361.         if self._chunksize == 0:
  362.             if self.debuglevel > 0:
  363.                 print '0 size Chunk: ending chunk processing'
  364.             
  365.             self.response.body = self._chunkfp.getvalue()
  366.             self._chunkfp = None
  367.             self.set_terminator('\r\n\r\n')
  368.             self._responsefp = StringIO.StringIO()
  369.             self._AsyncHTTPConnection__set_state(_STATE_CHUNK_RESIDUE)
  370.             return None
  371.         self.set_terminator(self._chunksize + 2)
  372.         self._responsefp = StringIO.StringIO()
  373.         self._AsyncHTTPConnection__set_state(_STATE_CHUNK_BODY)
  374.  
  375.     
  376.     def _chunk_body_data(self):
  377.         self._chunkbuffer += self._responsefp.getvalue()
  378.         while self._chunkbuffer:
  379.             chunk_plus_crlf_size = self._chunksize + 2
  380.             if len(self._chunkbuffer) > chunk_plus_crlf_size:
  381.                 chunkbody = self._chunkbuffer[:chunk_plus_crlf_size]
  382.                 self._chunkbuffer = self._chunkbuffer[chunk_plus_crlf_size:]
  383.                 self._chunkbuffer = self._chunkbuffer.lstrip()
  384.             else:
  385.                 chunkbody = self._chunkbuffer
  386.                 self._chunkbuffer = ''
  387.             self._chunkfp.write(chunkbody)
  388.             if not self._chunkbuffer:
  389.                 break
  390.             
  391.             if self._chunkbuffer.find('\r\n') < 0:
  392.                 self._responsefp = StringIO.StringIO()
  393.                 self.set_terminator('\r\n')
  394.                 self._AsyncHTTPConnection__set_state(_STATE_CHUNK_START)
  395.                 return None
  396.             self._chunksize = self._get_chunk_size()
  397.             if self._chunksize == 0:
  398.                 self.response.body = self._chunkfp.getvalue()
  399.                 self._chunkfp = None
  400.                 if self._chunkbuffer:
  401.                     self._chunkbuffer = ''
  402.                     self._AsyncHTTPConnection__set_state(_STATE_ACTIVE)
  403.                     if self._willclose:
  404.                         self.close()
  405.                     
  406.                     self.handle_response()
  407.                     return None
  408.                 self.set_terminator('\r\n\r\n')
  409.                 self._responsefp = StringIO.StringIO()
  410.                 self._AsyncHTTPConnection__set_state(_STATE_CHUNK_RESIDUE)
  411.                 return None
  412.             chunk_plus_crlf_size = self._chunksize + 2
  413.             bufsize = len(self._chunkbuffer)
  414.             if bufsize < chunk_plus_crlf_size:
  415.                 self.set_terminator(chunk_plus_crlf_size - bufsize)
  416.                 self._responsefp = StringIO.StringIO()
  417.                 self._AsyncHTTPConnection__set_state(_STATE_CHUNK_BODY)
  418.                 return None
  419.             continue
  420.             bufsize < chunk_plus_crlf_size
  421.         self._responsefp = StringIO.StringIO()
  422.         self.set_terminator('\r\n')
  423.         self._AsyncHTTPConnection__set_state(_STATE_CHUNK_START)
  424.  
  425.     
  426.     def _chunk_residue_data(self):
  427.         residue = string.strip(self._responsefp.getvalue())
  428.         if self.debuglevel > 0 and residue:
  429.             print "chunk residue '%s'" % residue
  430.         
  431.         self._responsefp = None
  432.         if self._willclose:
  433.             self.close()
  434.         
  435.         self._AsyncHTTPConnection__set_state(_STATE_ACTIVE)
  436.         self.handle_response()
  437.  
  438.     
  439.     def handle_response(self):
  440.         raise HandleResponse('Call to AsyncHTTPConnection.handle_response', name = str(self))
  441.  
  442.     
  443.     def __set_state(self, next_state):
  444.         if self.debuglevel > 0:
  445.             print '%s to %s' % (self._AsyncHTTPConnection__state, next_state)
  446.         
  447.         self._AsyncHTTPConnection__state = next_state
  448.         self.found_terminator = self._TERMINATOR_MAP[self._AsyncHTTPConnection__state]
  449.  
  450.  
  451.  
  452. class AsyncHTTPException(Exception):
  453.     
  454.     def __init__(self, message = '', name = ''):
  455.         self._message = message
  456.         self._name = name
  457.  
  458.     
  459.     def __str__(self):
  460.         return '%s %s' % (self._name, self._message)
  461.  
  462.  
  463.  
  464. class NotConnected(AsyncHTTPException):
  465.     pass
  466.  
  467.  
  468. class UnknownProtocol(AsyncHTTPException):
  469.     pass
  470.  
  471.  
  472. class UnknownTransferEncoding(AsyncHTTPException):
  473.     pass
  474.  
  475.  
  476. class BadStatusLine(AsyncHTTPException):
  477.     pass
  478.  
  479.  
  480. class ImproperConnectionState(AsyncHTTPException):
  481.     pass
  482.  
  483.  
  484. class RequestNotReady(ImproperConnectionState):
  485.     pass
  486.  
  487.  
  488. class ResponseNotReady(ImproperConnectionState):
  489.     pass
  490.  
  491.  
  492. class HandleResponse(ImproperConnectionState):
  493.     pass
  494.  
  495.  
  496. class UnexpectedData(AsyncHTTPException):
  497.     pass
  498.  
  499.  
  500. class UnexpectedTerminator(AsyncHTTPException):
  501.     pass
  502.  
  503.  
  504. class InvalidChunk(AsyncHTTPException):
  505.     pass
  506.  
  507.  
  508. class __test_AsyncHTTPConnection(AsyncHTTPConnection):
  509.     
  510.     def __init__(self, host, port, url):
  511.         AsyncHTTPConnection.__init__(self, host, port)
  512.         self._url = url
  513.  
  514.     
  515.     def handle_response(self):
  516.         self.close()
  517.  
  518.     
  519.     def handle_connect(self):
  520.         print '__test_AsyncHTTPConnection.handle_connect'
  521.         AsyncHTTPConnection.handle_connect(self)
  522.         self.putrequest('GET', self._url)
  523.         self.endheaders()
  524.         self.getresponse()
  525.  
  526.  
  527. if __name__ == '__main__':
  528.     if len(sys.argv) < 4:
  529.         print 'Usage:  asynchttp.py <host> <port> <request>'
  530.         print "\t\tUsing www.google.com 80 '/'"
  531.         sys.argv[1:] = [
  532.             'www.google.com',
  533.             '80',
  534.             '/']
  535.     
  536.     tester = __test_AsyncHTTPConnection(sys.argv[1], int(sys.argv[2]), sys.argv[3])
  537.     tester.set_debuglevel(1)
  538.     tester.connect()
  539.     asyncore.loop()
  540.     if not hasattr(tester, 'response'):
  541.         print 'No rsponse'
  542.         sys.exit(-1)
  543.     
  544.     print 'results %s %d %s' % (tester.response.version, tester.response.status, tester.response.reason)
  545.     print 'headers:'
  546.     for hdr in tester.response.msg.headers:
  547.         print '%s' % string.strip(hdr)
  548.     
  549.     if tester.response.status == 200:
  550.         print 'body:'
  551.         print tester.response.body
  552.     
  553.  
  554.