예제 #1
0
    def initialize(self, stream, session):
        super(OutgoingFileTransferHandler, self).initialize(stream, session)
        if stream.file_selector.fd is None:
            NotificationCenter().post_notification(
                'FileTransferHandlerDidNotInitialize',
                sender=self,
                data=NotificationData(reason='file descriptor not specified'))
            return
        if stream.file_selector.size == 0:
            NotificationCenter().post_notification(
                'FileTransferHandlerDidNotInitialize',
                sender=self,
                data=NotificationData(reason='file is empty'))
            return

        self.headers[ContentTypeHeader.name] = ContentTypeHeader(
            stream.file_selector.type)
        self.headers[SuccessReportHeader.name] = SuccessReportHeader('yes')
        self.headers[FailureReportHeader.name] = FailureReportHeader('yes')

        if stream.file_selector.hash is None:
            self._calculate_file_hash()
        else:
            NotificationCenter().post_notification(
                'FileTransferHandlerDidInitialize', sender=self)
예제 #2
0
 def make_hello(self,
                msrptransport,
                success_report=None,
                failure_report=None):
     chunk = msrptransport.make_send_request(data='hello')
     chunk.add_header(ContentTypeHeader('text/plain'))
     # because MSRPTransport does not send the responses, the relay must not either
     if success_report is not None:
         chunk.add_header(SuccessReportHeader(success_report))
     if failure_report is not None:
         chunk.add_header(FailureReportHeader(failure_report))
     return chunk
예제 #3
0
 def __init__(self, filename, msrp_session, msrp):
     self.notification_center = NotificationCenter()
     self.msrp = msrp
     self.msrp_session = msrp_session
     self.offset = 0
     self.fileSize = 0
     self.filename = filename
     self.headers = {}
     self.headers[ContentTypeHeader.name] = ContentTypeHeader('application/x-webodf-genesisdocument')
     self.headers[SuccessReportHeader.name] = SuccessReportHeader('yes')
     self.headers[FailureReportHeader.name] = FailureReportHeader('yes')
     self.finished_event = Event()
     self.stop_event = Event()
예제 #4
0
 def _msrp_writer(self):
     while True:
         try:
             data = self.outgoing_queue.wait()
             chunk = self.msrp.make_send_request(data=data)
             chunk.add_header(SuccessReportHeader('no'))
             chunk.add_header(FailureReportHeader('partial'))
             chunk.add_header(ContentTypeHeader('application/x-rfb'))
             self.msrp.write_chunk(chunk)
         except Exception as e:
             self.msrp_writer_thread = None # avoid issues caused by the notification handler killing this greenlet during post_notification
             if self.shutting_down and isinstance(e, ConnectionDone):
                 break
             self._failure_reason = str(e)
             NotificationCenter().post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='sending', reason=self._failure_reason))
             break
예제 #5
0
    def _send_chunk(self, data):
        if self.stop_event.is_set():
            return
        data_len = len(data)
        chunk = self.stream.msrp.make_send_request(message_id=self.message_id,
                                                   data=data,
                                                   start=self.offset+1,
                                                   end=self.offset+data_len,
                                                   length=self.stream.file_selector.size)
        chunk.add_header(ContentTypeHeader(self.stream.file_selector.type))
        chunk.add_header(SuccessReportHeader('yes'))
        chunk.add_header(FailureReportHeader('yes'))

        try:
            self.stream.msrp_session.send_chunk(chunk, response_cb=self._on_transaction_response)
        except Exception as e:
            NotificationCenter().post_notification('FileTransferHandlerError', sender=self, data=NotificationData(error=str(e)))
        else:
            self.offset += data_len
예제 #6
0
    def _message_queue_handler(self):
        notification_center = NotificationCenter()
        try:
            while True:
                message = self.message_queue.wait()
                if self.msrp_session is None:
                    if message.notify_progress:
                        data = NotificationData(message_id=message.id,
                                                message=None,
                                                code=0,
                                                reason='Stream ended')
                        notification_center.post_notification(
                            'ChatStreamDidNotDeliverMessage',
                            sender=self,
                            data=data)
                    break

                try:
                    if isinstance(message.content, str):
                        message.content = message.content.encode('utf8')
                        charset = 'utf8'
                    else:
                        charset = None

                    if not isinstance(message, QueuedOTRInternalMessage):
                        try:
                            message.content = self.encryption.otr_session.handle_output(
                                message.content, message.content_type)
                        except OTRError as e:
                            raise ChatStreamError(str(e))

                    message.sender = message.sender or self.local_identity
                    message.recipients = message.recipients or [
                        self.remote_identity
                    ]

                    # check if we MUST use CPIM
                    need_cpim = (message.sender != self.local_identity or
                                 message.recipients != [self.remote_identity]
                                 or message.courtesy_recipients
                                 or message.subject or message.timestamp
                                 or message.required
                                 or message.additional_headers)

                    if need_cpim or not contains_mime_type(
                            self.remote_accept_types, message.content_type):
                        if not contains_mime_type(
                                self.remote_accept_wrapped_types,
                                message.content_type):
                            raise ChatStreamError(
                                'Unsupported content_type for outgoing message: %r'
                                % message.content_type)
                        if not self.cpim_enabled:
                            raise ChatStreamError(
                                'Additional message meta-data cannot be sent, because the CPIM wrapper is not used'
                            )
                        if not self.private_messages_allowed and message.recipients != [
                                self.remote_identity
                        ]:
                            raise ChatStreamError(
                                'The remote end does not support private messages'
                            )
                        if message.timestamp is None:
                            message.timestamp = ISOTimestamp.now()
                        payload = CPIMPayload(charset=charset,
                                              **{
                                                  name: getattr(message, name)
                                                  for name in Message.__slots__
                                              })
                    elif self.prefer_cpim and self.cpim_enabled and contains_mime_type(
                            self.remote_accept_wrapped_types,
                            message.content_type):
                        if message.timestamp is None:
                            message.timestamp = ISOTimestamp.now()
                        payload = CPIMPayload(charset=charset,
                                              **{
                                                  name: getattr(message, name)
                                                  for name in Message.__slots__
                                              })
                    else:
                        payload = SimplePayload(message.content,
                                                message.content_type, charset)
                except ChatStreamError as e:
                    if message.notify_progress:
                        data = NotificationData(message_id=message.id,
                                                message=None,
                                                code=0,
                                                reason=e.args[0])
                        notification_center.post_notification(
                            'ChatStreamDidNotDeliverMessage',
                            sender=self,
                            data=data)
                    continue
                else:
                    content, content_type = payload.encode()

                message_id = message.id
                notify_progress = message.notify_progress
                report = 'yes' if notify_progress else 'no'

                chunk = self.msrp_session.make_message(
                    content, content_type=content_type, message_id=message_id)
                chunk.add_header(FailureReportHeader(report))
                chunk.add_header(SuccessReportHeader(report))

                try:
                    self.msrp_session.send_chunk(
                        chunk,
                        response_cb=partial(self._on_transaction_response,
                                            message_id))
                except Exception as e:
                    if notify_progress:
                        data = NotificationData(message_id=message_id,
                                                message=None,
                                                code=0,
                                                reason=str(e))
                        notification_center.post_notification(
                            'ChatStreamDidNotDeliverMessage',
                            sender=self,
                            data=data)
                except ProcExit:
                    if notify_progress:
                        data = NotificationData(message_id=message_id,
                                                message=None,
                                                code=0,
                                                reason='Stream ended')
                        notification_center.post_notification(
                            'ChatStreamDidNotDeliverMessage',
                            sender=self,
                            data=data)
                    raise
                else:
                    if notify_progress:
                        self.sent_messages.add(message_id)
                        notification_center.post_notification(
                            'ChatStreamDidSendMessage',
                            sender=self,
                            data=NotificationData(message=chunk))
        finally:
            self.message_queue_thread = None
            while self.sent_messages:
                message_id = self.sent_messages.pop()
                data = NotificationData(message_id=message_id,
                                        message=None,
                                        code=0,
                                        reason='Stream ended')
                notification_center.post_notification(
                    'ChatStreamDidNotDeliverMessage', sender=self, data=data)
            message_queue, self.message_queue = self.message_queue, queue()
            while message_queue:
                message = message_queue.wait()
                if message.notify_progress:
                    data = NotificationData(message_id=message.id,
                                            message=None,
                                            code=0,
                                            reason='Stream ended')
                    notification_center.post_notification(
                        'ChatStreamDidNotDeliverMessage',
                        sender=self,
                        data=data)
예제 #7
0
                    else:
                        payload = SimplePayload(message.content, message.content_type, charset)
                except ChatStreamError, e:
                    if message.notify_progress:
                        data = NotificationData(message_id=message.id, message=None, code=0, reason=e.args[0])
                        notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)
                    continue
                else:
                    content, content_type = payload.encode()

                message_id = message.id
                notify_progress = message.notify_progress
                report = 'yes' if notify_progress else 'no'

                chunk = self.msrp_session.make_message(content, content_type=content_type, message_id=message_id)
                chunk.add_header(FailureReportHeader(report))
                chunk.add_header(SuccessReportHeader(report))

                try:
                    self.msrp_session.send_chunk(chunk, response_cb=partial(self._on_transaction_response, message_id))
                except Exception, e:
                    if notify_progress:
                        data = NotificationData(message_id=message_id, message=None, code=0, reason=str(e))
                        notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)
                except ProcExit:
                    if notify_progress:
                        data = NotificationData(message_id=message_id, message=None, code=0, reason='Stream ended')
                        notification_center.post_notification('ChatStreamDidNotDeliverMessage', sender=self, data=data)
                    raise
                else:
                    if notify_progress: