Ejemplo n.º 1
0
    def POST(self, request):
        """Handle HTTP POST requests for the Swift on File object server"""
        device, partition, account, container, obj, policy = \
            get_name_and_placement(request, 5, 5, True)
        req_timestamp = valid_timestamp(request)
        new_delete_at = int(request.headers.get('X-Delete-At') or 0)
        if new_delete_at and new_delete_at < time.time():
            return HTTPBadRequest(body='X-Delete-At in past', request=request,
                                  content_type='text/plain')

        # Get DiskFile
        try:
            disk_file = self.get_diskfile(device, partition, account,
                                          container, obj, policy)
        except DiskFileDeviceUnavailable:
            return HTTPInsufficientStorage(drive=device, request=request)

        # Set Purgelock status if we got it
        purgelock = request.headers.get('X-HPSS-Purgelock-Status')
        if purgelock:
            try:
                hpssfs.ioctl(disk_file._fd, hpssfs.HPSSFS_PURGE_LOCK,
                             int(purgelock))
            except IOError as err:
                raise SwiftOnFileSystemIOError(
                    err.errno,
                    '%s, xattr.getxattr("%s", ...)' %
                    (err.strerror, disk_file._fd))

        # Set class of service if we got it
        cos = request.headers.get('X-HPSS-Class-Of-Service-ID')
        if cos:
            try:
                xattr.setxattr(disk_file._fd, 'system.hpss.cos', int(cos))
            except IOError as err:
                raise SwiftOnFileSystemIOError(
                    err.errno,
                    '%s, xattr.setxattr("%s", ...)' %
                    (err.strerror, disk_file._fd))

        # Update metadata from request
        try:
            orig_metadata = disk_file.read_metadata()
        except (DiskFileNotExist, DiskFileQuarantined):
            return HTTPNotFound(request=request)
        orig_timestamp = Timestamp(orig_metadata.get('X-Timestamp', 0))
        if orig_timestamp >= req_timestamp:
            return HTTPConflict(request=request,
                                headers={
                                    'X-Backend-Timestamp': orig_timestamp.internal
                                })
        metadata = {'X-Timestamp': req_timestamp.internal}
        metadata.update(val for val in request.headers.iteritems()
                        if is_user_meta('object', val[0]))
        for header_key in self.allowed_headers:
            if header_key in request.headers:
                header_caps = header_key.title()
                metadata[header_caps] = request.headers[header_key]
        orig_delete_at = int(orig_metadata.get('X-Delete-At') or 0)
        if orig_delete_at != new_delete_at:
            if new_delete_at:
                self.delete_at_update('PUT', new_delete_at, account,
                                      container, obj, request, device, policy)
            if orig_delete_at:
                self.delete_at_update('DELETE', orig_delete_at, account,
                                      container, obj, request, device, policy)
        disk_file.write_metadata(metadata)
        return HTTPAccepted(request=request)