def _SendQueuedData(self):
     """Send data that is sitting in the unsent data queue."""
     while self._unsent_data and not self._stopping:
         try:
             send_data = utils.CreateSubprotocolDataFrame(
                 self._unsent_data[0])
             # We need to append to _unconfirmed_data before calling Send(), because
             # otherwise we could receive the ack for the sent data before we do the
             # append, which we would interpret as an invalid ack. This does mean
             # there's a small window of time where we'll accept acks of data that
             # hasn't truly been sent if a badly behaving server sends such acks, but
             # that's not really a problem, because we'll behave identically to as if
             # the ack was received after the data was sent (so no data or control
             # flow corruption), and we don't have a goal of giving an error every
             # time the server misbehaves.
             self._unconfirmed_data.append(self._unsent_data.popleft())
             self._websocket_helper.Send(send_data)
         except helper.WebSocketConnectionClosed:
             break
         except EnvironmentError as e:
             log.info('Unable to send WebSocket data [%s]', str(e))
             break
         except:  # pylint: disable=bare-except
             log.info('Error while attempting to send [%d] bytes',
                      len(send_data),
                      exc_info=True)
             break
     # We need to check _input_eof before _unsent_data to avoid a race
     # condition with setting _input_eof simultaneously with this check.
     if self._input_eof and not self._unsent_data:
         self._sent_all.set()
 def _SendData(self, bytes_to_send):
     first_to_send = bytes_to_send[:utils.SUBPROTOCOL_MAX_DATA_FRAME_SIZE]
     bytes_to_send = bytes_to_send[utils.SUBPROTOCOL_MAX_DATA_FRAME_SIZE:]
     if first_to_send:
         send_data = utils.CreateSubprotocolDataFrame(first_to_send)
         self._SendBytes(send_data)
     return bytes_to_send
    def _SendQueuedData(self):
        """Send data that is sitting in the unsent data queue."""
        try:
            while not self._stopping:
                self._MaybeSendAck()
                # This is a blocking call in case the queue is empty. The timeout is
                # there so we can unblock and send acks if no message arrive after a few
                # seconds
                try:
                    if not self._data_to_resend.empty():
                        data = self._data_to_resend.get()
                    else:
                        data = self._unsent_data.get(
                            timeout=MAX_WEBSOCKET_SEND_WAIT_TIME_SEC)
                except queue.Empty:
                    # Throws empty if timeout reached
                    if self._IsClosed():
                        raise helper.WebSocketConnectionClosed
                    break

                # When EOF is reached, EOF error will be put in the queue.
                # When close is called. ConnectionAborted error is put in the queue.
                if data is EOFError or data is StoppingError:
                    # Now we tell the thread to quit as there's no more data to send.
                    self._stopping = True
                    if data is EOFError:
                        self._input_eof = True
                    break

                # We need to append to _unconfirmed_data before calling Send(), because
                # otherwise we could receive the ack for the sent data before we do the
                # append, which we would interpret as an invalid ack. This does mean
                # there's a small window of time where we'll accept acks of data that
                # hasn't truly been sent if a badly behaving server sends such acks, but
                # that's not really a problem, because we'll behave identically to as if
                # the ack was received after the data was sent (so no data or control
                # flow corruption), and we don't have a goal of giving an error every
                # time the server misbehaves.
                # It's also important in case we take the data out of the unset data
                # queue but we can't send it up because the connection was closed. By
                # adding it to unconfirmed, we will resend it later.
                self._unconfirmed_data.append(data)

                send_data = utils.CreateSubprotocolDataFrame(data)
                self._websocket_helper.Send(send_data)
        finally:
            if (self._input_eof and self._data_to_resend.empty()
                    and self._unsent_data.empty()):
                self._sent_all.set()
Beispiel #4
0
 def Send(self, bytes_to_send):
     """Send bytes over WebSocket connection."""
     if not self._websocket_open:
         self.WaitForOpenOrRaiseError()
         if not self._websocket:
             raise UnexpectedConnectionCloseError(
                 'WebSocket unexpectedly closed')
     while bytes_to_send:
         first_to_send = bytes_to_send[:utils.
                                       SUBPROTOCOL_MAX_DATA_FRAME_SIZE]
         bytes_to_send = bytes_to_send[utils.
                                       SUBPROTOCOL_MAX_DATA_FRAME_SIZE:]
         send_data = utils.CreateSubprotocolDataFrame(first_to_send)
         self._websocket.send(send_data,
                              opcode=websocket.ABNF.OPCODE_BINARY)
Beispiel #5
0
 def _SendQueuedData(self):
   """Send data that is sitting in the unsent data queue."""
   while self._unsent_data and not self._stopping:
     try:
       send_data = utils.CreateSubprotocolDataFrame(self._unsent_data[0])
       self._websocket_helper.Send(send_data)
       self._unconfirmed_data.append(self._unsent_data.popleft())
     except helper.WebSocketConnectionClosed:
       break
     except EnvironmentError as e:
       log.info('Unable to send WebSocket data [%s]', str(e))
       break
     except:  # pylint: disable=bare-except
       log.info('Error while attempting to send [%d] bytes', len(send_data),
                exc_info=True)
       break
Beispiel #6
0
 def testCreateSubprotocolDataFrame(self, bytes_to_send, expected_bytes):
     self.assertEqual(utils.CreateSubprotocolDataFrame(bytes_to_send),
                      expected_bytes)