设置权限

接口定义:

void S3_set_acl(const S3BucketContext *bucketContext, const char *key, 
                const char *ownerId, const char *ownerDisplayName,
                int aclGrantCount, const S3AclGrant *aclGrants, 
                S3RequestContext *requestContext,
                const S3ResponseHandler *handler, void *callbackData);

参数:

参数名 类型 说明
bucketContext const S3BucketContext * 包含bucket及相关的请求参数
key const char * 若设置对象的acl,则为对象名称;若设置bucket的acl,则为NULL
ownerId char * 拥有者id
ownerDisplayName char * 拥有者名称
aclGrantCount int 返回S3AclGrant的个数
aclGrants const S3AclGrant * 权限信息结构构成的数组
requestContext S3RequestContext * 请求参数,如果为NULL,则立即同步执行请求
timeoutMs int 如果非0,则是以毫秒为单位的请求超时时间
handler const S3ResponseHandler * 回调函数
callbackData void * 回调数据

代码示例:

#include <string.h>
#include <ctype.h>
#include <unistd.h>

// Simple ACL format:  Lines of this format:
// Type - ignored
// Starting with a dash - ignored
// Email email_address permission
// UserID user_id (display_name) permission
// Group Authenticated AWS Users permission
// Group All Users  permission
// permission is one of READ, WRITE, READ_ACP, WRITE_ACP, FULL_CONTROL
static int convert_simple_acl(char *aclXml, char *ownerId,
                              char *ownerDisplayName,
                              int *aclGrantCountReturn,
                              S3AclGrant *aclGrants)
{
    *aclGrantCountReturn = 0;
    *ownerId = 0;
    *ownerDisplayName = 0;

#define SKIP_SPACE(require_more)      \
    do                                \
    {                                 \
        while (isspace(*aclXml))      \
        {                             \
            aclXml++;                 \
        }                             \
        if (require_more && !*aclXml) \
        {                             \
            return 0;                 \
        }                             \
    } while (0)

#define COPY_STRING_MAXLEN(field, maxlen)           \
    do                                              \
    {                                               \
        SKIP_SPACE(1);                              \
        int len = 0;                                \
        while ((len < maxlen) && !isspace(*aclXml)) \
        {                                           \
            field[len++] = *aclXml++;               \
        }                                           \
        field[len] = 0;                             \
    } while (0)

#define COPY_STRING(field) \
    COPY_STRING_MAXLEN(field, (int)(sizeof(field) - 1))

    while (1)
    {
        SKIP_SPACE(0);

        if (!*aclXml)
        {
            break;
        }

        // Skip Type lines and dash lines
        if (!strncmp(aclXml, "Type", sizeof("Type") - 1) ||
            (*aclXml == '-'))
        {
            while (*aclXml && ((*aclXml != '\n') && (*aclXml != '\r')))
            {
                aclXml++;
            }
            continue;
        }

        if (!strncmp(aclXml, "OwnerID", sizeof("OwnerID") - 1))
        {
            aclXml += sizeof("OwnerID") - 1;
            COPY_STRING_MAXLEN(ownerId, S3_MAX_GRANTEE_USER_ID_SIZE);
            SKIP_SPACE(1);
            COPY_STRING_MAXLEN(ownerDisplayName,
                               S3_MAX_GRANTEE_DISPLAY_NAME_SIZE);
            continue;
        }

        if (*aclGrantCountReturn == S3_MAX_ACL_GRANT_COUNT)
        {
            return 0;
        }

        S3AclGrant *grant = &(aclGrants[(*aclGrantCountReturn)++]);

        if (!strncmp(aclXml, "Email", sizeof("Email") - 1))
        {
            grant->granteeType = S3GranteeTypeAmazonCustomerByEmail;
            aclXml += sizeof("Email") - 1;
            COPY_STRING(grant->grantee.amazonCustomerByEmail.emailAddress);
        }
        else if (!strncmp(aclXml, "UserID", sizeof("UserID") - 1))
        {
            grant->granteeType = S3GranteeTypeCanonicalUser;
            aclXml += sizeof("UserID") - 1;
            COPY_STRING(grant->grantee.canonicalUser.id);
            SKIP_SPACE(1);
            // Now do display name
            COPY_STRING(grant->grantee.canonicalUser.displayName);
        }
        else if (!strncmp(aclXml, "Group", sizeof("Group") - 1))
        {
            aclXml += sizeof("Group") - 1;
            SKIP_SPACE(1);
            if (!strncmp(aclXml, "Authenticated AWS Users",
                         sizeof("Authenticated AWS Users") - 1))
            {
                grant->granteeType = S3GranteeTypeAllAwsUsers;
                aclXml += (sizeof("Authenticated AWS Users") - 1);
            }
            else if (!strncmp(aclXml, "All Users", sizeof("All Users") - 1))
            {
                grant->granteeType = S3GranteeTypeAllUsers;
                aclXml += (sizeof("All Users") - 1);
            }
            else if (!strncmp(aclXml, "Log Delivery",
                              sizeof("Log Delivery") - 1))
            {
                grant->granteeType = S3GranteeTypeLogDelivery;
                aclXml += (sizeof("Log Delivery") - 1);
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }

        SKIP_SPACE(1);

        if (!strncmp(aclXml, "READ_ACP", sizeof("READ_ACP") - 1))
        {
            grant->permission = S3PermissionReadACP;
            aclXml += (sizeof("READ_ACP") - 1);
        }
        else if (!strncmp(aclXml, "READ", sizeof("READ") - 1))
        {
            grant->permission = S3PermissionRead;
            aclXml += (sizeof("READ") - 1);
        }
        else if (!strncmp(aclXml, "WRITE_ACP", sizeof("WRITE_ACP") - 1))
        {
            grant->permission = S3PermissionWriteACP;
            aclXml += (sizeof("WRITE_ACP") - 1);
        }
        else if (!strncmp(aclXml, "WRITE", sizeof("WRITE") - 1))
        {
            grant->permission = S3PermissionWrite;
            aclXml += (sizeof("WRITE") - 1);
        }
        else if (!strncmp(aclXml, "FULL_CONTROL",
                          sizeof("FULL_CONTROL") - 1))
        {
            grant->permission = S3PermissionFullControl;
            aclXml += (sizeof("FULL_CONTROL") - 1);
        }
    }

    return 1;
}

void set_acl(const char *filename)
{
    FILE *infile;

    if (filename)
    {
        if (!(infile = fopen(filename, "r")))
        {
            fprintf(stderr, "\nERROR: Failed to open input file %s: ",
                    filename);
            perror(0);
            exit(-1);
        }
    }
    else
    {
        infile = stdin;
    }

    // Read in the complete ACL
    char aclBuf[65536];
    aclBuf[fread(aclBuf, 1, sizeof(aclBuf), infile)] = 0;
    char ownerId[S3_MAX_GRANTEE_USER_ID_SIZE];
    char ownerDisplayName[S3_MAX_GRANTEE_DISPLAY_NAME_SIZE];

    // Parse it
    int aclGrantCount;
    S3AclGrant aclGrants[S3_MAX_ACL_GRANT_COUNT];
    if (!convert_simple_acl(aclBuf, ownerId, ownerDisplayName,
                            &aclGrantCount, aclGrants))
    {
        fprintf(stderr, "\nERROR: Failed to parse ACLs\n");
        fclose(infile);
        exit(-1);
    }

    S3ResponseHandler responseHandler =
        {
            &responsePropertiesCallback,
            &responseCompleteCallback};

    do
    {
        S3_set_acl(&bucketContext, test_key, ownerId, ownerDisplayName,
                   aclGrantCount, aclGrants, 0, 0, &responseHandler, 0);
    } while (S3_status_is_retryable(statusG) && should_retry());

    if (statusG != S3StatusOK)
    {
        printError();
    }

    fclose(infile);
}