Upload objects

Last Updated: Sep 28, 2017

In OSS, objects are the basic data units for user operation. The maximum size of a single object may vary with different data upload modes. The size of an object cannot exceed 5 GB in the Put Object mode or 48.8 TB in the multipart upload mode.

OSS C SDK provides rich interfaces for object upload. You can uploadan object from OSS through any of the following methods:

  • Simple upload
  • Append upload
  • Resumable upload
  • Multipart upload

Simple upload

Upload data from memory to OSS

You can upload data from memory to OSS using the oss_put_object_from_buffer interface:

  1. void put_object_from_buffer()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_table_t *headers = NULL;
  7. aos_table_t *resp_headers = NULL;
  8. oss_request_options_t *options = NULL;
  9. aos_list_t buffer;
  10. aos_buf_t *content = NULL;
  11. char *str = "test oss c sdk";
  12. aos_status_t *s = NULL;
  13. aos_pool_create(&p, NULL);
  14. /* Create and initialize options */
  15. options = oss_request_options_create(p);
  16. init_options(options);
  17. aos_str_set(&bucket, "<Name of your bucket>");
  18. aos_str_set(&object, "<Name of your object>");
  19. /* Initialize parameters */
  20. aos_list_init(&buffer);
  21. content = aos_buf_pack(options->pool, str, strlen(str));
  22. aos_list_add_tail(&content->node, &buffer);
  23. /* Upload the object */
  24. s = oss_put_object_from_buffer(options, &bucket, &object,
  25. &buffer, headers, &resp_headers);
  26. /* Determine whether the upload was successful */
  27. if (aos_status_is_ok(s)) {
  28. printf("put object from buffer succeeded\n");
  29. } else {
  30. printf("put object from buffer failed\n");
  31. }
  32. /* Release the resources*/
  33. aos_pool_destroy(p);
  34. }

Note: Complete code can be found at GitHub.

Upload a local file to OSS

You can upload a local file to OSS using the oss_put_object_from_file interface with the filepath parameter specified:

  1. void put_object_from_file()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_table_t *headers = NULL;
  7. aos_table_t *resp_headers = NULL;
  8. oss_request_options_t *options = NULL;
  9. char *filename = __FILE__;
  10. aos_status_t *s = NULL;
  11. aos_string_t file;
  12. aos_pool_create(&p, NULL);
  13. /* Create and initialize options */
  14. options = oss_request_options_create(p);
  15. init_options(options);
  16. /* Initialize parameters */
  17. headers = aos_table_make(options->pool, 1);
  18. apr_table_set(headers, OSS_CONTENT_TYPE, "image/jpeg");
  19. aos_str_set(&bucket, "<Name of your bucket>");
  20. aos_str_set(&object, "<Name of your object>");
  21. aos_str_set(&file, filename);
  22. /* Upload the object */
  23. s = oss_put_object_from_file(options, &bucket, &object, &file,
  24. headers, &resp_headers);
  25. /* Determine whether the upload was successful */
  26. if (aos_status_is_ok(s)) {
  27. printf("put object from file succeeded\n");
  28. } else {
  29. printf("put object from file failed\n");
  30. }
  31. /* Release the resources*/
  32. aos_pool_destroy(p);
  33. }

Note:

  • When uploading objects in this manner, the largest object cannot exceed 5 GB. You can use multipart upload to upload an object exceeding 5 GB.
  • Complete code can be found at GitHub.

Append upload

OSS supports appendable upload of objects. When calling this method, specify the append position of the object. If the object is newly created, the append position is 0. If the object already exists, the append position must be set to the object length before the append.

  • If the object does not exist, an appendable object will be created when Append Object is called.
  • If the object exists, new content will be added to the end of the object when Append Object is called.

Append Object uploads objects with the Append Write method. The type of the objects created with the Append Object operation is Appendable Object, and the type of the objects uploaded with the Put Object operation is Normal Object.

Append data from memory to OSS

You can append data from memory to OSS using the oss_append_object_from_buffer interface:

  1. void append_object_from_buffer()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. char *str = "test oss c sdk";
  7. aos_status_t *s = NULL;
  8. int64_t position = 0;
  9. aos_table_t *headers1 = NULL;
  10. aos_table_t *headers2 = NULL;
  11. aos_table_t *resp_headers = NULL;
  12. oss_request_options_t *options = NULL;
  13. aos_list_t buffer;
  14. aos_buf_t *content = NULL;
  15. char *next_append_position = NULL;
  16. aos_pool_create(&p, NULL);
  17. /* Create and initialize options */
  18. options = oss_request_options_create(p);
  19. init_options(options);
  20. /* Initialize parameters */
  21. headers1 = aos_table_make(p, 0);
  22. aos_str_set(&bucket, "<Name of your bucket>");
  23. aos_str_set(&object, "<Name of your object>");
  24. /* Get the starting position of the append */
  25. s = oss_head_object(options, &bucket, &object, headers1, &resp_headers);
  26. if (aos_status_is_ok(s)) {
  27. next_append_position = (char*)(apr_table_get(resp_headers,
  28. "x-oss-next-append-position"));
  29. position = atoi(next_append_position);
  30. }
  31. /* Append the object */
  32. headers2 = aos_table_make(p, 0);
  33. aos_list_init(&buffer);
  34. content = aos_buf_pack(p, str, strlen(str));
  35. aos_list_add_tail(&content->node, &buffer);
  36. s = oss_append_object_from_buffer(options, &bucket, &object,
  37. position, &buffer, headers2, &resp_headers);
  38. /* Determine whether the append is successful */
  39. if (aos_status_is_ok(s))
  40. {
  41. printf("append object from buffer succeeded\n");
  42. } else {
  43. printf("append object from buffer failed\n");
  44. }
  45. /* Release the resources*/
  46. aos_pool_destroy(p);
  47. }

Note: Complete code can be found at GitHub.

Append data from a local file to OSS

You can append data from a local file to OSS using the oss_append_object_from_file interface:

  1. void append_object_from_file()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_table_t *headers1 = NULL;
  7. aos_table_t *headers2 = NULL;
  8. aos_table_t *resp_headers = NULL;
  9. oss_request_options_t *options = NULL;
  10. char *filename = __FILE__;
  11. aos_status_t *s = NULL;
  12. aos_string_t file;
  13. int64_t position = 0;
  14. char *next_append_position = NULL;
  15. aos_pool_create(&p, NULL);
  16. /* Create and initialize options */
  17. options = oss_request_options_create(p);
  18. init_options(options);
  19. /* Initialize parameters */
  20. headers1 = aos_table_make(options->pool, 0);
  21. headers2 = aos_table_make(options->pool, 0);
  22. aos_str_set(&bucket, "<Name of your bucket>");
  23. aos_str_set(&object, "<Name of your object>");
  24. aos_str_set(&file, filename);
  25. /* Get the starting position of the append */
  26. s = oss_head_object(options, &bucket, &object, headers1, &resp_headers);
  27. if(aos_status_is_ok(s)) {
  28. next_append_position = (char*)(apr_table_get(resp_headers,
  29. "x-oss-next-append-position"));
  30. position = atoi(next_append_position);
  31. }
  32. /* Append the object */
  33. s = oss_append_object_from_file(options, &bucket, &object,
  34. position, &file, headers2, &resp_headers);
  35. /* Determine whether the append is successful */
  36. if (aos_status_is_ok(s)) {
  37. printf("append object from file succeeded\n");
  38. } else {
  39. printf("append object from file failed\n");
  40. }
  41. /* Release the resources*/
  42. aos_pool_destroy(p);
  43. }

Note:

  • Append Object is not applicable to a non-appendable object. For example, if a normal object with the same name already exists and the Append Object operation is still performed, the system will return the 409 message and the error code ObjectNotAppendable.
  • If you perform the Put Object operation on an existing appendable object, this appendable object will be overwritten by the new object, and the type of this object will be changed to Normal Object.
  • After the Head Object operation is performed, the system will return x-oss-object-type, which indicates the type of the object. If the object is an appendable object, the value of x-oss-object-type is Appendable. For an appendable object, after the Head Object operation is performed, the system will also return x-oss-next-append-position and x-oss-hash-crc64ecma.
  • You cannot use Copy Object to copy an appendable object or change the encryption attribute of this object on the server. You can use Copy Object to modify the custom metadata.
  • Complete code can be found at GitHub.

Resumable upload

When the network is unstable or other exceptions occur as a large object is being uploaded, the whole upload operation will fail. You have to re-upload the objects, wasting resources. When the network is unstable, you may need to try multiple times. Resumable upload supports concurrent uploads and resuming uploading from interruptions. Resumable upload controls uploading resumption behavior through oss_resumable_clt_params_t. It has the following parameters:

  • part_size: The size of each part to be uploaded. The size ranges from 100 KB to 5 GB. Unit: Byte.
  • thread_num: The number of concurrent threads. The default value is 1.
  • enable_checkpoint: Whether to enable resumable uploads. This option is disabled by default.
  • checkpoint_path: The path of the checkpoint object. It is by default stored under the upload object directory {upload_file_path}.cp.

The principle of resumable upload is to divide the object to be uploaded into multiple parts and upload them separately. When all the parts are uploaded, the upload of the entire object will be completed. The progress of the current upload will be recorded during the uploading process (in the checkpoint object). If the upload of any part fails during the process, the next upload attempt will start from the recorded position in the checkpoint object. This requires that the same checkpoint object with the previous upload be used in the next call. When the upload is complete, the checkpoint object will be deleted.

  1. void resumable_upload()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_string_t filename;
  7. aos_status_t *s = NULL;
  8. int is_cname = 0;
  9. aos_table_t *headers = NULL;
  10. aos_table_t *resp_headers = NULL;
  11. aos_list_t resp_body;
  12. oss_request_options_t *options = NULL;
  13. oss_resumable_clt_params_t *clt_params;
  14. aos_pool_create(&p, NULL);
  15. options = oss_request_options_create(p);
  16. init_sample_request_options(options, is_cname);
  17. headers = aos_table_make(p, 0);
  18. aos_str_set(&bucket, BUCKET_NAME);
  19. aos_str_set(&object, "my_key.zip");
  20. aos_str_set(&filename, "local_big_file.zip");
  21. aos_list_init(&resp_body);
  22. // Resumable upload
  23. clt_params = oss_create_resumable_clt_params_content(p, 1024 * 100, 3, AOS_TRUE, NULL);
  24. s = oss_resumable_upload_file(options, &bucket, &object, &filename, headers, NULL,
  25. clt_params, NULL, &resp_headers, &resp_body);
  26. if (aos_status_is_ok(s)) {
  27. printf("upload succeeded\n");
  28. } else {
  29. printf("upload failed\n");
  30. }
  31. aos_pool_destroy(p);
  32. }

Note:

  • Resumable upload supports metainformation setting, upload callback and the progress bar feature.
  • Complete code can be found at GitHub.

Multipart upload

In addition to the simple upload mode, OSS also provides the multipart upload mode. You can apply the multipart upload mode in the following scenarios (but not limited to the following):

  • Resumable upload is required.
  • Upload an object larger than 100 MB.
  • Connection to the OSS server is frequently interrupted due to poor network conditions.
  • Stream uploading of objects is required. The size of the object to be uploaded is unknown.

Multipart upload using easy-to-use interfaces

The following code uploads files in the multipart upload mode through the encapsulated easy-to-use oss_upload_file interface.

  1. void test_upload_file()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. oss_request_options_t *options = NULL;
  7. aos_status_t *s = NULL;
  8. int part_size = 100 * 1024;
  9. aos_string_t upload_id;
  10. aos_string_t filepath;
  11. aos_pool_create(&p, NULL);
  12. /* Create and initialize options */
  13. options = oss_request_options_create(p);
  14. init_options(options);
  15. aos_str_set(&bucket, "<Name of your bucket>");
  16. aos_str_set(&object, "<Name of your object>");
  17. aos_str_null(&upload_id);
  18. aos_str_set(&filepath, __FILE__);
  19. /* Upload in multiple parts */
  20. s = oss_upload_file(options, &bucket, &object, &upload_id, &filepath,
  21. part_size, NULL);
  22. /* Determine whether the upload was successful */
  23. if (aos_status_is_ok(s)) {
  24. printf("upload file succeeded\n");
  25. } else {
  26. printf("upload file failed\n");
  27. }
  28. /* Release the resources*/
  29. aos_pool_destroy(p);
  30. }

Note:

  • When using the oss_upload_file interface for multipart upload of objects, set the upload_id to Null through aos_str_null(&upload_id) for a new multipart upload task. To resume an upload task based on an existing upload_id, set the upload_id to the specified upload_id_str through aos_str_set(&upload_id, upload_id_str).
  • When performing multipart upload using the oss_upload_file interface, specify the size of each part. The size of each part must be larger than 100 KB. The number of parts must be within the range of 1 to 10,000. When the number of parts exceeds the range during object splitting, the oss_upload_file interface will automatically adjust the size of each part.
  • When the oss_upload_file interface is used for multipart upload, if the specified upload_id already exists, the size of each part to be uploaded must be the same with that in the specified upload_id.
  • Complete code can be found at GitHub.

Multipart upload steps

The step-by-step multipart upload mode is flexible. The general process is as follows:

  1. Initialize a multipart upload task (oss_init_multipart_upload)
  2. Upload the parts individually or concurrently (oss_upload_part_from_file)
  3. Complete the upload (oss_complete_multipart_upload)

Initialization

Initialize a multipart upload task:

  1. void init_multipart_upload()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_table_t *headers = NULL;
  7. aos_table_t *resp_headers = NULL;
  8. oss_request_options_t *options = NULL;
  9. aos_string_t upload_id;
  10. oss_upload_file_t *upload_file = NULL;
  11. aos_status_t *s = NULL;
  12. oss_list_upload_part_params_t *params = NULL;
  13. aos_list_t complete_part_list;
  14. oss_list_part_content_t *part_content = NULL;
  15. aos_pool_create(&p, NULL);
  16. /* Create and initialize options */
  17. options = oss_request_options_create(p);
  18. init_options(options);
  19. /* Initialize parameters */
  20. headers = aos_table_make(p, 1);
  21. aos_str_set(&bucket, "<Name of your bucket>");
  22. aos_str_set(&object, "<Name of your object>");
  23. /* Initialize the multipart upload to get an upload ID */
  24. s = oss_init_multipart_upload(options, &bucket, &object,
  25. &upload_id, headers, &resp_headers);
  26. /* Determine whether the initialization of the multipart upload is successful */
  27. if (aos_status_is_ok(s)) {
  28. printf("Init multipart upload succeeded, upload_id:%.*s\n",
  29. upload_id.len, upload_id.data);
  30. } else {
  31. printf("Init multipart upload failed, upload_id:%.*s\n",
  32. upload_id.len, upload_id.data);
  33. }
  34. /* Upload each part. The code can be found in the next section. Skipped. */
  35. /* Complete the multipart upload. The code can be found in a later section. Skipped.*/
  36. /* Release the resources*/
  37. aos_pool_destroy(p);
  38. }

Note:

  • The returned result contains the upload_id which is the unique identifier of a multipart upload event. We will use this upload_id in subsequent operations.
  • The preceding code only demonstrates how to initialize parts for uploading. The code is not complete. Complete code can be found at GitHub.
  • The order of parameters in Version 1.0.0 is: …headers, upload_id…. The order of parameters in Version 2.0.0 is: …upload_id, headers….

Multipart upload of a local file

Next, we will perform multipart upload of a local file.

  1. void multipart_upload_file()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. int is_cname = 0;
  7. aos_table_t *headers = NULL;
  8. aos_table_t *complete_headers = NULL;
  9. aos_table_t *resp_headers = NULL;
  10. oss_request_options_t *options = NULL;
  11. aos_string_t upload_id;
  12. oss_upload_file_t *upload_file = NULL;
  13. aos_status_t *s = NULL;
  14. oss_list_upload_part_params_t *params = NULL;
  15. aos_list_t complete_part_list;
  16. oss_list_part_content_t *part_content = NULL;
  17. oss_complete_part_content_t *complete_part_content = NULL;
  18. int part_num1 = 1;
  19. int part_num2 = 2;
  20. aos_pool_create(&p, NULL);
  21. /* Create and initialize options */
  22. options = oss_request_options_create(p);
  23. init_options(options);
  24. /* Initialize parameters */
  25. headers = aos_table_make(p, 1);
  26. resp_headers = aos_table_make(options->pool, 5);
  27. aos_str_set(&bucket, "<Name of your bucket>");
  28. aos_str_set(&object, "<Name of your object>");
  29. /* Initialize parts for upload to get the upload ID. The code can be found in the previous section. Skipped.*/
  30. /* Upload the first part */
  31. upload_file = oss_create_upload_file(p);
  32. aos_str_set(&upload_file->filename, MULTIPART_UPLOAD_FILE_PATH);
  33. upload_file->file_pos = 0;
  34. upload_file->file_last = 200 * 1024; //200k
  35. s = oss_upload_part_from_file(options, &bucket, &object, &upload_id,
  36. part_num1, upload_file, &resp_headers);
  37. /* Determine whether the part upload is successful */
  38. if (aos_status_is_ok(s)) {
  39. printf("Multipart upload from file succeeded\n");
  40. } else {
  41. printf("Multipart upload from file failed\n");
  42. }
  43. /* Upload the second part */
  44. upload_file->file_pos = 200 *1024;//remain content start pos
  45. upload_file->file_last = get_file_size(MULTIPART_UPLOAD_FILE_PATH);
  46. s = oss_upload_part_from_file(options, &bucket, &object, &upload_id,
  47. part_num2, upload_file, &resp_headers);
  48. /* Determine whether the part upload is successful */
  49. if (aos_status_is_ok(s)) {
  50. printf("Multipart upload from file succeeded\n");
  51. } else {
  52. printf("Multipart upload from file failed\n");
  53. }
  54. /* Complete the multipart upload. The code can be found in the next section. Skipped.*/
  55. /* Release the resources*/
  56. aos_pool_destroy(p);
  57. }

The main idea of the preceding code is to call the oss_upload_part_from_file interface to upload each part.

Note:

  • The oss_upload_part_from_file interface requires that all parts except the last one must be larger than 100 KB.
  • The part number ranges from 1 to 10,000. If the part number exceeds this range, the OSS will return the InvalidArgument error code.
  • When each part is uploaded, the stream is directed to the start point of the part.
  • The preceding code only demonstrates how to initialize parts for uploading. The code is not complete. Complete code can be found at GitHub.

Get uploaded parts to complete the multipart upload

  1. void complete_multipart_upload()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_table_t *complete_headers = NULL;
  7. aos_table_t *resp_headers = NULL;
  8. oss_request_options_t *options = NULL;
  9. aos_string_t upload_id;
  10. aos_status_t *s = NULL;
  11. oss_list_upload_part_params_t *params = NULL;
  12. aos_list_t complete_part_list;
  13. oss_list_part_content_t *part_content = NULL;
  14. oss_complete_part_content_t *complete_part_content = NULL;
  15. aos_pool_create(&p, NULL);
  16. /* Create and initialize options */
  17. options = oss_request_options_create(p);
  18. init_options(options);
  19. /* Initialize parameters */
  20. headers = aos_table_make(p, 1);
  21. resp_headers = aos_table_make(options->pool, 5);
  22. aos_str_set(&bucket, "<Name of your bucket>");
  23. aos_str_set(&object, "<Name of your object>");
  24. /* Initialize parts for upload to get the upload ID. The code can be found in the previous section. Skipped.*/
  25. /* Upload each part. The code can be found in the previous section. Skipped. */
  26. /* Get uploaded parts
  27. * The call of the "oss_complete_multipart_upload" interface requires the ETag value of each part. You can get this value via two approaches:
  28. * First, the returned result of each part upload will contain the ETag of the specific part. You can save the values for future use;
  29. * Second, you can call the "oss_list_upload_part" interface to get the ETag values of uploaded parts.
  30. * The second approach is demonstrated as follows.
  31. */
  32. params = oss_create_list_upload_part_params(p);
  33. params->max_ret = 1000;
  34. aos_list_init(&complete_part_list);
  35. s = oss_list_upload_part(options, &bucket, &object, &upload_id,
  36. params, &resp_headers);
  37. /* Determine whether the part list has been obtained successfully */
  38. if (aos_status_is_ok(s)) {
  39. printf("List multipart succeeded\n");
  40. } else {
  41. printf("List multipart failed\n");
  42. }
  43. aos_list_for_each_entry(part_content, &params->part_list, node) {
  44. complete_part_content = oss_create_complete_part_content(p);
  45. aos_str_set(&complete_part_content->part_number,
  46. part_content->part_number.data);
  47. aos_str_set(&complete_part_content->etag, part_content->etag.data);
  48. aos_list_add_tail(&complete_part_content->node, &complete_part_list);
  49. }
  50. /* Complete multipart uploading */
  51. s = oss_complete_multipart_upload(options, &bucket, &object, &upload_id,
  52. &complete_part_list, complete_headers, &resp_headers);
  53. /* Determine whether the multipart upload is successful */
  54. if (aos_status_is_ok(s)) {
  55. printf("Complete multipart upload from file succeeded, upload_id:%.*s\n",
  56. upload_id.len, upload_id.data);
  57. } else {
  58. printf("Complete multipart upload from file failed\n");
  59. }
  60. /* Release the resources */
  61. aos_pool_destroy(p);
  62. }

Note:

  • Compared with Version 1.0.0, Version 2.0.0 adds the headers parameter for the oss_complete_multipart_upload interface to modify the headers value when the upload is completed.
  • Complete code can be found at GitHub.

Cancel a multipart upload task

  1. void abort_multipart_upload()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_table_t *headers = NULL;
  7. aos_table_t *resp_headers = NULL;
  8. oss_request_options_t *options = NULL;
  9. aos_string_t upload_id;
  10. aos_status_t *s = NULL;
  11. aos_pool_create(&p, NULL);
  12. /* Create and initialize options */
  13. options = oss_request_options_create(p);
  14. init_options(options);
  15. /* Initialize parameters */
  16. headers = aos_table_make(p, 1);
  17. aos_str_set(&bucket, "<Name of your bucket>");
  18. aos_str_set(&object, "<Name of your object>");
  19. /* Initialize the multipart upload to get an upload ID */
  20. s = oss_init_multipart_upload(options, &bucket, &object,
  21. &upload_id, headers, &resp_headers);
  22. if (aos_status_is_ok(s)) {
  23. printf("Init multipart upload succeeded, upload_id:%.*s\n",
  24. upload_id.len, upload_id.data);
  25. } else {
  26. printf("Init multipart upload failed\n");
  27. }
  28. /* Cancel the multipart upload */
  29. s = oss_abort_multipart_upload(options, &bucket, &object, &upload_id,
  30. &resp_headers);
  31. /* Determine whether the multipart upload is canceled */
  32. if (aos_status_is_ok(s)) {
  33. printf("Abort multipart upload succeeded, upload_id::%.*s\n",
  34. upload_id.len, upload_id.data);
  35. } else {
  36. printf("Abort multipart upload failed\n");
  37. }
  38. /* Release the resources */
  39. aos_pool_destroy(p);
  40. }

Note:

  • When a multipart upload task is aborted, you cannot use the upload_id to perform any operations and the uploaded parts will be deleted.
  • Complete code can be found at GitHub.

Set the metainformation

Object Meta describes the attributes of objects uploaded to the OSS. These attributes come in two types: HTTP standard attributes (HTTP Headers) and user-defined metainformation (User Meta). The object matadata can be set at the upload (stream upload, object upload, append upload, multipart upload and resumable upload) or copy. The names of metainformation are case-insensitive. For more information on object metadata, see Object Meta.

HTTP standard attributes

Descriptions of common HTTP standard attributes can be found as follows. For more information, see RFC2616.

Name Description Default value
Content-MD5 Object data verification. After this value is set, the OSS will enable the MD5 verification on the object content and compare the MD5 you provide with the MD5 of the object. An error will be returned if any inconsistency is found. None
Content-Type The object MIME. It defines the object type and webpage encoding and decides the form and encoding used by the browser to read objects. If not specified, the object MIME will be generated based on the key or object name extension. If no extension is available, the default value applies. Application/octet-stream
Content-Disposition It instructs the MIME user proxy how to display, open, or download the attached object and the object name. None
Content-Length The length of the uploaded data. Data in excess of the length will be truncated. If the data falls short of the length, the actual data length will apply. The actual length of data
Expires The expiration time of cache. It is not used in the OSS. The time format is in GMT. None
Cache-Control It specifies the cache action of the webpage when the object is downloaded. None
Expect The specific action expected by the HTTP client. 100-continue is supported currently. Related with the libcurl implementation
Transfer-Encoding The encoding format for data transmission. chunked is supported currently. Related with the libcurl implementation
  1. void put_object_from_file()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_table_t *headers = NULL;
  7. aos_table_t *resp_headers = NULL;
  8. oss_request_options_t *options = NULL;
  9. char *filename = __FILE__;
  10. aos_status_t *s = NULL;
  11. aos_string_t file;
  12. aos_pool_create(&p, NULL);
  13. /* Create and initialize options */
  14. options = oss_request_options_create(p);
  15. init_options(options);
  16. /* Initialize parameters */
  17. headers = aos_table_make(options->pool, 2);
  18. apr_table_set(headers, OSS_CONTENT_TYPE, "image/jpeg");
  19. apr_table_set(headers, OSS_CONTENT_MD5, "eB5eJF1ptWaXm4bijSPyxw==");
  20. aos_str_set(&bucket, "<Name of your bucket>");
  21. aos_str_set(&object, "<Name of your object>");
  22. aos_str_set(&file, filename);
  23. /* Upload the object */
  24. s = oss_put_object_from_file(options, &bucket, &object, &file,
  25. headers, &resp_headers);
  26. /* Determine whether the upload was successful */
  27. if (aos_status_is_ok(s)) {
  28. printf("put object from file succeeded\n");
  29. } else {
  30. printf("put object from file failed\n");
  31. }
  32. /* Release the resources*/
  33. aos_pool_destroy(p);
  34. }

Note:

  • For calculation methods of data and object MD5 values, see Put Object.
  • The HTTP standard attributes will change the data transmission actions. Set the attributes after you are clearly aware of their actions.

User Meta

To facilitate more descriptions on objects, the OSS stipulates that all parameters with the prefix of x-oss-meta- are regarded as User Meta. One object can have multiple similar parameters. User Meta will be returned in the HTTP header during GetObject or HeadObject operations.

  1. void put_object_from_file()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. aos_table_t *headers = NULL;
  7. aos_table_t *resp_headers = NULL;
  8. oss_request_options_t *options = NULL;
  9. char *filename = __FILE__;
  10. aos_status_t *s = NULL;
  11. aos_string_t file;
  12. aos_pool_create(&p, NULL);
  13. /* Create and initialize options */
  14. options = oss_request_options_create(p);
  15. init_options(options);
  16. /* Initialize parameters */
  17. headers = aos_table_make(options->pool, 4);
  18. apr_table_set(headers, OSS_CONTENT_TYPE, "image/jpeg");
  19. apr_table_set(headers, OSS_CONTENT_MD5, "eB5eJF1ptWaXm4bijSPyxw==");
  20. apr_table_set(headers, "x-oss-meta-author", "mingdi");
  21. apr_table_set(headers, "x-oss-meta-category", "computer");
  22. aos_str_set(&bucket, "<Name of your bucket>");
  23. aos_str_set(&object, "<Name of your object>");
  24. aos_str_set(&file, filename);
  25. /* Upload the object */
  26. s = oss_put_object_from_file(options, &bucket, &object, &file,
  27. headers, &resp_headers);
  28. /* Determine whether the upload was successful */
  29. if (aos_status_is_ok(s)) {
  30. printf("put object from file succeeded\n");
  31. } else {
  32. printf("put object from file failed\n");
  33. }
  34. /* Release the resources*/
  35. aos_pool_destroy(p);
  36. }

Upload callback

When an upload is completed, the OSS can perform a callback to the application server. You only need to carry the relevant callback parameters in the request to the OSS to implement the callback. Interfaces that support callback include: PutObject, PostObject and ompleteMultipartUpload. For more details on upload callback, see Upload Callback. Next we will take the PutObject interface as an example to explain the upload callback usage.

  1. void put_object_from_buffer_with_callback()
  2. {
  3. aos_pool_t *p = NULL;
  4. char *str = "test oss c sdk";
  5. aos_status_t *s = NULL;
  6. int is_cname = 0;
  7. aos_string_t bucket;
  8. aos_string_t object;
  9. aos_table_t *headers = NULL;
  10. oss_request_options_t *options = NULL;
  11. aos_table_t *resp_headers = NULL;
  12. aos_list_t resp_body;
  13. aos_list_t buffer;
  14. aos_buf_t *content;
  15. char *buf = NULL;
  16. int64_t len = 0;
  17. int64_t size = 0;
  18. int64_t pos = 0;
  19. char b64_buf[1024];
  20. int b64_len;
  21. /* JSON format */
  22. char *callback = "{"
  23. "\"callbackUrl\":\"http://callback.oss-demo.com:23450\","
  24. "\"callbackHost\":\"oss-cn-hangzhou.aliyuncs.com\","
  25. "\"callbackBody\":\"bucket=${bucket}&object=${object}&size=${size}&mimeType=${mimeType}\","
  26. "\"callbackBodyType\":\"application/x-www-form-urlencoded\""
  27. "}";
  28. /* init sample */
  29. aos_pool_create(&p, NULL);
  30. options = oss_request_options_create(p);
  31. init_sample_request_options(options, is_cname);
  32. aos_str_set(&bucket, BUCKET_NAME);
  33. aos_str_set(&object, OBJECT_NAME);
  34. aos_list_init(&resp_body);
  35. aos_list_init(&buffer);
  36. content = aos_buf_pack(options->pool, str, strlen(str));
  37. aos_list_add_tail(&content->node, &buffer);
  38. /* put call into header */
  39. b64_len = aos_base64_encode((unsigned char*)callback, strlen(callback), b64_buf);
  40. b64_buf[b64_len] = '\0';
  41. headers = aos_table_make(p, 1);
  42. apr_table_set(headers, OSS_CALLBACK, b64_buf);
  43. /* test put object */
  44. s = oss_do_put_object_from_buffer(options, &bucket, &object, &buffer,
  45. headers, NULL, NULL, &resp_headers, &resp_body);
  46. if (aos_status_is_ok(s)) {
  47. printf("put object from buffer succeeded\n");
  48. } else {
  49. printf("put object from buffer failed\n");
  50. }
  51. /* get buffer len */
  52. len = aos_buf_list_len(&resp_body);
  53. buf = (char *)aos_pcalloc(p, (apr_size_t)(len + 1));
  54. buf[len] = '\0';
  55. /* copy buffer content to memory */
  56. aos_list_for_each_entry(aos_buf_t, content, &resp_body, node) {
  57. size = aos_buf_size(content);
  58. memcpy(buf + pos, content->pos, (size_t)size);
  59. pos += size;
  60. }
  61. aos_pool_destroy(p);
  62. }

Note:

Progress bar

The OSS C SDK supports the progress bar feature to indicate the uploading/downloading progress. The following code takes PutObject as an example to describe the usage of the progress bar feature.

  1. void percentage(int64_t consumed_bytes, int64_t total_bytes)
  2. {
  3. assert(total_bytes >= consumed_bytes);
  4. printf("%%%" APR_INT64_T_FMT "\n", consumed_bytes * 100 / total_bytes);
  5. }
  6. void put_and_get_from_file_with_progress()
  7. {
  8. aos_pool_t *p = NULL;
  9. aos_status_t *s = NULL;
  10. int is_cname = 0;
  11. aos_string_t bucket;
  12. aos_string_t object;
  13. aos_string_t filename;
  14. oss_request_options_t *options = NULL;
  15. aos_table_t *resp_headers = NULL;
  16. aos_list_t resp_body;
  17. char *download_filename = "get_object_to_local_file.txt";
  18. /* init test*/
  19. aos_pool_create(&p, NULL);
  20. options = oss_request_options_create(p);
  21. init_sample_request_options(options, is_cname);
  22. aos_str_set(&bucket, BUCKET_NAME);
  23. aos_str_set(&object, OBJECT_NAME);
  24. aos_str_set(&filename, __FILE__);
  25. aos_list_init(&resp_body);
  26. /* put object */
  27. s = oss_do_put_object_from_file(options, &bucket, &object, &filename, NULL, NULL, percentage, &resp_headers, &resp_body);
  28. if (aos_status_is_ok(s)) {
  29. printf("put object from file succeeded\n");
  30. } else {
  31. printf("put object from file failed\n");
  32. aos_pool_destroy(p);
  33. return;
  34. }
  35. aos_pool_destroy(p);
  36. }

Note: Interfaces that support the progress bar feature include: oss_do_put_object_from_buffer, oss_do_put_object_from_file, oss_do_append_object_from_buffer, oss_do_append_object_from_file, oss_do_upload_part_from_buffer, oss_do_upload_part_from_file, and oss_resumable_upload_file. The code can be found at GitHub.

Thank you! We've received your feedback.