def test_0005_bad_pipeline(self): "Chain 3 queries, second is bad, should stop the response stream." self.real_test = "{0}".format(inspect.stack()[0][3]) self._prepare_pipe_test() self.req2.set_location(Tools.NULL, random=True) self.req3 = Request(id(self)) self.req3.set_location(self.config.get('SERVER_DEFAULT_LOCATION'), random=True) with Client() as csock: csock.send(self.req1) csock.send(self.req2) csock.send(self.req3) responses = csock.read_all() outmsg(str(responses)) self.analysis(responses, expected_number=2, regular_expected=False) self.assertTrue((responses.count <= 2)) if (responses.count > 1): self.assertIn(self.status, [self.STATUS_REJECTED, self.STATUS_ERR400], 'Bad response status {0}'.format(self.status))
def close_sending(self): """First closing step, cut the sending part of the socket.""" try: outmsg('# closing client connection send canal ' '(can still receive).') self._sock.shutdown(socket.SHUT_WR) except OSError: raise ClosedSocketError('closed socket detected on send close')
def close(self): """Ensure the tcp/ip socket is really closed.""" if self._sock is not None: outmsg('# closing client connection.') try: self._sock.shutdown(socket.SHUT_RDWR) except Exception: # already closed pass self._sock.close() self._sock = None
def _socket_send(self, message): msglen = len(message) totalsent = 0 outmsg('# ====================>') while totalsent < msglen: outmsg('# ...') sent = self._sock.send(message[totalsent:]) if sent == 0: raise RuntimeError("socket connection broken") totalsent = totalsent + sent
def send(self, request): """Send given request on the socket, support delayed emission.""" msg = request.getBytesStream() msglen = len(msg) outmsg('# SENDING ({0}) =====>'.format(msglen)) # here we use the not-so real format (special bytes are not # replaced in str(), only in getBytesStream()) Tools.print_message(six.text_type(request), cleanup=True) try: self._socket_send(msg) except socket.error as errmsg: outmsg('#<====ABORTED COMMUNICATION WHILE' ' SENDING {0}\n#{1}'.format(six.text_type(msg), errmsg)) return while request.is_delayed: msg = request.getDelayedOutput() msglen = len(msg) outmsg('# SENDING Delayed ({0}) =====>'.format(msglen)) # hopefully we do not use strange bytes in delayed chunks for now Tools.print_message(six.text_type(msg), cleanup=True) try: self._socket_send(msg) except socket.error as errmsg: outmsg('#<====ABORTED COMMUNICATION WHILE' ' SENDING (delayed) ' '{0}\r\n#{1}'.format(six.text_type(msg), errmsg)) return
def _prepare_pipe_test(self, method1='GET', method2='GET'): outmsg("={0}=".format(self.real_test)) if Register.flags['keepalive'] is False: self.skipTest("No keepalive support.") if Register.flags['pipelining'] is False: self.skipTest("No pipelining support.") self.send_mode = self.SEND_MODE_PIPE location = self.get_default_location( with_prefix=self.use_backend_location) self.req1 = Request(id(self)) self.req1.add_header('Connection', 'keep-alive') self.req1.set_location(location, random=True) self.req1.set_method(method1) self.req2 = Request(id(self)) self.req2.set_location(location, random=True) self.req2.set_method(method2)
def send_queries(self): responses = None if self.send_mode == self.SEND_MODE_UNIQUE: with Client() as csock: csock.send(self.req) responses = csock.read_all() self._hook_while_sending() elif self.send_mode == self.SEND_MODE_PIPE: with Client() as csock: # csock.send(u'{0}{1}'.format(self.req1, self.req2)) csock.send(self.req1) csock.send(self.req2) responses = csock.read_all() self._hook_while_sending() else: raise ValueError('Unknown send mode for test HTTP queries.') outmsg(str(responses)) return responses
def test_0003_regular_keepalive(self): "Chain two regular queries in a keepalive conn." self.real_test = "{0}".format(inspect.stack()[0][3]) self._prepare_simple_test() self.req.add_header('Connection', 'keep-alive') responses2 = False with Client() as csock: csock.send(self.req) responses1 = csock.read_all() outmsg(str(responses1)) self.analysis(responses1, http09_allowed=False, regular_expected=True) if self.status == self.STATUS_REJECTED: Register.flag('keepalive', False) self.assertIn(self.status, [self.STATUS_ACCEPTED], 'Bad response status {0}'.format(self.status)) if responses1.count: # TODO: check Connection: keep-alive on response headers self._prepare_simple_test() csock.send(self.req) # inform server we are done with sending data # FIXME: this is failing with Nginx (at least) # try: # csock.close_sending() # except ClosedSocketError: # Register.flag('keepalive', False) # self.setGravity(self.GRAVITY_UNKNOWN) # raise AssertionError('Connection closed before reading') responses2 = csock.read_all() outmsg(str(responses2)) self.analysis(responses2, http09_allowed=False, regular_expected=True) self.assertIn(self.status, [self.STATUS_ACCEPTED], 'Bad response status {0}'.format(self.status))
def open(self): """Open client socket connection.""" if self.hostip is None: outmsg('# searching host IP (DNS) for {0} '.format(self.host)) self.hostip = socket.getaddrinfo(self.host, self.port)[0][4][0] self._ci() try: if not self._hostip: raise Exception(u'\u0262\u0046\u0059') outmsg('# Connecting to Host: {0} IP: {1} PORT: {2}'.format( self.host, self.hostip, self.port)) self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._sock.settimeout(10) except socket.error as msg: outmsg("[ERROR] {0}".format(str(msg))) raise Exception('error creating socket') outmsg('# socket ok') if self.https: try: outmsg('# Establishing SSL layer') self._sock = ssl.wrap_socket(self._sock, cert_reqs=ssl.CERT_NONE) except: outmsg("[SSL ERROR]") raise Exception('error establishing SSL connection') try: self._sock.connect((self.hostip, self.port)) except socket.error as msg: outmsg("[ERROR] {0}".format(str(msg))) raise Exception('error establishing socket connect') outmsg('# client connection established.')
def _prepare_simple_test(self): outmsg("={0}=".format(self.real_test)) self.req = Request(id(self)) location = self.get_default_location() self.req.set_location(location, random=True)
def outmsg(self, message): outmsg(message, prefix=u'BACKEND {0}> '.format(self.name), color='yellow')
def open(self): """Open client socket connection.""" if self.hostip is None: outmsg('# searching host IP (DNS) for {0} '.format(self.host)) self.hostip = socket.getaddrinfo(self.host, self.port)[0][4][0] self._ci() try: if not self._hostip: raise Exception(u'\u0262\u0046\u0059') outmsg( '# Connecting to Host: {0} IP: {1} PORT: {2}'.format( self.host, self.hostip, self.port)) self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._sock.settimeout(10) except socket.error as msg: outmsg("[ERROR] {0}".format(str(msg))) raise Exception('error creating socket') outmsg('# socket ok') if self.https: try: outmsg('# Establishing SSL layer') self._sock = ssl.wrap_socket(self._sock, cert_reqs=ssl.CERT_NONE) except: outmsg("[SSL ERROR]") raise Exception('error establishing SSL connection') try: self._sock.connect((self.hostip, self.port)) except socket.error as msg: outmsg("[ERROR] {0}".format(str(msg))) raise Exception('error establishing socket connect') outmsg('# client connection established.')
def outmsg(self, message): outmsg(message, prefix=b'BACKEND> ', color='yellow')