Updated on 2026-08-03 GMT+08:00

Deleting the Custom Domain Name of a Bucket (SDK for C)

If you have any questions during development, post them on the Issues page of GitHub.

Function

You can configure a custom domain name for an OBS bucket so that you can use the domain name to access OBS.

This API is used to delete the custom domain name of a bucket.

Restrictions

Method

1
void delete_bucket_custom_domain(const obs_options *options, obs_response_handler *handler, void *callback_data);

Request Parameters

Table 1 List of request parameters

Parameter

Type

Mandatory (Yes/No)

Description

options

const obs_options*

Yes

Explanation:

Context of the requested bucket. Refer to Configuring option (SDK for C) to set the AK, SK, endpoint, bucket, timeout interval, and temporary credentials through obs_options.

Restrictions:

None

Value range:

None

Default value:

None

handler

obs_response_handler *

Yes

Explanation:

A callback structure where all members are pointers to callback functions, used to set the callback functions that handle response data. You can set a callback function to copy the response data from the server to callback_data (custom callback data).

Restrictions:

None

Value range:

None

Default value:

None

callback_data

void *

Yes

Explanation:

Custom callback data

Restrictions:

None

Value range:

None

Default value:

None

Table 2 obs_options

Parameter

Type

Mandatory (Yes/No)

Description

bucket_options

obs_bucket_context

Yes

Explanation:

Bucket settings

Restrictions:

None

Value range:

None

Default value:

None

request_options

obs_http_request_option

Yes

Explanation:

Request-related settings

Restrictions:

None

Value range:

None

Default value:

None

temp_auth

temp_auth_configure*

No

Explanation:

Structure used for temporary signature calculation. Set this parameter to NULL if it is not used.

Restrictions:

None

Value range:

None

Default value:

None

Table 3 obs_bucket_context

Parameter

Type

Mandatory (Yes/No)

Description

host_name

char *

Yes

Explanation:

Requested host name, used as an address for connecting to OBS. It is the domain name (the endpoint) of the server where the requested resource is stored.

Example: host_name = "obs.ap-southeast-1.myhuaweicloud.com";

Restrictions:

The value does not need to contain http:// or https:// as a prefix, which is controlled using obs_protocol.

Value range:

To view the endpoints available for OBS, see Regions and Endpoints.

Default value:

None

bucket_name

char *

Yes

Explanation:

Bucket name

Restrictions:

  • A bucket name must be unique across all accounts and regions.
  • A bucket name:
    • Must be 3 to 63 characters long and start with a digit or letter. Lowercase letters, digits, hyphens (-), and periods (.) are allowed.
    • Cannot be an IP address.
    • Cannot start or end with a hyphen (-) or period (.).
    • Cannot contain two consecutive periods (..), for example, my..bucket.
    • Cannot contain a period (.) and a hyphen (-) adjacent to each other, for example, my-.bucket or my.-bucket.
  • If you repeatedly create buckets with the same name in the same region, no error will be reported and the bucket properties comply with those set in the first creation request.

Value range:

None

Default value:

None

useCname

bool

No

Explanation:

Whether to use a custom domain name to access OBS

Restrictions:

None

Value range:

true: A custom domain name is used.

false: A custom domain name is not used.

Default value:

false

protocol

obs_protocol

No

Explanation:

Whether to use the HTTP or HTTPS protocol

Restrictions:

None

Value range:

For details, see obs_protocol.

Default value:

OBS_PROTOCOL_HTTPS (HTTPS is used by default.)

access_key

char *

Yes

Explanation:

Access key ID (AK)

Restrictions:

None

Value range:

For details, see Creating Access Keys.

Default value:

None

secret_access_key

char *

Yes

Explanation:

Secret access key (SK)

Restrictions:

None

Value range:

For details, see Creating Access Keys.

Default value:

None

storage_class

obs_storage_class

No

Explanation:

Bucket storage class that can be specified during bucket creation

Restrictions:

None

Value range:

For details, see obs_storage_class.

Default value:

OBS_STORAGE_CLASS_STANDARD (Standard storage class)

token

char *

No

Explanation:

Security token in temporary credentials

Restrictions:

None

Value range:

For details, see Creating Access Keys.

Default value:

None

epid

char *

No

Explanation:

Enterprise project ID that can be specified during bucket creation. Users who have enabled the enterprise project function can obtain the ID from the enterprise project service.

Restrictions:

The value is in UUID format. This parameter is not required if you have not enabled an enterprise project.

Example: 9892d768-2d13-450f-aac7-ed0e44c2585f

Default value:

None

bucket_type

obs_bucket_type

No

Explanation:

Whether a bucket is an object bucket or a parallel file system

Restrictions:

None

Value range:

For details, see obs_bucket_type.

Default value:

OBS_BUCKET_OBJECT (object bucket)

bucket_list_type

obs_bucket_list_type

No

Explanation:

Whether to list all buckets, object buckets, or parallel file systems

Restrictions:

None

Value range:

For details, see obs_bucket_list_type.

Table 4 obs_protocol

Constant

Original Value

Description

OBS_PROTOCOL_HTTPS

https

HTTPS is used for access.

OBS_PROTOCOL_HTTP

http

HTTP is used for access.

Table 5 obs_storage_class

Constant

Original Value

Description

OBS_STORAGE_CLASS_STANDARD

STANDARD

Standard storage class.

This class features low access latency and high throughput and is used for storing massive, frequently accessed (multiple times a month) or small objects (< 1 MB) requiring quick response.

OBS_STORAGE_CLASS_STANDARD_IA

STANDARD_IA

Infrequent Access storage class.

Used for storing data that is semi-frequently accessed (fewer than 12 times a year) but becomes instantly available when needed.

OBS_STORAGE_CLASS_GLACIER

GLACIER

Archive storage class.

Used for storing rarely accessed (once a year) data.

Table 6 obs_bucket_type

Constant

Original Value

Description

OBS_BUCKET_OBJECT

OBJECT

Object buckets.

OBS_BUCKET_PFS

POSIX

Parallel file systems.

Table 7 obs_bucket_list_type

Constant

Original Value

Description

OBS_BUCKET_LIST_ALL

No header is sent.

Lists all buckets.

OBS_BUCKET_LIST_OBJECT

OBJECT

Lists all object buckets.

OBS_BUCKET_LIST_PFS

POSIX

Lists all parallel file systems.

Table 8 obs_http_request_option

Parameter

Type

Mandatory (Yes/No)

Description

connect_time

int

Yes

Explanation:

Timeout period for establishing an HTTP/HTTPS connection, in ms.

Restrictions:

None

Value range:

[10000, 60000]

Default value:

60000

max_connected_time

int

Yes

Explanation:

Timeout period (in seconds) of a request.

Restrictions:

None

Value range:

None

Default value:

0 (There is never automatic disconnection.)

proxy_auth

char*

No

Explanation:

Proxy authentication information, in the format username:password

Restrictions:

None

Value range:

None

Default value:

None

proxy_host

char*

No

Explanation:

IP address or host name of the proxy server.

Restrictions:

None

Value range:

None

Default value:

None

Table 9 temp_auth_configure

Parameter

Type

Mandatory (Yes/No)

Description

expires

long long int

Yes

Explanation:

Validity period of the temporary credentials, in seconds

Restrictions:

None

Value range:

0 to 630720000

Default value:

None

temp_auth_callback

void (*temp_auth_callback)(char *temp_auth_url,

uint64_t temp_auth_url_len,

char*temp_auth_headers,

uint64_t temp_auth_headers_len,

void*callback_data)

Yes

Explanation:

Pointer to the custom callback function, which is used to record the temporary URL and involved signature header to the custom callback data

Restrictions:

None

Value range:

None

Default value:

None

callback_data

void *

Yes

Explanation:

Custom callback data

Restrictions:

None

Value range:

None

Default value:

None

Table 10 temp_auth_callback

Parameter

Type

Mandatory (Yes/No)

Description

temp_auth_url

char *

Yes

Explanation:

Temporary URL. OBS allows you to construct a URL for a specific operation. In such a URL, you use Query parameters to provide authentication information including the user AK, signature, and validity period. Anyone who has the URL can perform the specified operation. After receiving a request made using such a URL, OBS treats the requester as the user who issued the URL and processes the request. For example, if you construct a pre-signed URL for downloading an object and provide it to various users, they can use the URL to download the object without authentication, but they must do so within the validity period specified by the Expires parameter.

Restrictions:

None

Value range:

None

Default value:

None

temp_auth_url_len

uint64_t

Yes

Explanation:

Length of the temporary URL.

Restrictions:

None

Value range:

None

Default value:

None

temp_auth_headers

char *

Yes

Explanation:

Headers for temporary authentication.

Restrictions:

None

Value range:

None

Default value:

None

temp_auth_headers_len

uint64_t

Yes

Explanation:

Length of the buffer for temporary authentication headers, in bytes.

Restrictions:

None

Value range:

None

Default value:

None

callback_data

void *

Yes

Explanation:

Custom callback data.

Restrictions:

None

Value range:

None

Default value:

None

Table 11 obs_response_handler

Parameter

Type

Mandatory (Yes/No)

Description

properties_callback

obs_response_properties_callback *

Yes

Explanation:

Details about the request failure, including the error message and resource information. You are advised to record them in callback_data (custom callback data).

Restrictions:

None

Value range:

None

Default value:

None

complete_callback

obs_response_complete_callback *

Yes

Explanation:

Pointer to the completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).

Restrictions:

None

Value range:

None

Default value:

None

Table 12 obs_response_properties_callback

Parameter

Type

Mandatory (Yes/No)

Description

properties

const obs_response_properties*

Yes

Explanation:

Parameters in the response headers. You are advised to record them in callback_data (custom callback data).

Restrictions:

None

Value range:

None

Default value:

None

callback_data

void *

Yes

Explanation:

Pointer to the custom callback data

Restrictions:

None

Value range:

None

Default value:

None

Table 13 obs_response_complete_callback

Parameter

Type

Mandatory (Yes/No)

Description

status

obs_status

Yes

Explanation:

Internal request status code of the SDK

Restrictions:

None

Value range:

For details, see obs_status.

error_details

const obs_error_details*

Yes

Explanation:

Details about the request failure, including the error message and resource information. You are advised to record them in callback_data (custom callback data).

Restrictions:

None

Value range:

None

Default value:

None

callback_data

void *

Yes

Explanation:

Pointer to the custom callback data

Restrictions:

None

Value range:

None

Default value:

None

Table 14 obs_response_properties

Parameter

Type

Mandatory (Yes/No)

Description

request_id

const char *

No

Explanation:

Value created by OBS to uniquely identify the request. OBS uses this value to locate the fault.

Restrictions:

None

Value range:

None

Default value:

None

request_id2

const char *

No

Explanation:

Special symbol that helps locate faults

Restrictions:

None

Value range:

None

Default value:

None

content_type

const char *

No

Explanation:

MIME type of the object. MIME type is a standard way of describing a data type and is used by the browser to decide how to display data.

Restrictions:

None

Value range:

None

Default value:

None

content_length

uint64_t

No

Explanation:

Length of the response body, in bytes

Restrictions:

None

Value range:

None

Default value:

None

server

const char *

No

Explanation:

Server header in an HTTP request

Restrictions:

None

Value range:

None

Default value:

None

etag

const char *

No

Explanation:

Base64-encoded, 128-bit MD5 value of an object. ETag is the unique identifier of the object content. It can be used to determine whether the object content is changed. For example, if the ETag is A when an object is uploaded and is B when the object is downloaded, it indicates that the object content has been changed. The ETag reflects changes to the object content, rather than the object metadata. An object created by an upload or copy operation has a unique ETag.

Restrictions:

If an object is encrypted using server-side encryption, the ETag is not the MD5 value of the object.

Value range:

The value must contain 32 characters.

Default value:

None

expiration

const char *

No

Explanation:

Expiration details of an object

Restrictions:

None

Value range:

An integer greater than 0, in days

Default value:

None

website_redirect_location

const char *

No

Explanation:

Indicates where an object request is redirected. If the bucket that contains the object is configured with Website settings, this parameter can be set in the object metadata so that the request for the object can be redirected to another object in the same bucket or an external URL after the website returns a 301 redirect response.

The request is redirected to another object in the bucket:

x-obs-website-redirect-location:/anotherPage.html

The request is redirected to an external URL:

x-obs-website-redirect-location:http://www.example.com/

OBS obtains the specified value from the header and stores it in the object metadata WebsiteRedirectLocation.

Restrictions:

  • The value must start with a slash (/), http://, or https:// and cannot exceed 2 KB.
  • OBS only supports redirection for objects in the root directory of a bucket.

Value range:

None

Default value:

None

version_id

const char *

No

Explanation:

Object version ID

Restrictions:

If an object has no version ID, the value is NULL.

Value range:

The value must contain 32 characters.

Default value:

None

meta_data_count

int

No

Explanation:

Number of elements in the meta_data array

Restrictions:

None

Value range:

None

Default value:

None

meta_data

const obs_name_value *

No

Explanation:

Custom metadata of an object. You can add custom metadata headers that start with x-obs-meta- for easy object management. When you retrieve or query the metadata of the object, the added custom metadata headers will be returned in the response.

Restrictions:

None

use_server_side_encryption

char

No

Explanation:

If server-side encryption is enabled, this parameter is set to '\1'.

Restrictions:

None

Value range:

None

Default value:

None

allow_origin

const char *

No

Explanation:

Indicates that the origin is included in the response if the origin in the request meets the CORS configuration requirements on the server.

Restrictions:

None

Value range:

The value that complies with the CORS

Default value:

None

allow_headers

const char *

No

Explanation:

Indicates that the headers are included in the response if the headers in the request meet the CORS configuration requirements on the server.

Restrictions:

At most one asterisk (*) is allowed. Spaces, ampersands (&), colons (:), less-than signs (<), and full-width characters are not allowed.

Value range:

The value that complies with the CORS

Default value:

None

max_age

const char *

No

Explanation:

MaxAgeSeconds in the CORS rules of the bucket. It specifies the duration your client can cache the response for a cross-origin request.

Restrictions:

Each CORS rule can contain at most one MaxAgeSeconds.

Value range:

An integer greater than or equal to 0, in seconds

Default value:

3000

allow_methods

const char *

No

Explanation:

Indicates that methods in the rule are included in the response if Access-Control-Request-Method in the request meets the CORS configuration requirements on the server.

Restrictions:

None

Value range:

  • GET
  • PUT
  • HEAD
  • POST
  • DELETE

Default value:

None

expose_headers

const char *

No

Explanation:

ExposeHeader in the CORS rules of the bucket. It specifies the CORS-allowed additional headers in the response. These headers provide additional information to clients. By default, a browser can access only headers Content-Length and Content-Type. If the browser needs to access other headers, you need to configure them in this parameter.

Restrictions:

Spaces, asterisks (*), ampersands (&), colons (:), less-than signs (<), and full-width characters are not allowed.

Value range:

None

Default value:

None

storage_class

const char *

No

Explanation:

Object storage class

Restrictions:

This header is returned only when the storage class of an object is not Standard.

Value range:
  • WARM (Infrequent Access storage)
  • COLD (Archive storage)

Default value:

None

server_side_encryption

const char *

No

Explanation:

Server-side encryption method

Example: x-obs-server-side-encryption:kms

Restrictions:

This header is included in a response if SSE-KMS is used.

Value range:

  • kms (SSE-KMS encryption)
  • obs (SSE-OBS encryption)

Default value:

None

kms_key_id

const char *

No

Explanation:

Key ID. If the SSE-KMS encryption is used with a specified key, the key ID is required.

Restrictions:

This header can only be used when you specify kms for the server_side_encryption header.

Value range:

None

Default value:

If you specify kms for encryption but do not specify a key ID, the default master key will be used. If there is no default master key, OBS will create one and use it.

customer_algorithm

const char *

No

Explanation:

Decryption algorithm. This header is included in a response if SSE-C is used.

Restrictions:

None

Value range:

AES256 (AES256 decryption algorithm)

Default value:

None

customer_key_md5

const char *

No

Explanation:

MD5 value of the key used for decryption. This header is included in a response if SSE-C is used.

Restrictions:

Base64-encoded MD5 value of the key, for example, 4XvB3tbNTN+tIEVa0/fGaQ==

Value range:

Base64-encoded MD5 value of the key ID

Default value:

None

bucket_location

const char *

No

Explanation:

Bucket location

Restrictions:

None

Value range:

None

Default value:

None

obs_version

const char *

No

Explanation:

OBS version of a bucket

Restrictions:

None

Value range:

  • 3.0: bucket of the latest version
  • --: bucket of an earlier version

Default value:

None

restore

const char *

No

Explanation:

Restoration status of an object

Examples: ongoing-request="true" (the object is being restored); ongoing-request="false", expiry-date="Wed, 7 Nov 2012 00:00:00 GMT" (the object has been restored) expiry-date indicates when the restored object will expire.

Restrictions:

For an Archive object that is being restored or has been restored, this header is returned.

Value range:

None

Default value:

None

obs_object_type

const char *

No

Explanation:

Object type

Restrictions:

This header is returned only when the object type is not Normal.

Value range:

Appendable

Default value:

None

obs_next_append_position

const char *

No

Explanation:

Position to be provided for the next request

Restrictions:

This header is returned only when an object is appendable.

Value range:

None

Default value:

None

obs_head_epid

const char *

No

Explanation:

Enterprise project ID for the current bucket. Users who have enabled the enterprise project function can obtain the ID from the enterprise project service.

Restrictions:

The value is in UUID format. This parameter is not required if you have not enabled an enterprise project.

Value range:

None

Default value:

None

reserved_indicator

const char *

No

Explanation:

Special symbol that helps locate faults

Restrictions:

None

Value range:

None

Default value:

None

Table 15 obs_error_details

Parameter

Type

Description

message

const char*

Explanation:

Error details in the XML error response body

Restrictions:

None

Value range:

See Error Codes.

Default value:

None

resource

const char*

Explanation:

Bucket resources related to the error

Restrictions:

None

Value range:

None

Default value:

None

further_details

const char*

Explanation:

Value of the FurtherDetails element in the XML error response body

Restrictions:

None

Value range:

None

Default value:

None

extra_details_count

int

Explanation:

Number of other elements in the XML error response body

Restrictions:

None

Value range:

None

Default value:

None

extra_details

obs_name_value*

Explanation:

Values of other elements in the XML error response body

Restrictions:

None

error_headers_count

int

Explanation:

Number of headers in error_headers

Restrictions:

None

Value range:

None

Default value:

None

error_headers

char**

Explanation:

All response headers that contain the error

Restrictions:

None

Value range:

None

Default value:

None

Table 16 obs_name_value

Parameter

Type

Mandatory (Yes/No)

Description

name

char *

No

Explanation:

Key of a property.

Restrictions:

None

Value range:

None

Default value:

None

value

char *

No

Explanation:

Property value.

Restrictions:

None

Value range:

None

Default value:

None

Table 17 obs_status

Constant

Original Value

Description

OBS_STATUS_OK

0

The request is successful.

OBS_STATUS_InitCurlFailed

1

Failed to initialize curl.

OBS_STATUS_InternalError

2

Internal error.

OBS_STATUS_OutOfMemory

3

The local memory is insufficient.

OBS_STATUS_FailedToIInitializeRequest

6

Failed to initialize the request.

OBS_STATUS_XmlParseFailure

23

Failed to parse the XML file.

OBS_STATUS_NameLookupError

33

Domain name resolution failed.

OBS_STATUS_FailedToConnect

34

Failed to connect to the server.

OBS_STATUS_ConnectionFailed

36

Network connection failed.

OBS_STATUS_PartialFile

38

Network transmission interrupted.

OBS_STATUS_InvalidParameter

39

Invalid parameter.

OBS_STATUS_NoToken

40

The current number of concurrent tasks exceeds the upper limit (1,000 by default). The token here refers to the concurrent request token, not the security authentication token. You can use the set_online_request_max_count function to adjust the maximum number of concurrent tasks.

OBS_STATUS_OpenFileFailed

41

Failed to open the file.

OBS_STATUS_AccessDenied

43

The request is rejected.

OBS_STATUS_MalformedPolicy

44

The format of the request policy is incorrect.

OBS_STATUS_MalformedXML

45

The XML request format is incorrect.

OBS_STATUS_MethodNotAllowed

46

The request method is not allowed.

OBS_STATUS_SignatureDoesNotMatch

47

The signatures do not match. Check whether the AK, SK, and token are correct.

OBS_STATUS_ServiceUnavailable

48

Server exception.

OBS_STATUS_SlowDown

49

The request frequency is too high.

Sample Code

This example deletes the custom domain name of a bucket.
#include "eSDKOBS.h"
#include <stdio.h>
#include <stdlib.h>
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data);
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data);
int main()
{
    // The following code shows how to delete the custom domain name of a bucket.
    // Call the obs_initialize method at the program entry to initialize global resources such as the network and memory.
    obs_status ret_status = obs_initialize(OBS_INIT_ALL);
    if (OBS_STATUS_OK != ret_status)
    {
        printf("obs_initialize failed(%s).\n", obs_get_status_name(ret_status));
        return -1;
    }
    obs_options options;
    // Create and initialize options, including the access domain name (host_name), access keys (access_key_id and access_key_secret), bucket name (bucket_name), and bucket storage class (storage_class).
    init_obs_options(&options);
    options.bucket_options.host_name = "obs.cn-north-4.myhuaweicloud.com";
    options.bucket_options.access_key = getenv("ACCESS_KEY_ID");
    options.bucket_options.secret_access_key = getenv("SECRET_ACCESS_KEY");
    // Specify the bucket name, for example, example-bucket-name.
    char * bucket_name = "example-bucket-name";
    char * custom_domain_name = "test.custom.domain.name.com";
    options.bucket_options.bucket_name = bucket_name;
    // Set the response callback function.
    obs_response_handler response_handler = {
        &response_properties_callback,
        &response_complete_callback
    };
    obs_custom_domain custom_domain = { 0 };
    custom_domain.bucket_name = bucket_name;
    custom_domain.domain_name = custom_domain_name;
    ret_status = OBS_STATUS_BUTT;
    delete_bucket_custom_domain(&options, &custom_domain, &response_handler, &ret_status);
    // Check whether the request is successful.
    if (ret_status == OBS_STATUS_OK) {
        printf("Delete bucket custom domain successfully.");
    }
    else
    {
        printf("Delete bucket custom domain failed(%s).\n",
            obs_get_status_name(ret_status));
    }
    // Release the allocated global resources.
    obs_deinitialize();
}
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data)
{
    if (properties == NULL)
    {
        printf("error! obs_response_properties is null!");
        return OBS_STATUS_OK;      
    }
    // Print the response.
#define print_nonnull(name, field)                                 \
    do {                                                           \
        if (properties-> field) {                                  \
            printf("%s: %s\n", name, properties->field);          \
        }                                                          \
    } while (0)
    print_nonnull("request_id", request_id);
    print_nonnull("request_id2", request_id2);
    print_nonnull("content_type", content_type);
    if (properties->content_length) {
        printf("content_length: %llu\n", properties->content_length);
    }
    print_nonnull("server", server);
    print_nonnull("ETag", etag);
    print_nonnull("expiration", expiration);
    print_nonnull("website_redirect_location", website_redirect_location);
    print_nonnull("version_id", version_id);
    print_nonnull("allow_origin", allow_origin);
    print_nonnull("allow_headers", allow_headers);
    print_nonnull("max_age", max_age);
    print_nonnull("allow_methods", allow_methods);
    print_nonnull("expose_headers", expose_headers);
    print_nonnull("storage_class", storage_class);
    print_nonnull("server_side_encryption", server_side_encryption);
    print_nonnull("kms_key_id", kms_key_id);
    print_nonnull("customer_algorithm", customer_algorithm);
    print_nonnull("customer_key_md5", customer_key_md5);
    print_nonnull("bucket_location", bucket_location);
    print_nonnull("obs_version", obs_version);
    print_nonnull("restore", restore);
    print_nonnull("obs_object_type", obs_object_type);
    print_nonnull("obs_next_append_position", obs_next_append_position);
    print_nonnull("obs_head_epid", obs_head_epid);
    print_nonnull("reserved_indicator", reserved_indicator);
    int i;
    for (i = 0; i < properties->meta_data_count; i++) {
        printf("x-obs-meta-%s: %s\n", properties->meta_data[i].name,
            properties->meta_data[i].value);
    }
    return OBS_STATUS_OK;
}
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data)
{
    if (callback_data) {
        obs_status *ret_status = (obs_status *)callback_data;
        *ret_status = status;
    }
    else {
        printf("Callback_data is NULL");
    }
    if (error && error->message) {
        printf("Error Message: \n   %s\n", error->message);
    }
    if (error && error->resource) {
        printf("Error Resource: \n  %s\n", error->resource);
    }
    if (error && error->further_details) {
        printf("Error further_details: \n   %s\n", error->further_details);
    }
    if (error && error->extra_details_count) {
        int i;
        for (i = 0; i < error->extra_details_count; i++) {
            printf("Error Extra Detail(%d):\n   %s:%s\n", i, error->extra_details[i].name,
                error->extra_details[i].value);
        }
    }
    if (error && error->error_headers_count) {
        int i;
        for (i = 0; i < error->error_headers_count; i++) {
            const char *errorHeader = error->error_headers[i];
            printf("Error Headers(%d):\n    %s\n", i, errorHeader == NULL ? "NULL Header" : errorHeader);
        }
    }
}