

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 를 사용한 Amazon S3 코드 예제 AWS SDK for C\$1\$1
<a name="examples-s3"></a>

[Amazon S3](https://aws.amazon.com/s3)는 어디서든 원하는 양의 데이터를 저장하고 검색할 수 있도록 빌드된 객체 스토리지입니다. Amazon S3와 인터페이스 AWS SDK for C\$1\$1 하기 위해에서 제공하는 여러 클래스가 있습니다.

**참고**  
이 안내서에는 특정 기술을 시연하는 데 필요한 코드만 제공되며 [전체 예제 코드는 GitHub에서 확인할 수 있습니다](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp). GitHub에서 단일 소스 파일을 다운로드하거나, 리포지토리를 로컬에 복제하여 모든 예제를 가져오고 빌드하고 실행할 수 있습니다.
+ [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_s3_client.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_s3_client.html) 클래스 

  `S3Client` 라이브러리는 완전한 기능을 갖춘 Amazon S3 인터페이스입니다.

  이 세트의 `list_buckets_disabling_dns_cache.cpp` 예제는 Linux/Mac 환경에서 CURL과 함께 작동하도록 특별히 설계되었습니다(Windows에서도 작동하도록 수정 가능). Windows에서 작업하는 경우, 프로젝트를 빌드하기 전에 `list_buckets_disabling_dns_cache.cpp` 파일을 삭제합니다. 이 파일은 Linux의 curl HttpClient에 의존하기 때문입니다.

  `S3Client`를 활용하는 예제 코드는 Github의 [`s3` 폴더](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3)에 있습니다. 이 예제 세트로 시연된 기능의 전체 목록은 Github의 [Readme](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/README.md)를 참조하세요.

  `s3` 예제 세트의 일부는 본 안내서에서 추가적으로 상세히 다루고 있습니다.
  + [버킷 생성, 나열, 삭제](examples-s3-buckets.md)
  + [객체 관련 작업](examples-s3-objects.md) – 데이터 객체 업로드 및 다운로드
  + [Amazon S3 액세스 권한 관리](examples-s3-access-permissions.md)
  + [버킷 정책을 사용하여 Amazon S3 버킷에 대한 액세스 관리](examples-s3-bucket-policies.md)
  + [Amazon S3 버킷을 웹 사이트로 구성](examples-s3-website-configuration.md)
+ [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3-crt/html/class_aws_1_1_s3_crt_1_1_s3_crt_client.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3-crt/html/class_aws_1_1_s3_crt_1_1_s3_crt_client.html) 클래스 

  `S3CrtClient`는 SDK 버전 1.9에서 추가되었습니다. `S3CrtClient`는 Amazon S3 GET(다운로드) 및 PUT(업로드) 작업에 높은 처리량을 제공합니다. `S3CrtClient`는 AWS 공통 런타임(CRT) 라이브러리 위에 구현됩니다.

  `S3CrtClient`를 활용하는 예제 코드는 Github의 [`s3-crt` 폴더](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3-crt)에 있습니다. 이 예제 세트로 시연된 기능의 전체 목록은 Github의 [Readme](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3-crt/README.md)를 참조하세요.
  + [Amazon S3 작업에 `S3CrtClient` 사용](examples-s3-crt.md)
+ [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/class_aws_1_1_transfer_1_1_transfer_manager.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/class_aws_1_1_transfer_1_1_transfer_manager.html) 클래스 

  `TransferManager`는 File Transfer Protocol(FTP), File Transfer Protocol over SSL(FTPS) 또는 Secure Shell(SSH) File Transfer Protocol(SFTP)을 통해 파일을 Amazon S3와 직접 주고받도록 지원하는 완전 관리형 서비스입니다.

  `TransferManager`를 활용하는 예제 코드는 Github의 [`transfer-manager` 폴더](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/transfer-manager)에 있습니다. 이 예제 세트로 시연된 기능의 전체 목록은 Github의 [Readme](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/transfer-manager/README.md)를 참조하세요.
  + [Amazon S3 작업에 TransferManager 사용](examples-s3-transfermanager.md)

# 버킷 생성, 나열, 삭제
<a name="examples-s3-buckets"></a>

Amazon Simple Storage Service(Amazon S3)의 모든 *객체* 또는 파일은 객체 폴더를 나타내는 *버킷*에 포함됩니다. 각 버킷에는 AWS 내에서 전역적으로 고유한 이름이 있습니다. 자세한 내용은 Amazon Simple Storage Service 사용 설명서에서 [Amazon S3 버킷을 사용한 작업](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html)을 참조하세요.

## 사전 조건
<a name="codeExamplePrereq"></a>

시작하기 전에 [AWS SDK for C\$1\$1 사용 시작하기](getting-started.md)를 읽어보시기 바랍니다.

예제 코드를 다운로드하고 [코드 예제 시작하기](getting-started-code-examples.md)에 설명된 대로 솔루션을 빌드합니다.

예제를 실행하려면 코드가 요청을 수행하는 데 사용하는 사용자 프로필이 AWS에서 적절한 권한(서비스 및 동작에 대한)을 보유하고 있어야 합니다. 자세한 내용은 [AWS 자격 증명 제공](credentials.md)을 참조하세요.

## 버킷 나열
<a name="list-buckets"></a>

`list_buckets` 예제를 실행하려면 명령 프롬프트에서 빌드 시스템이 빌드 실행 파일을 생성하는 폴더로 이동합니다. `run_list_buckets`과 같은 실행 파일을 실행합니다. 전체 실행 파일 이름은 운영 체제에 따라 다릅니다. 출력에는 계정 버킷이 있는 경우 해당 버킷 목록이 표시되며, 버킷이 없는 경우에는 빈 목록이 표시됩니다.

`list_buckets.cpp`에는 두 가지 메서드가 있습니다.
+ `main()` - `ListBuckets()`를 호출합니다.
+ `ListBuckets()` - SDK를 사용하여 버킷을 쿼리합니다.

`S3Client` 객체는 SDK의 `ListBuckets()` 메서드를 호출합니다. 성공하면 메서드는 `ListBucketResult` 객체가 포함된 `ListBucketOutcome` 객체를 반환합니다. `ListBucketResult` 객체는 `GetBuckets()` 메서드를 호출하여 계정의 각 Amazon S3 버킷에 대한 정보가 포함된 `Bucket` 객체 목록을 가져옵니다.

 **코드** 

```
bool AwsDoc::S3::listBuckets(const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);

    auto outcome = client.ListBuckets();

    bool result = true;
    if (!outcome.IsSuccess()) {
        std::cerr << "Failed with error: " << outcome.GetError() << std::endl;
        result = false;
    } else {
        std::cout << "Found " << outcome.GetResult().GetBuckets().size() << " buckets\n";
        for (auto &&b: outcome.GetResult().GetBuckets()) {
            std::cout << b.GetName() << std::endl;
        }
    }

    return result;
}
```

전체 [list\$1buckets 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/list_buckets.cpp)는 Github에서 확인하세요.

## 버킷 생성
<a name="create-bucket"></a>



`create_bucket` 예제를 실행하려면 명령 프롬프트에서 빌드 시스템이 빌드 실행 파일을 생성하는 폴더로 이동합니다. `run_create_bucket`과 같은 실행 파일을 실행합니다. 전체 실행 파일 이름은 운영 체제에 따라 다릅니다. 이 코드는 계정 아래에 빈 버킷을 생성한 다음 요청의 성공 또는 실패를 표시합니다.

`create_bucket.cpp`에는 두 가지 메서드가 있습니다.
+ `main()` - `CreateBucket()`를 호출합니다. `main()`에서는 `enum`를 사용하여 AWS 리전을 계정의 리전으로 변경해야 합니다. [AWS Management Console](https://console.aws.amazon.com/)에 로그인한 후 오른쪽 상단 모서리에서 리전을 찾으면 본인 계정의 리전을 확인할 수 있습니다.
+ `CreateBucket()` - SDK를 사용하여 버킷을 생성합니다.



`S3Client` 객체는 SDK의 `CreateBucket()` 메서드를 호출하여 버킷 이름과 함께 `CreateBucketRequest`를 전달합니다. 기본적으로 버킷은 *us-east-1*(북부 버지니아) 리전에 생성됩니다. 리전이 *us-east-1*이 아닌 경우 코드는 버킷이 해당 리전에 생성되도록 보장하기 위해 버킷 제약 조건을 설정합니다.

 **코드** 

```
bool AwsDoc::S3::createBucket(const Aws::String &bucketName,
                              const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);
    Aws::S3::Model::CreateBucketRequest request;
    request.SetBucket(bucketName);

    if (clientConfig.region != "us-east-1") {
        Aws::S3::Model::CreateBucketConfiguration createBucketConfig;
        createBucketConfig.SetLocationConstraint(
                Aws::S3::Model::BucketLocationConstraintMapper::GetBucketLocationConstraintForName(
                        clientConfig.region));
        request.SetCreateBucketConfiguration(createBucketConfig);
    }

    Aws::S3::Model::CreateBucketOutcome outcome = client.CreateBucket(request);
    if (!outcome.IsSuccess()) {
        auto err = outcome.GetError();
        std::cerr << "Error: createBucket: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Created bucket " << bucketName <<
                  " in the specified AWS Region." << std::endl;
    }

    return outcome.IsSuccess();
}
```

전체 [create\$1buckets 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/create_bucket.cpp)는 Github에서 확인하세요.

## 버킷 삭제
<a name="delete-bucket"></a>



`delete_bucket` 예제를 실행하려면 명령 프롬프트에서 빌드 시스템이 빌드 실행 파일을 생성하는 폴더로 이동합니다. `run_delete_bucket`과 같은 실행 파일을 실행합니다. 전체 실행 파일 이름은 운영 체제에 따라 다릅니다. 코드는 계정에 지정된 버킷을 삭제한 다음 요청의 성공 또는 실패를 표시합니다.

`delete_bucket.cpp`에는 두 가지 메서드가 있습니다.
+ `main()` - `DeleteBucket()`를 호출합니다. `main()`에서는 `enum`를 사용하여 AWS 리전을 계정의 리전으로 변경해야 합니다. 또한 `bucket_name`을 삭제할 버킷의 이름으로 변경해야 합니다.
+ `DeleteBucket()` - SDK를 사용하여 버킷을 삭제합니다.



`S3Client` 객체는 SDK의 `DeleteBucket()` 메서드를 사용하여 삭제할 버킷 이름과 함께 `DeleteBucketRequest` 객체를 전달합니다. 성공하려면 버킷이 비어 있어야 합니다.

 **코드**

```
bool AwsDoc::S3::deleteBucket(const Aws::String &bucketName,
                              const Aws::S3::S3ClientConfiguration &clientConfig) {

    Aws::S3::S3Client client(clientConfig);

    Aws::S3::Model::DeleteBucketRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::DeleteBucketOutcome outcome =
            client.DeleteBucket(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: deleteBucket: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "The bucket was deleted" << std::endl;
    }

    return outcome.IsSuccess();
}
```

전체 [delete\$1bucket 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/delete_bucket.cpp)는 Github에서 확인하세요.

# 객체 관련 작업
<a name="examples-s3-objects"></a>

Amazon S3 객체는 데이터 모음인 *파일*을 나타냅니다. 각 객체는 [버킷](examples-s3-buckets.md) 안에 상주해야 합니다.

## 사전 조건
<a name="codeExamplePrereq"></a>

시작하기 전에 [AWS SDK for C\$1\$1사용 시작하기](getting-started.md)를 읽어보시기 바랍니다.

예제 코드를 다운로드하고 [코드 예제 시작하기](getting-started-code-examples.md)에 설명된 대로 솔루션을 빌드합니다.

예제를 실행하려면 코드에서 요청을 만드는 데 사용하는 사용자 프로필에 AWS (서비스 및 작업에 대한) 적절한 권한이 있어야 합니다. 자세한 내용은 자격 [AWS 증명 제공을](credentials.md) 참조하세요.

## 버킷에 파일 업로드
<a name="upload-object"></a>

`S3Client` 객체의 `PutObject` 함수를 사용하여 버킷 이름, 키 이름 및 업로드할 파일을 제공합니다. `Aws::FStream`은 로컬 파일의 콘텐츠를 버킷에 업로드하는 데 사용됩니다. 버킷이 반드시 있어야 하며, 그렇지 않으면 오류가 발생합니다.

객체를 비동기적으로 업로드하는 예제는 [를 사용한 비동기 프로그래밍 AWS SDK for C\$1\$1](async-methods.md) 섹션을 참조하세요.

 **코드** 

```
bool AwsDoc::S3::putObject(const Aws::String &bucketName,
                           const Aws::String &fileName,
                           const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::PutObjectRequest request;
    request.SetBucket(bucketName);
    //We are using the name of the file as the key for the object in the bucket.
    //However, this is just a string and can be set according to your retrieval needs.
    request.SetKey(fileName);

    std::shared_ptr<Aws::IOStream> inputData =
            Aws::MakeShared<Aws::FStream>("SampleAllocationTag",
                                          fileName.c_str(),
                                          std::ios_base::in | std::ios_base::binary);

    if (!*inputData) {
        std::cerr << "Error unable to read file " << fileName << std::endl;
        return false;
    }

    request.SetBody(inputData);

    Aws::S3::Model::PutObjectOutcome outcome =
            s3Client.PutObject(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Error: putObject: " <<
                  outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Added object '" << fileName << "' to bucket '"
                  << bucketName << "'.";
    }

    return outcome.IsSuccess();
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_object.cpp)는 Github에서 확인하세요.

## 버킷에 문자열 업로드
<a name="upload-object-string"></a>

`S3Client` 객체의 `PutObject` 함수를 사용하여 버킷 이름, 키 이름 및 업로드할 파일을 제공합니다. 버킷이 반드시 있어야 하며, 그렇지 않으면 오류가 발생합니다. 이 예제는 `Aws::StringStream`을 사용하여 인 메모리 문자열 데이터 객체를 버킷에 직접 업로드한다는 점에서 이전 예제와 다릅니다.

객체를 비동기적으로 업로드하는 예제는 [를 사용한 비동기 프로그래밍 AWS SDK for C\$1\$1](async-methods.md) 섹션을 참조하세요.

 **코드** 

```
bool AwsDoc::S3::putObjectBuffer(const Aws::String &bucketName,
                                 const Aws::String &objectName,
                                 const std::string &objectContent,
                                 const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::PutObjectRequest request;
    request.SetBucket(bucketName);
    request.SetKey(objectName);

    const std::shared_ptr<Aws::IOStream> inputData =
            Aws::MakeShared<Aws::StringStream>("");
    *inputData << objectContent.c_str();

    request.SetBody(inputData);

    Aws::S3::Model::PutObjectOutcome outcome = s3Client.PutObject(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Error: putObjectBuffer: " <<
                  outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Success: Object '" << objectName << "' with content '"
                  << objectContent << "' uploaded to bucket '" << bucketName << "'.";
    }

    return outcome.IsSuccess();
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_object_buffer.cpp)는 Github에서 확인하세요.

## 객체 나열
<a name="list-objects"></a>

버킷 내의 객체 목록을 가져오려면 `S3Client` 객체의 `ListObjects` 함수를 사용합니다. 콘텐츠를 나열할 버킷의 이름이 설정된 `ListObjectsRequest`를 이 함수에 제공합니다.

`ListObjects` 함수는 객체 목록을 `Object` 인스턴스 형태로 가져오는 데 사용할 수 있는 `ListObjectsOutcome` 객체를 반환합니다.

 **코드** 

```
bool AwsDoc::S3::listObjects(const Aws::String &bucketName,
                             Aws::Vector<Aws::String> &keysResult,
                             const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::ListObjectsV2Request request;
    request.WithBucket(bucketName);

    Aws::String continuationToken; // Used for pagination.
    Aws::Vector<Aws::S3::Model::Object> allObjects;

    do {
        if (!continuationToken.empty()) {
            request.SetContinuationToken(continuationToken);
        }

        auto outcome = s3Client.ListObjectsV2(request);

        if (!outcome.IsSuccess()) {
            std::cerr << "Error: listObjects: " <<
                      outcome.GetError().GetMessage() << std::endl;
            return false;
        } else {
            Aws::Vector<Aws::S3::Model::Object> objects =
                    outcome.GetResult().GetContents();

            allObjects.insert(allObjects.end(), objects.begin(), objects.end());
            continuationToken = outcome.GetResult().GetNextContinuationToken();
        }
    } while (!continuationToken.empty());

    std::cout << allObjects.size() << " object(s) found:" << std::endl;

    for (const auto &object: allObjects) {
        std::cout << "  " << object.GetKey() << std::endl;
        keysResult.push_back(object.GetKey());
    }

    return true;
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/list_objects.cpp)는 Github에서 확인하세요.

## 객체 다운로드
<a name="download-object"></a>

`S3Client` 객체의 `GetObject` 함수를 사용하여 버킷 이름과 다운로드할 객체 키가 설정된 `GetObjectRequest`를 이 함수에 전달합니다. `GetObject`는 [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_object_result.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_object_result.html) 및 [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_s3_error.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_s3_error.html)로 구성된 [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/namespace_aws_1_1_s3_1_1_model.html#a6e16a7b25e8c7547934968a538a15272](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/namespace_aws_1_1_s3_1_1_model.html#a6e16a7b25e8c7547934968a538a15272) 객체를 반환합니다. `GetObjectResult`는 S3 객체의 데이터에 액세스하는 데 사용할 수 있습니다.

다음 예제는 Amazon S3에서 객체를 다운로드합니다. 객체 콘텐츠는 로컬 변수에 저장되고 콘텐츠의 첫 번째 줄이 콘솔에 출력됩니다.

 **코드** 

```
bool AwsDoc::S3::getObject(const Aws::String &objectKey,
                           const Aws::String &fromBucket,
                           const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);

    Aws::S3::Model::GetObjectRequest request;
    request.SetBucket(fromBucket);
    request.SetKey(objectKey);

    Aws::S3::Model::GetObjectOutcome outcome =
            client.GetObject(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: getObject: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Successfully retrieved '" << objectKey << "' from '"
                  << fromBucket << "'." << std::endl;
    }

    return outcome.IsSuccess();
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_object.cpp)는 Github에서 확인하세요.

## 객체 삭제
<a name="delete-object"></a>

`S3Client` 객체의 `DeleteObject` 함수를 사용하여 다운로드할 버킷과 객체의 이름이 설정된 `DeleteObjectRequest`를 이 함수에 전달합니다. *지정된 버킷과 객체 키가 반드시 있어야 하며, 그렇지 않으면 오류가 발생합니다*.

 **코드** 

```
bool AwsDoc::S3::deleteObject(const Aws::String &objectKey,
                              const Aws::String &fromBucket,
                              const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);
    Aws::S3::Model::DeleteObjectRequest request;

    request.WithKey(objectKey)
            .WithBucket(fromBucket);

    Aws::S3::Model::DeleteObjectOutcome outcome =
            client.DeleteObject(request);

    if (!outcome.IsSuccess()) {
        auto err = outcome.GetError();
        std::cerr << "Error: deleteObject: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Successfully deleted the object." << std::endl;
    }

    return outcome.IsSuccess();
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/delete_object.cpp)는 Github에서 확인하세요.

# Amazon S3 액세스 권한 관리
<a name="examples-s3-access-permissions"></a>

Amazon S3 버킷 또는 객체에 대한 액세스 권한은 액세스 제어 목록(ACL)에 정의되어 있습니다. ACL은 버킷/객체의 소유자와 권한 부여 목록을 지정합니다. 각 권한 부여에는 사용자(또는 수혜자)와 버킷/객체에 대한 사용자의 액세스 권한(예: READ 또는 WRITE 권한)이 지정됩니다.

## 사전 조건
<a name="codeExamplePrereq"></a>

시작하기 전에 [AWS SDK for C\$1\$1사용 시작하기](getting-started.md)를 읽어보시기 바랍니다.

예제 코드를 다운로드하고 [코드 예제 시작하기](getting-started-code-examples.md)에 설명된 대로 솔루션을 빌드합니다.

예제를 실행하려면 코드에서 요청을 만드는 데 사용하는 사용자 프로필에 AWS (서비스 및 작업에 대한) 적절한 권한이 있어야 합니다. 자세한 내용은 자격 [AWS 증명 제공을](credentials.md) 참조하세요.

## 객체의 액세스 제어 목록 관리
<a name="manage-an-object-s-access-control-list"></a>

`S3Client` 메서드 `GetObjectAcl`를 직접적으로 호출하여 객체에 대한 액세스 제어 목록을 검색할 수 있습니다. 이 메서드는 객체와 버킷의 이름을 허용합니다. 반환 값에는 ACL의 `Owner` 및 `Grants` 목록이 포함됩니다.

```
bool AwsDoc::S3::getObjectAcl(const Aws::String &bucketName,
                              const Aws::String &objectKey,
                              const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::GetObjectAclRequest request;
    request.SetBucket(bucketName);
    request.SetKey(objectKey);

    Aws::S3::Model::GetObjectAclOutcome outcome =
            s3Client.GetObjectAcl(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: getObjectAcl: "
                  << err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        Aws::Vector<Aws::S3::Model::Grant> grants =
                outcome.GetResult().GetGrants();

        for (auto it = grants.begin(); it != grants.end(); it++) {
            std::cout << "For object " << objectKey << ": "
                      << std::endl << std::endl;

            Aws::S3::Model::Grant grant = *it;
            Aws::S3::Model::Grantee grantee = grant.GetGrantee();

            if (grantee.TypeHasBeenSet()) {
                std::cout << "Type:          "
                          << getGranteeTypeString(grantee.GetType()) << std::endl;
            }

            if (grantee.DisplayNameHasBeenSet()) {
                std::cout << "Display name:  "
                          << grantee.GetDisplayName() << std::endl;
            }

            if (grantee.EmailAddressHasBeenSet()) {
                std::cout << "Email address: "
                          << grantee.GetEmailAddress() << std::endl;
            }

            if (grantee.IDHasBeenSet()) {
                std::cout << "ID:            "
                          << grantee.GetID() << std::endl;
            }

            if (grantee.URIHasBeenSet()) {
                std::cout << "URI:           "
                          << grantee.GetURI() << std::endl;
            }

            std::cout << "Permission:    " <<
                      getPermissionString(grant.GetPermission()) <<
                      std::endl << std::endl;
        }
    }

    return outcome.IsSuccess();
}

//! Routine which converts a built-in type enumeration to a human-readable string.
/*!
 \param type: Type enumeration.
 \return String: Human-readable string
*/
Aws::String getGranteeTypeString(const Aws::S3::Model::Type &type) {
    switch (type) {
        case Aws::S3::Model::Type::AmazonCustomerByEmail:
            return "Email address of an AWS account";
        case Aws::S3::Model::Type::CanonicalUser:
            return "Canonical user ID of an AWS account";
        case Aws::S3::Model::Type::Group:
            return "Predefined Amazon S3 group";
        case Aws::S3::Model::Type::NOT_SET:
            return "Not set";
        default:
            return "Type unknown";
    }
}

//! Routine which converts a built-in type enumeration to a human-readable string.
/*!
 \param permission: Permission enumeration.
 \return String: Human-readable string
*/
Aws::String getPermissionString(const Aws::S3::Model::Permission &permission) {
    switch (permission) {
        case Aws::S3::Model::Permission::FULL_CONTROL:
            return "Can read this object's data and its metadata, "
                   "and read/write this object's permissions";
        case Aws::S3::Model::Permission::NOT_SET:
            return "Permission not set";
        case Aws::S3::Model::Permission::READ:
            return "Can read this object's data and its metadata";
        case Aws::S3::Model::Permission::READ_ACP:
            return "Can read this object's permissions";
            // case Aws::S3::Model::Permission::WRITE // Not applicable.
        case Aws::S3::Model::Permission::WRITE_ACP:
            return "Can write this object's permissions";
        default:
            return "Permission unknown";
    }
}
```

ACL은 새 ACL을 생성하거나 현재 ACL에 지정된 권한 부여를 변경하여 수정할 수 있습니다. 업데이트된 ACL은 `PutObjectAcl` 메서드에 전달하여 새로운 현재 ACL이 됩니다.

다음 코드는 `GetObjectAcl`로 검색된 ACL을 사용하고 여기에 새 권한 부여를 추가합니다. 사용자 또는 피부여자에게 객체에 대한 READ 권한이 부여됩니다. 수정된 ACL은 `PutObjectAcl`로 전달되어 새로운 현재 ACL이 됩니다.

```
bool AwsDoc::S3::putObjectAcl(const Aws::String &bucketName, const Aws::String &objectKey, const Aws::String &ownerID,
                              const Aws::String &granteePermission, const Aws::String &granteeType,
                              const Aws::String &granteeID, const Aws::String &granteeEmailAddress,
                              const Aws::String &granteeURI, const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::Owner owner;
    owner.SetID(ownerID);

    Aws::S3::Model::Grantee grantee;
    grantee.SetType(setGranteeType(granteeType));

    if (!granteeEmailAddress.empty()) {
        grantee.SetEmailAddress(granteeEmailAddress);
    }

    if (!granteeID.empty()) {
        grantee.SetID(granteeID);
    }

    if (!granteeURI.empty()) {
        grantee.SetURI(granteeURI);
    }

    Aws::S3::Model::Grant grant;
    grant.SetGrantee(grantee);
    grant.SetPermission(setGranteePermission(granteePermission));

    Aws::Vector<Aws::S3::Model::Grant> grants;
    grants.push_back(grant);

    Aws::S3::Model::AccessControlPolicy acp;
    acp.SetOwner(owner);
    acp.SetGrants(grants);

    Aws::S3::Model::PutObjectAclRequest request;
    request.SetAccessControlPolicy(acp);
    request.SetBucket(bucketName);
    request.SetKey(objectKey);

    Aws::S3::Model::PutObjectAclOutcome outcome =
            s3Client.PutObjectAcl(request);

    if (!outcome.IsSuccess()) {
        auto error = outcome.GetError();
        std::cerr << "Error: putObjectAcl: " << error.GetExceptionName()
                  << " - " << error.GetMessage() << std::endl;
    } else {
        std::cout << "Successfully added an ACL to the object '" << objectKey
                  << "' in the bucket '" << bucketName << "'." << std::endl;
    }

    return outcome.IsSuccess();
}

//! Routine which converts a human-readable string to a built-in type enumeration.
/*!
 \param access: Human readable string.
 \return Permission: Permission enumeration.
*/
Aws::S3::Model::Permission setGranteePermission(const Aws::String &access) {
    if (access == "FULL_CONTROL")
        return Aws::S3::Model::Permission::FULL_CONTROL;
    if (access == "WRITE")
        return Aws::S3::Model::Permission::WRITE;
    if (access == "READ")
        return Aws::S3::Model::Permission::READ;
    if (access == "WRITE_ACP")
        return Aws::S3::Model::Permission::WRITE_ACP;
    if (access == "READ_ACP")
        return Aws::S3::Model::Permission::READ_ACP;
    return Aws::S3::Model::Permission::NOT_SET;
}

//! Routine which converts a human-readable string to a built-in type enumeration.
/*!
 \param type: Human readable string.
 \return Type: Type enumeration.
*/
Aws::S3::Model::Type setGranteeType(const Aws::String &type) {
    if (type == "Amazon customer by email")
        return Aws::S3::Model::Type::AmazonCustomerByEmail;
    if (type == "Canonical user")
        return Aws::S3::Model::Type::CanonicalUser;
    if (type == "Group")
        return Aws::S3::Model::Type::Group;
    return Aws::S3::Model::Type::NOT_SET;
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_put_object_acl.cpp)는 Github에서 확인하세요.

## 버킷의 액세스 제어 목록 관리
<a name="manage-a-bucket-s-access-control-list"></a>

대부분의 경우 버킷의 액세스 권한을 설정할 때 선호하는 방법은 버킷 정책을 정의하는 것입니다. 그러나 버킷은 액세스 제어 목록을 사용하고자 하는 사용자를 위해 이를 지원하기도 합니다.

버킷에 대한 액세스 제어 목록 관리는 객체에 사용되는 것과 동일합니다. `GetBucketAcl` 메서드는 버킷의 현재 ACL을 검색하고 `PutBucketAcl` 메서드는 버킷에 새 ACL을 적용합니다.

다음 코드는 버킷 ACL을 가져오고 설정하는 방법을 보여줍니다.

```
//! Routine which demonstrates setting the ACL for an S3 bucket.
/*!
  \param bucketName: Name of a bucket.
  \param ownerID: The canonical ID of the bucket owner.
   See https://docs.aws.amazon.com/AmazonS3/latest/userguide/finding-canonical-user-id.html for more information.
  \param granteePermission: The access level to enable for the grantee.
  \param granteeType: The type of grantee.
  \param granteeID: The canonical ID of the grantee.
  \param granteeEmailAddress: The email address associated with the grantee's AWS account.
  \param granteeURI: The URI of a built-in access group.
  \param clientConfig: Aws client configuration.
  \return bool: Function succeeded.
*/

bool AwsDoc::S3::getPutBucketAcl(const Aws::String &bucketName,
                                 const Aws::String &ownerID,
                                 const Aws::String &granteePermission,
                                 const Aws::String &granteeType,
                                 const Aws::String &granteeID,
                                 const Aws::String &granteeEmailAddress,
                                 const Aws::String &granteeURI,
                                 const Aws::S3::S3ClientConfiguration &clientConfig) {
    bool result = ::putBucketAcl(bucketName, ownerID, granteePermission, granteeType,
                                 granteeID,
                                 granteeEmailAddress,
                                 granteeURI,
                                 clientConfig);
    if (result) {
        result = ::getBucketAcl(bucketName, clientConfig);
    }

    return result;
}

//! Routine which demonstrates setting the ACL for an S3 bucket.
/*!
  \param bucketName: Name of from bucket.
  \param ownerID: The canonical ID of the bucket owner.
   See https://docs.aws.amazon.com/AmazonS3/latest/userguide/finding-canonical-user-id.html for more information.
  \param granteePermission: The access level to enable for the grantee.
  \param granteeType: The type of grantee.
  \param granteeID: The canonical ID of the grantee.
  \param granteeEmailAddress: The email address associated with the grantee's AWS account.
  \param granteeURI: The URI of a built-in access group.
  \param clientConfig: Aws client configuration.
  \return bool: Function succeeded.
*/

bool putBucketAcl(const Aws::String &bucketName,
                  const Aws::String &ownerID,
                  const Aws::String &granteePermission,
                  const Aws::String &granteeType,
                  const Aws::String &granteeID,
                  const Aws::String &granteeEmailAddress,
                  const Aws::String &granteeURI,
                  const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::Owner owner;
    owner.SetID(ownerID);

    Aws::S3::Model::Grantee grantee;
    grantee.SetType(setGranteeType(granteeType));

    if (!granteeEmailAddress.empty()) {
        grantee.SetEmailAddress(granteeEmailAddress);
    }

    if (!granteeID.empty()) {
        grantee.SetID(granteeID);
    }

    if (!granteeURI.empty()) {
        grantee.SetURI(granteeURI);
    }

    Aws::S3::Model::Grant grant;
    grant.SetGrantee(grantee);
    grant.SetPermission(setGranteePermission(granteePermission));

    Aws::Vector<Aws::S3::Model::Grant> grants;
    grants.push_back(grant);

    Aws::S3::Model::AccessControlPolicy acp;
    acp.SetOwner(owner);
    acp.SetGrants(grants);

    Aws::S3::Model::PutBucketAclRequest request;
    request.SetAccessControlPolicy(acp);
    request.SetBucket(bucketName);

    Aws::S3::Model::PutBucketAclOutcome outcome =
            s3Client.PutBucketAcl(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &error = outcome.GetError();

        std::cerr << "Error: putBucketAcl: " << error.GetExceptionName()
                  << " - " << error.GetMessage() << std::endl;
    } else {
        std::cout << "Successfully added an ACL to the bucket '" << bucketName
                  << "'." << std::endl;
    }

    return outcome.IsSuccess();
}

//! Routine which demonstrates getting the ACL for an S3 bucket.
/*!
  \param bucketName: Name of the s3 bucket.
  \param clientConfig: Aws client configuration.
  \return bool: Function succeeded.
*/
bool getBucketAcl(const Aws::String &bucketName,
                  const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::GetBucketAclRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::GetBucketAclOutcome outcome =
            s3Client.GetBucketAcl(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: getBucketAcl: "
                  << err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        const Aws::Vector<Aws::S3::Model::Grant> &grants =
                outcome.GetResult().GetGrants();

        for (const Aws::S3::Model::Grant &grant: grants) {
            const Aws::S3::Model::Grantee &grantee = grant.GetGrantee();

            std::cout << "For bucket " << bucketName << ": "
                      << std::endl << std::endl;

            if (grantee.TypeHasBeenSet()) {
                std::cout << "Type:          "
                          << getGranteeTypeString(grantee.GetType()) << std::endl;
            }

            if (grantee.DisplayNameHasBeenSet()) {
                std::cout << "Display name:  "
                          << grantee.GetDisplayName() << std::endl;
            }

            if (grantee.EmailAddressHasBeenSet()) {
                std::cout << "Email address: "
                          << grantee.GetEmailAddress() << std::endl;
            }

            if (grantee.IDHasBeenSet()) {
                std::cout << "ID:            "
                          << grantee.GetID() << std::endl;
            }

            if (grantee.URIHasBeenSet()) {
                std::cout << "URI:           "
                          << grantee.GetURI() << std::endl;
            }

            std::cout << "Permission:    " <<
                      getPermissionString(grant.GetPermission()) <<
                      std::endl << std::endl;
        }
    }

    return outcome.IsSuccess();
}

//! Routine which converts a built-in type enumeration to a human-readable string.
/*!
 \param permission: Permission enumeration.
 \return String: Human-readable string.
*/

Aws::String getPermissionString(const Aws::S3::Model::Permission &permission) {
    switch (permission) {
        case Aws::S3::Model::Permission::FULL_CONTROL:
            return "Can list objects in this bucket, create/overwrite/delete "
                   "objects in this bucket, and read/write this "
                   "bucket's permissions";
        case Aws::S3::Model::Permission::NOT_SET:
            return "Permission not set";
        case Aws::S3::Model::Permission::READ:
            return "Can list objects in this bucket";
        case Aws::S3::Model::Permission::READ_ACP:
            return "Can read this bucket's permissions";
        case Aws::S3::Model::Permission::WRITE:
            return "Can create, overwrite, and delete objects in this bucket";
        case Aws::S3::Model::Permission::WRITE_ACP:
            return "Can write this bucket's permissions";
        default:
            return "Permission unknown";
    }
}

//! Routine which converts a human-readable string to a built-in type enumeration
/*!
 \param access: Human readable string.
 \return Permission: Permission enumeration.
*/
Aws::S3::Model::Permission setGranteePermission(const Aws::String &access) {
    if (access == "FULL_CONTROL")
        return Aws::S3::Model::Permission::FULL_CONTROL;
    if (access == "WRITE")
        return Aws::S3::Model::Permission::WRITE;
    if (access == "READ")
        return Aws::S3::Model::Permission::READ;
    if (access == "WRITE_ACP")
        return Aws::S3::Model::Permission::WRITE_ACP;
    if (access == "READ_ACP")
        return Aws::S3::Model::Permission::READ_ACP;
    return Aws::S3::Model::Permission::NOT_SET;
}

//! Routine which converts a built-in type enumeration to a human-readable string.
/*!
 \param type: Type enumeration.
 \return bool: Human-readable string.
*/
Aws::String getGranteeTypeString(const Aws::S3::Model::Type &type) {
    switch (type) {
        case Aws::S3::Model::Type::AmazonCustomerByEmail:
            return "Email address of an AWS account";
        case Aws::S3::Model::Type::CanonicalUser:
            return "Canonical user ID of an AWS account";
        case Aws::S3::Model::Type::Group:
            return "Predefined Amazon S3 group";
        case Aws::S3::Model::Type::NOT_SET:
            return "Not set";
        default:
            return "Type unknown";
    }
}

Aws::S3::Model::Type setGranteeType(const Aws::String &type) {
    if (type == "Amazon customer by email")
        return Aws::S3::Model::Type::AmazonCustomerByEmail;
    if (type == "Canonical user")
        return Aws::S3::Model::Type::CanonicalUser;
    if (type == "Group")
        return Aws::S3::Model::Type::Group;
    return Aws::S3::Model::Type::NOT_SET;
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_put_bucket_acl.cpp)는 Github에서 확인하세요.

# 버킷 정책을 사용하여 Amazon S3 버킷에 대한 액세스 관리
<a name="examples-s3-bucket-policies"></a>

*버킷 정책*을 설정하거나 가져오거나 삭제하여 Amazon S3 버킷에 대한 액세스를 관리할 수 있습니다.

## 사전 조건
<a name="codeExamplePrereq"></a>

시작하기 전에 [AWS SDK for C\$1\$1사용 시작하기](getting-started.md)를 읽어보시기 바랍니다.

예제 코드를 다운로드하고 [코드 예제 시작하기](getting-started-code-examples.md)에 설명된 대로 솔루션을 빌드합니다.

예제를 실행하려면 코드에서 요청을 만드는 데 사용하는 사용자 프로필에 AWS (서비스 및 작업에 대한) 적절한 권한이 있어야 합니다. 자세한 내용은 자격 [AWS 증명 제공을](credentials.md) 참조하세요.

## 버킷 정책 설정
<a name="set-s3-bucket-policy"></a>

`S3Client`의 `PutBucketPolicy` 함수를 직접적으로 호출하고 [PutBucketPolicyRequest](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_put_bucket_policy_request.html)에 버킷 이름과 정책의 JSON 표현을 제공하여 특정 S3 버킷에 대한 버킷 정책을 설정할 수 있습니다.

 **코드** 

```
//! Build a policy JSON string.
/*!
  \param userArn: Aws user Amazon Resource Name (ARN).
      For more information, see https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns.
  \param bucketName: Name of a bucket.
  \return String: Policy as JSON string.
*/

Aws::String getPolicyString(const Aws::String &userArn,
                            const Aws::String &bucketName) {
    return
            "{\n"
            "   \"Version\":\"2012-10-17\",\n"
            "   \"Statement\":[\n"
            "       {\n"
            "           \"Sid\": \"1\",\n"
            "           \"Effect\": \"Allow\",\n"
            "           \"Principal\": {\n"
            "               \"AWS\": \""
            + userArn +
            "\"\n""           },\n"
            "           \"Action\": [ \"s3:getObject\" ],\n"
            "           \"Resource\": [ \"arn:aws:s3:::"
            + bucketName +
            "/*\" ]\n"
            "       }\n"
            "   ]\n"
            "}";
}
```

```
bool AwsDoc::S3::putBucketPolicy(const Aws::String &bucketName,
                                 const Aws::String &policyBody,
                                 const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    std::shared_ptr<Aws::StringStream> request_body =
            Aws::MakeShared<Aws::StringStream>("");
    *request_body << policyBody;

    Aws::S3::Model::PutBucketPolicyRequest request;
    request.SetBucket(bucketName);
    request.SetBody(request_body);

    Aws::S3::Model::PutBucketPolicyOutcome outcome =
            s3Client.PutBucketPolicy(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Error: putBucketPolicy: "
                  << outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Set the following policy body for the bucket '" <<
                  bucketName << "':" << std::endl << std::endl;
        std::cout << policyBody << std::endl;
    }

    return outcome.IsSuccess();
}
```

**참고**  
[Aws::Utils::Json::JsonValue](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-core/html/class_aws_1_1_utils_1_1_json_1_1_json_value.html) 유틸리티 클래스는 `PutBucketPolicy`에 전달할 유효한 JSON 객체를 구성하는 데 사용할 수 있습니다.

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_bucket_policy.cpp)는 Github에서 확인하세요.

## 버킷 정책 가져오기
<a name="get-s3-bucket-policy"></a>

Amazon S3 버킷에 대한 정책을 가져오려면 `S3Client`의 `GetBucketPolicy` 함수를 직접적으로 호출하고 버킷 이름을 [GetBucketPolicyRequest](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_bucket_policy_request.html)에 전달합니다.

 **코드** 

```
bool AwsDoc::S3::getBucketPolicy(const Aws::String &bucketName,
                                 const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::GetBucketPolicyRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::GetBucketPolicyOutcome outcome =
            s3Client.GetBucketPolicy(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: getBucketPolicy: "
                  << err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        Aws::StringStream policy_stream;
        Aws::String line;

        outcome.GetResult().GetPolicy() >> line;
        policy_stream << line;

        std::cout << "Retrieve the policy for bucket '" << bucketName << "':\n\n" <<
                  policy_stream.str() << std::endl;
    }

    return outcome.IsSuccess();
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_bucket_policy.cpp)는 Github에서 확인하세요.

## 버킷 정책 삭제
<a name="delete-s3-bucket-policy"></a>

버킷 정책을 삭제하려면 `S3Client`의 `DeleteBucketPolicy` 함수를 직접적으로 호출하고 버킷 이름을 [DeleteBucketPolicyRequest](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_delete_bucket_policy_request.html)에 제공합니다.

 **코드** 

```
bool AwsDoc::S3::deleteBucketPolicy(const Aws::String &bucketName,
                                    const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);

    Aws::S3::Model::DeleteBucketPolicyRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::DeleteBucketPolicyOutcome outcome = client.DeleteBucketPolicy(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();
        std::cerr << "Error: deleteBucketPolicy: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Policy was deleted from the bucket." << std::endl;
    }

    return outcome.IsSuccess();
}
```

이 함수는 버킷에 정책이 아직 존재하지 않더라도 성공합니다. 존재하지 않는 버킷 이름을 지정하거나 해당 버킷에 대한 액세스 권한이 없는 경우 `AmazonServiceException`이 발생합니다.

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/delete_bucket_policy.cpp)는 Github에서 확인하세요.

## 추가 정보
<a name="more-info"></a>
+  Amazon Simple Storage Service API 참조의 [PutBucketPolicy](https://docs.aws.amazon.com/AmazonS3/latest/API/PutBucketPolicy.html)
+  Amazon Simple Storage Service API 참조의 [GetBucketPolicy](https://docs.aws.amazon.com/AmazonS3/latest/API/GetBucketPolicy.html)
+  Amazon Simple Storage Service API 참조의 [DeleteBucketPolicy](https://docs.aws.amazon.com/AmazonS3/latest/API/DeleteBucketPolicy.html)
+  Amazon Simple Storage Service 사용 설명서의 [액세스 정책 언어 개요](https://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html)
+  Amazon Simple Storage Service 사용 설명서의 [버킷 정책 예](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html)

# Amazon S3 버킷을 웹 사이트로 구성
<a name="examples-s3-website-configuration"></a>

Amazon S3 버킷이 웹 사이트로 작동하도록 구성할 수 있습니다. 이렇게 하려면 웹 사이트 구성을 설정해야 합니다.

## 사전 조건
<a name="codeExamplePrereq"></a>

시작하기 전에 [AWS SDK for C\$1\$1사용 시작하기](getting-started.md)를 읽어보시기 바랍니다.

예제 코드를 다운로드하고 [코드 예제 시작하기](getting-started-code-examples.md)에 설명된 대로 솔루션을 빌드합니다.

예제를 실행하려면 코드에서 요청을 만드는 데 사용하는 사용자 프로필에 AWS (서비스 및 작업에 대한) 적절한 권한이 있어야 합니다. 자세한 내용은 자격 [AWS 증명 제공을](credentials.md) 참조하세요.

## 버킷의 웹 사이트 구성 설정
<a name="set-a-bucket-s-website-configuration"></a>

Amazon S3 버킷의 웹 사이트 구성을 설정하려면 `S3Client`의 `PutBucketWebsite` 함수를 직접적으로 호출합니다. 이때 버킷 이름과 [WebsiteConfiguration](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_website_configuration.html) 객체에 제공되는 웹 사이트 구성이 포함된 [PutBucketWebsiteRequest](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_put_bucket_website_request.html) 객체를 함께 사용합니다.

인덱스 문서 설정은 *필수*이며, 그 밖의 다른 파라미터는 선택적 파라미터입니다.

 **코드** 

```
bool AwsDoc::S3::putWebsiteConfig(const Aws::String &bucketName,
                                  const Aws::String &indexPage, const Aws::String &errorPage,
                                  const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);

    Aws::S3::Model::IndexDocument indexDocument;
    indexDocument.SetSuffix(indexPage);

    Aws::S3::Model::ErrorDocument errorDocument;
    errorDocument.SetKey(errorPage);

    Aws::S3::Model::WebsiteConfiguration websiteConfiguration;
    websiteConfiguration.SetIndexDocument(indexDocument);
    websiteConfiguration.SetErrorDocument(errorDocument);

    Aws::S3::Model::PutBucketWebsiteRequest request;
    request.SetBucket(bucketName);
    request.SetWebsiteConfiguration(websiteConfiguration);

    Aws::S3::Model::PutBucketWebsiteOutcome outcome =
            client.PutBucketWebsite(request);

    if (!outcome.IsSuccess()) {
        std::cerr << "Error: PutBucketWebsite: "
                  << outcome.GetError().GetMessage() << std::endl;
    } else {
        std::cout << "Success: Set website configuration for bucket '"
                  << bucketName << "'." << std::endl;
    }

    return outcome.IsSuccess();
}
```

**참고**  
웹 사이트 구성을 설정해도 버킷의 액세스 권한을 수정되지 않습니다. 또한 파일이 웹에 표시되도록 하려면 버킷 내 파일에 대한 퍼블릭 읽기 액세스 권한을 허용하는 *버킷 정책*을 설정해야 합니다. 자세한 내용은 [Managing Access to Amazon S3 Buckets Using Bucket Policies](examples-s3-bucket-policies.md) 단원을 참조하십시오.

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/put_website_config.cpp)는 Github에서 확인하세요.

## 버킷의 웹 사이트 구성 가져오기
<a name="get-a-bucket-s-website-configuration"></a>

Amazon S3 버킷의 웹 사이트 구성을 가져오려면 `S3Client`의 `GetBucketWebsite` 함수를 직접적으로 호출합니다. 이때 구성을 가져올 버킷의 이름이 포함된 [GetBucketWebsiteRequest](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_bucket_website_request.html)를 와 함께 사용합니다.

구성은 결과 객체 내에서 [GetBucketWebsiteResult](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_get_bucket_website_result.html) 객체로 반환됩니다. 버킷에 대한 웹 사이트 구성이 없으면 `null`이 반환됩니다.

 **코드** 

```
bool AwsDoc::S3::getWebsiteConfig(const Aws::String &bucketName,
                                  const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client s3Client(clientConfig);

    Aws::S3::Model::GetBucketWebsiteRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::GetBucketWebsiteOutcome outcome =
            s3Client.GetBucketWebsite(request);

    if (!outcome.IsSuccess()) {
        const Aws::S3::S3Error &err = outcome.GetError();

        std::cerr << "Error: GetBucketWebsite: "
                  << err.GetMessage() << std::endl;
    } else {
        Aws::S3::Model::GetBucketWebsiteResult websiteResult = outcome.GetResult();

        std::cout << "Success: GetBucketWebsite: "
                  << std::endl << std::endl
                  << "For bucket '" << bucketName << "':"
                  << std::endl
                  << "Index page : "
                  << websiteResult.GetIndexDocument().GetSuffix()
                  << std::endl
                  << "Error page: "
                  << websiteResult.GetErrorDocument().GetKey()
                  << std::endl;
    }

    return outcome.IsSuccess();
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/get_website_config.cpp)는 Github에서 확인하세요.

## 버킷의 웹 사이트 구성 삭제
<a name="delete-a-bucket-s-website-configuration"></a>

Amazon S3 버킷의 웹 사이트 구성을 삭제하려면 `S3Client`의 `DeleteBucketWebsite` 함수를 직접적으로 호출합니다. 이때 구성을 삭제할 버킷의 이름이 포함된 [DeleteBucketWebsiteRequest](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3/html/class_aws_1_1_s3_1_1_model_1_1_delete_bucket_website_request.html)를 함께 사용합니다.

 **코드** 

```
bool AwsDoc::S3::deleteBucketWebsite(const Aws::String &bucketName,
                                     const Aws::S3::S3ClientConfiguration &clientConfig) {
    Aws::S3::S3Client client(clientConfig);
    Aws::S3::Model::DeleteBucketWebsiteRequest request;
    request.SetBucket(bucketName);

    Aws::S3::Model::DeleteBucketWebsiteOutcome outcome =
            client.DeleteBucketWebsite(request);

    if (!outcome.IsSuccess()) {
        auto err = outcome.GetError();
        std::cerr << "Error: deleteBucketWebsite: " <<
                  err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
    } else {
        std::cout << "Website configuration was removed." << std::endl;
    }

    return outcome.IsSuccess();
}
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3/delete_website_config.cpp)는 Github에서 확인하세요.

## 추가 정보
<a name="more-information"></a>
+  Amazon Simple Storage Service API 참조의 [PUT 버킷 웹 사이트](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTwebsite.html)
+  Amazon Simple Storage Service API 참조의 [GET 버킷 웹 사이트](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETwebsite.html)
+  Amazon Simple Storage Service API 참조의 [DELETE 버킷 웹 사이트](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETEwebsite.html)

# Amazon S3 작업에 TransferManager 사용
<a name="examples-s3-transfermanager"></a>

클래스를 AWS SDK for C\$1\$1 `TransferManager` 사용하여 로컬 환경에서 Amazon S3로 파일을 안정적으로 전송하고 한 Amazon S3 위치에서 다른 위치로 객체를 복사할 수 있습니다.는 전송 진행 상황을 확인하고 업로드 및 다운로드를 일시 중지하거나 재개할 `TransferManager` 수 있습니다.

**참고**  
불완전하거나 부분적인 업로드에 대한 요금이 부과되지 않도록 Amazon S3 버킷에서 [AbortIncompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpu-abort-incomplete-mpu-lifecycle-config.html) 수명 주기 규칙을 활성화하는 것이 좋습니다.  
이 규칙은 시작된 후 지정된 일수 내에 완료되지 않은 멀티파트 업로드를 중단하도록 Amazon S3에 지시합니다. 설정된 시간 제한을 초과하면 Amazon S3에서 업로드를 중단한 후 완료되지 않은 업로드 데이터를 삭제합니다.  
자세한 내용은 Amazon S3 사용 설명서의 [버킷에서 수명 주기 구성 설정](https://docs.aws.amazon.com/AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html)을 참조하세요.

## 사전 조건
<a name="codeExamplePrereq"></a>

시작하기 전에 [AWS SDK for C\$1\$1사용 시작하기](getting-started.md)를 읽어보시기 바랍니다.

예제 코드를 다운로드하고 [코드 예제 시작하기](getting-started-code-examples.md)에 설명된 대로 솔루션을 빌드합니다.

예제를 실행하려면 코드에서 요청을 만드는 데 사용하는 사용자 프로필에 AWS (서비스 및 작업에 대한) 적절한 권한이 있어야 합니다. 자세한 내용은 자격 [AWS 증명 제공을](credentials.md) 참조하세요.

## `TransferManager`를 사용한 객체 업로드 및 다운로드
<a name="stream"></a>

이 예제는 [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/class_aws_1_1_transfer_1_1_transfer_manager.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/class_aws_1_1_transfer_1_1_transfer_manager.html)가 메모리 내 대형 객체를 전송하는 방식을 보여줍니다. `UploadFile` 및 `DownloadFile` 메서드는 모두 비동기적으로 직접 호출되며 요청 상태를 관리하기 위해 `TransferHandle`을 반환합니다. 업로드된 객체가 `bufferSize`보다 클 경우 멀티파트 업로드가 수행됩니다. `bufferSize`는 기본적으로 5MB로 설정되지만 [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/struct_aws_1_1_transfer_1_1_transfer_manager_configuration.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-transfer/html/struct_aws_1_1_transfer_1_1_transfer_manager_configuration.html)을 통해 구성할 수 있습니다.

```
        auto s3_client = Aws::MakeShared<Aws::S3::S3Client>("S3Client");
        auto executor = Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>("executor", 25);
        Aws::Transfer::TransferManagerConfiguration transfer_config(executor.get());
        transfer_config.s3Client = s3_client;

        // Create buffer to hold data received by the data stream.
        Aws::Utils::Array<unsigned char> buffer(BUFFER_SIZE);

        // The local variable 'streamBuffer' is captured by reference in a lambda.
        // It must persist until all downloading by the 'transfer_manager' is complete.
        Stream::PreallocatedStreamBuf streamBuffer(buffer.GetUnderlyingData(), buffer.GetLength());

        auto transfer_manager = Aws::Transfer::TransferManager::Create(transfer_config);

        auto uploadHandle = transfer_manager->UploadFile(LOCAL_FILE, BUCKET, KEY, "text/plain", Aws::Map<Aws::String, Aws::String>());
        uploadHandle->WaitUntilFinished();
        bool success = uploadHandle->GetStatus() == Transfer::TransferStatus::COMPLETED; 
      
        if (!success)
        {
            auto err = uploadHandle->GetLastError();           
            std::cout << "File upload failed:  "<< err.GetMessage() << std::endl;
        }
        else
        {
            std::cout << "File upload finished." << std::endl;

            auto downloadHandle = transfer_manager->DownloadFile(BUCKET,
                KEY,
                [&]() { //Define a lambda expression for the callback method parameter to stream back the data.
                    return Aws::New<MyUnderlyingStream>("TestTag", &streamBuffer);
                });
            downloadHandle->WaitUntilFinished();// Block calling thread until download is complete.
            auto downStat = downloadHandle->GetStatus();
            if (downStat != Transfer::TransferStatus::COMPLETED)
            {
                auto err = downloadHandle->GetLastError();
                std::cout << "File download failed:  " << err.GetMessage() << std::endl;
            }
            std::cout << "File download to memory finished."  << std::endl;
```

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/transfer-manager/transferOnStream.cpp)는 Github에서 확인하세요.

# Amazon S3 작업에 `S3CrtClient` 사용
<a name="examples-s3-crt"></a>

`S3CrtClient` 클래스는 버전 1.9에서 사용할 수 AWS SDK for C\$1\$1 있으며 Amazon S3에서 대용량 데이터 파일을 업로드하고 다운로드하는 처리량을 개선합니다. 이 릴리스의 개선 사항에 대한 자세한 내용은 [AWS SDK for C\$1\$1 v1.9를 사용한 Amazon S3 처리량 개선을 ](https://github.com/aws/aws-sdk-cpp/wiki/Improving-S3-Throughput-with-AWS-SDK-for-CPP-v1.9)참조하세요.

`S3CrtClient`는 [AWS 공통 런타임(CRT) 라이브러리](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html) 위에 구현됩니다.

**참고**  
불완전하거나 부분적인 업로드에 대한 요금이 부과되지 않도록 Amazon S3 버킷에서 [AbortIncompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpu-abort-incomplete-mpu-lifecycle-config.html) 수명 주기 규칙을 활성화하는 것이 좋습니다.  
이 규칙은 시작된 후 지정된 일수 내에 완료되지 않은 멀티파트 업로드를 중단하도록 Amazon S3에 지시합니다. 설정된 시간 제한을 초과하면 Amazon S3에서 업로드를 중단한 후 완료되지 않은 업로드 데이터를 삭제합니다.  
자세한 내용은 Amazon S3 사용 설명서의 [버킷에서 수명 주기 구성 설정](https://docs.aws.amazon.com/AmazonS3/latest/userguide/how-to-set-lifecycle-configuration-intro.html)을 참조하세요.

## 사전 조건
<a name="codeExamplePrereq"></a>

시작하기 전에 [AWS SDK for C\$1\$1사용 시작하기](getting-started.md)를 읽어보시기 바랍니다.

예제 코드를 다운로드하고 [코드 예제 시작하기](getting-started-code-examples.md)에 설명된 대로 솔루션을 빌드합니다.

예제를 실행하려면 코드에서 요청을 만드는 데 사용하는 사용자 프로필에 AWS (서비스 및 작업에 대한) 적절한 권한이 있어야 합니다. 자세한 내용은 자격 [AWS 증명 제공을](credentials.md) 참조하세요.

## `S3CrtClient`를 사용한 객체 업로드 및 다운로드
<a name="stream"></a>

이 예제는 [https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3-crt/html/class_aws_1_1_s3_crt_1_1_s3_crt_client.html](https://docs.aws.amazon.com/sdk-for-cpp/latest/api/aws-cpp-sdk-s3-crt/html/class_aws_1_1_s3_crt_1_1_s3_crt_client.html) 사용 방법을 보여줍니다. 이 예제에서는 버킷을 생성하고, 객체를 업로드하고, 객체를 다운로드한 다음 파일과 버킷을 삭제합니다. PUT 작업은 멀티파트 업로드로 변환됩니다. GET 작업은 여러 개의 “범위 지정” GET 요청으로 변환됩니다. 멀티파트 업로드에 대한 자세한 내용은 Amazon S3 사용 설명서에서 [멀티파트 업로드를 사용한 객체 업로드 및 복사](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html)를 참조하세요.

제공된 데이터 파일 `ny.json`은 이 예제에서 멀티파트 업로드로 업로드됩니다. 프로그램을 성공적으로 실행한 후 디버그 로그를 검토하면 이를 확인할 수 있습니다.

업로드에 실패하면 기본 CRT 라이브러리에서 `AbortMultipartUpload`가 발행되어 이미 업로드된 부분을 정리합니다. 그러나 네트워크 케이블이 뽑힌 경우처럼 모든 오류를 내부적으로 처리할 수 있는 것은 아닙니다. 부분적으로 업로드된 데이터가 계정에 남아 있지 않도록(부분적으로 업로드된 데이터도 과금 대상임) Amazon S3 버킷에 수명 주기 규칙을 생성하는 것이 좋습니다. 수명 주기 규칙을 설정하는 방법을 알아보려면 [Amazon S3 비용을 줄이기 위해 불완전 멀티파트 업로드 검색 및 삭제](https://aws.amazon.com/blogs/aws-cost-management/discovering-and-deleting-incomplete-multipart-uploads-to-lower-amazon-s3-costs/ )를 참조하세요.

**디버그 로그를 사용하여 멀티파트 업로드 세부 정보 탐색**

1. `main()`에는 코드 업데이트 지침이 포함된 "TODO" 주석이 있습니다.

   1. `file_name`: 코드 주석에 제공된 링크에서 샘플 데이터 파일 `ny.json`를 다운로드하거나 자체 대용량 데이터 파일을 사용합니다.

   1. 의 경우`region`: 열거형을 사용하여 `region` 변수를 계정 AWS 리전 의 로 업데이트합니다. 계정의 리전을 찾으려면 AWS Management Console에 로그인한 후 오른쪽 상단 모서리에서 리전을 찾습니다.

1. 예제를 빌드합니다.

1. `file_name` 변수로 지정된 파일을 실행 파일 폴더로 복사하고 `s3-crt-demo` 실행 파일을 실행합니다.

1. 실행 파일 폴더에서 최신 `.log` 파일을 찾습니다.

1. 로그 파일을 열고 **검색**을 선택한 다음 **partNumber**를 입력합니다.

1. 로그에는 다음과 유사한 항목이 포함되어 있습니다. 여기서 `partNumber`와 `uploadId`는 업로드된 파일의 각 부분마다 지정됩니다.

    `PUT /my-object partNumber=1&uploadId=gsk8vDbmnlA5EseDo._LDEgq22Qmt0SeuszYxMsZ9ABt503VqDIFOP8xzZI1P0zp.ToS.qo5kK16HNWogZF3KpRo.Dc7QnLZIK0BTmzCWwWoPax4T21hvP6nPdz9591F content-length:8388608 host:my-bucketasdfasdf.s3.us-east-2.amazonaws.com x-amz-content-sha256:UNSIGNED-PAYLOAD`

    및 

    `PUT /my-object partNumber=2&uploadId=gsk8vDbmnlA5EseDo._LDEgq22Qmt0SeuszYxMsZ9ABt503VqDIFOP8xzZI1P0zp.ToS.qo5kK16HNWogZF3KpRo.Dc7QnLZIK0BTmzCWwWoPax4T21hvP6nPdz9591F content-length:8388608 host:my-bucketasdfasdf.s3.us-east-2.amazonaws.com x-amz-content-sha256:UNSIGNED-PAYLOAD `

[전체 예제](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3-crt/s3-crt-demo.cpp)는 Github에서 확인하세요.