Beispiel #1
0
    def _send(self):
        """Send coroutine loop"""
        self.conn.upload_start = None
        while not self.failed:
            # fetch input data from the queue
            data = self.queue.get()
            # use HTTP transfer encoding chunked
            # to write data to RAWX
            try:
                with ChunkWriteTimeout(self.write_timeout):
                    if self.perfdata is not None \
                            and self.conn.upload_start is None:
                        self.conn.upload_start = monotonic_time()
                    self.conn.send("%x\r\n" % len(data))
                    self.conn.send(data)
                    self.conn.send("\r\n")
                    self.bytes_transferred += len(data)
                eventlet_yield()
            except (Exception, ChunkWriteTimeout) as exc:
                self.failed = True
                msg = str(exc)
                self.logger.warn("Failed to write to %s (%s, reqid=%s)",
                                 self.chunk, msg, self.reqid)
                self.chunk['error'] = 'write: %s' % msg

        # Drain the queue before quitting
        while True:
            try:
                self.queue.get_nowait()
            except Empty:
                break
Beispiel #2
0
 def getresponse(self):
     """Read the HTTP response from the connection"""
     try:
         # As the server may buffer data before writing it to non-volatile
         # storage, we don't know if we have to wait while sending data or
         # while reading response, thus we apply the same timeout to both.
         with ChunkWriteTimeout(self.write_timeout):
             resp = self.conn.getresponse()
             return resp
     finally:
         if self.perfdata is not None:
             perfdata_rawx = self.perfdata.setdefault('rawx', dict())
             chunk_url = self.conn.chunk['url']
             upload_end = monotonic_time()
             perfdata_rawx['upload.' + chunk_url] = \
                 upload_end - self.conn.upload_start
Beispiel #3
0
    def finish(self, metachunk_size, metachunk_hash):
        """
        Send metachunk_size and metachunk_hash as trailers.

        :returns: the chunk object if the upload has failed, else None
        """
        self.wait()
        if self.failed:
            self.logger.debug("NOT sending end marker and trailers to %s, "
                              "because upload has failed", self.chunk['url'])
            return self.chunk
        self.logger.debug("Sending end marker and trailers to %s",
                          self.chunk['url'])
        parts = [
            '0\r\n',
            '%s: %s\r\n' % (CHUNK_HEADERS['metachunk_size'],
                            metachunk_size),
            '%s: %s\r\n' % (CHUNK_HEADERS['metachunk_hash'],
                            metachunk_hash)
        ]
        if self.checksum:
            parts.append('%s: %s\r\n' % (CHUNK_HEADERS['chunk_hash'],
                                         self.checksum.hexdigest()))
        parts.append('\r\n')
        to_send = ''.join(parts).encode('utf-8')
        if self.perfdata is not None:
            fin_start = monotonic_time()
        try:
            with ChunkWriteTimeout(self.write_timeout):
                self.conn.send(to_send)
                # Last segment sent, disable TCP_CORK to flush buffers
                self.conn.set_cork(False)
        except (Exception, ChunkWriteTimeout) as exc:
            self.failed = True
            msg = text_type(exc)
            self.logger.warn("Failed to finish %s (%s, reqid=%s)",
                             self.chunk, msg, self.reqid)
            self.chunk['error'] = 'finish: %s' % msg
            return self.chunk
        finally:
            if self.perfdata is not None:
                fin_end = monotonic_time()
                rawx_perfdata = self.perfdata.setdefault('rawx', dict())
                chunk_url = self.conn.chunk['url']
                rawx_perfdata['upload_finish.' + chunk_url] = \
                    fin_end - fin_start
        return None
Beispiel #4
0
    def finish(self, metachunk_size, metachunk_hash):
        """
        Send metachunk_size and metachunk_hash as trailers.

        :returns: the chunk object if the upload has failed, else None
        """
        self.wait()
        if self.failed:
            self.logger.debug(
                "NOT sending end marker and trailers to %s, "
                "because upload has failed", self.chunk['url'])
            return self.chunk
        self.logger.debug("Sending end marker and trailers to %s",
                          self.chunk['url'])
        parts = [
            '0\r\n',
            '%s: %s\r\n' % (CHUNK_HEADERS['metachunk_size'], metachunk_size),
            '%s: %s\r\n' % (CHUNK_HEADERS['metachunk_hash'], metachunk_hash)
        ]
        if self.checksum:
            parts.append(
                '%s: %s\r\n' %
                (CHUNK_HEADERS['chunk_hash'], self.checksum.hexdigest()))
        parts.append('\r\n')
        to_send = "".join(parts)
        try:
            with ChunkWriteTimeout(self.write_timeout):
                self.conn.send(to_send)
                # Last segment sent, disable TCP_CORK to flush buffers
                self.conn.set_cork(False)
        except (Exception, ChunkWriteTimeout) as exc:
            self.failed = True
            msg = str(exc)
            self.logger.warn("Failed to finish %s (%s, reqid=%s)", self.chunk,
                             msg, self.reqid)
            self.chunk['error'] = 'finish: %s' % msg
            return self.chunk
        return None