You've already forked libmarias3
mirror of
https://github.com/mariadb-corporation/libmarias3.git
synced 2026-10-23 14:29:02 +03:00
Add Content-Type support for object mime
This adds two new functions `ms3_set_content_type` and `ms3_get_content_type`.
This commit is contained in:
@@ -393,3 +393,28 @@ Example
|
||||
printf("File timestamp: %ld\n", status.created);
|
||||
ms3_deinit(ms3);
|
||||
|
||||
ms3_set_content_type()
|
||||
----------------------
|
||||
|
||||
.. c:function:: void ms3_set_content_type(ms3_st *ms3, const char *content_type)
|
||||
|
||||
Sets the ``Content-Type:`` header for subsequent PUT requests. Note that this
|
||||
is not copied, so it should remain in scope for each :c:func:`ms3_put()` call.
|
||||
Setting this to ``NULL`` will clear the ``Content-Type`` header to the default.
|
||||
|
||||
:param ms3: The marias3 object
|
||||
:param content_type: The mime type to set
|
||||
|
||||
ms3_get_content_type()
|
||||
----------------------
|
||||
|
||||
.. c:function:: const char *ms3_get_content_type(ms3_st *ms3)
|
||||
|
||||
Gets the ``Content-Type:`` header for the previous response from the S3 server.
|
||||
This will automatically freed as part of the request handling, it will lose
|
||||
scope on the next request and should not be freed by the application.
|
||||
|
||||
:param ms3: The marias3 object
|
||||
:param content_type: The mime type for the previous request
|
||||
|
||||
|
||||
|
||||
@@ -149,10 +149,16 @@ uint8_t ms3_list_dir(ms3_st *ms3, const char *bucket, const char *prefix,
|
||||
MS3_API
|
||||
void ms3_list_free(ms3_list_st *list);
|
||||
|
||||
MS3_API
|
||||
void ms3_set_content_type(ms3_st *ms3, const char *content_type);
|
||||
|
||||
MS3_API
|
||||
uint8_t ms3_put(ms3_st *ms3, const char *bucket, const char *key,
|
||||
const uint8_t *data, size_t length);
|
||||
|
||||
MS3_API
|
||||
const char *ms3_get_content_type(ms3_st *ms3);
|
||||
|
||||
MS3_API
|
||||
uint8_t ms3_get(ms3_st *ms3, const char *bucket, const char *key,
|
||||
uint8_t **data, size_t *length);
|
||||
|
||||
@@ -230,6 +230,9 @@ ms3_st *ms3_init(const char *s3key, const char *s3secret,
|
||||
ms3->sts_region = NULL;
|
||||
ms3->iam_role_arn = NULL;
|
||||
|
||||
ms3->content_type_in = NULL;
|
||||
ms3->content_type_out = NULL;
|
||||
|
||||
return ms3;
|
||||
}
|
||||
|
||||
@@ -738,3 +741,21 @@ uint8_t ms3_assume_role(ms3_st *ms3)
|
||||
return res;
|
||||
}
|
||||
|
||||
void ms3_set_content_type(ms3_st *ms3, const char *content_type)
|
||||
{
|
||||
if (!ms3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ms3->content_type_out = content_type;
|
||||
}
|
||||
|
||||
const char *ms3_get_content_type(ms3_st *ms3)
|
||||
{
|
||||
if (!ms3)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return ms3->content_type_in;
|
||||
}
|
||||
|
||||
@@ -717,7 +717,9 @@ uint8_t execute_request(ms3_st *ms3, command_t cmd, const char *bucket,
|
||||
void *ret_ptr)
|
||||
{
|
||||
CURL *curl = NULL;
|
||||
CURLHcode curl_hret;
|
||||
struct curl_slist *headers = NULL;
|
||||
struct curl_header *content_type_in;
|
||||
uint8_t res = 0;
|
||||
struct memory_buffer_st mem;
|
||||
uri_method_t method;
|
||||
@@ -822,7 +824,14 @@ uint8_t execute_request(ms3_st *ms3, command_t cmd, const char *bucket,
|
||||
return res;
|
||||
}
|
||||
|
||||
if (ms3->no_content_type)
|
||||
if ((method == MS3_PUT) && ms3->content_type_out)
|
||||
{
|
||||
// Mime type maxmum is 128 bytes
|
||||
char content_type[196];
|
||||
snprintf(content_type, 195, "Content-Type: %s", ms3->content_type_out);
|
||||
headers = curl_slist_append(headers, content_type);
|
||||
}
|
||||
else if (ms3->no_content_type)
|
||||
{
|
||||
headers = curl_slist_append(headers, "Content-Type:");
|
||||
}
|
||||
@@ -874,7 +883,12 @@ uint8_t execute_request(ms3_st *ms3, command_t cmd, const char *bucket,
|
||||
|
||||
return MS3_ERR_REQUEST_ERROR;
|
||||
}
|
||||
|
||||
curl_hret = curl_easy_header(curl, "content-type", 0, CURLH_HEADER, -1,
|
||||
&content_type_in);
|
||||
if (!curl_hret && content_type_in)
|
||||
{
|
||||
ms3->content_type_in = content_type_in->value;
|
||||
}
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
ms3debug("Response code: %ld", response_code);
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ struct ms3_st
|
||||
char *query_buffer;
|
||||
void *read_cb;
|
||||
void *user_data;
|
||||
const char *content_type_out;
|
||||
const char *content_type_in;
|
||||
struct ms3_list_container_st list_container;
|
||||
};
|
||||
|
||||
|
||||
148
tests/content_type.c
Normal file
148
tests/content_type.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
||||
* Copyright 2019 MariaDB Corporation Ab. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <yatl/lite.h>
|
||||
#include <libmarias3/marias3.h>
|
||||
|
||||
/* Tests basic put, list, get, status, delete using the thread calls */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int res;
|
||||
ms3_list_st *list = NULL, *list_it = NULL;
|
||||
uint8_t *data;
|
||||
size_t length;
|
||||
int i;
|
||||
bool found;
|
||||
const char *test_string = "Another one bites the dust";
|
||||
ms3_status_st status;
|
||||
ms3_st *ms3;
|
||||
const char *content_type_in;
|
||||
char *s3key = getenv("S3KEY");
|
||||
char *s3secret = getenv("S3SECRET");
|
||||
char *s3region = getenv("S3REGION");
|
||||
char *s3bucket = getenv("S3BUCKET");
|
||||
char *s3host = getenv("S3HOST");
|
||||
char *s3noverify = getenv("S3NOVERIFY");
|
||||
char *s3usehttp = getenv("S3USEHTTP");
|
||||
char *s3port = getenv("S3PORT");
|
||||
|
||||
SKIP_IF_(!s3key, "Environemnt variable S3KEY missing");
|
||||
SKIP_IF_(!s3secret, "Environemnt variable S3SECRET missing");
|
||||
SKIP_IF_(!s3region, "Environemnt variable S3REGION missing");
|
||||
SKIP_IF_(!s3bucket, "Environemnt variable S3BUCKET missing");
|
||||
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
ms3_library_init();
|
||||
ms3 = ms3_init(s3key, s3secret, s3region, s3host);
|
||||
|
||||
if (s3noverify && !strcmp(s3noverify, "1"))
|
||||
{
|
||||
ms3_set_option(ms3, MS3_OPT_DISABLE_SSL_VERIFY, NULL);
|
||||
}
|
||||
|
||||
if (s3usehttp && !strcmp(s3usehttp, "1"))
|
||||
{
|
||||
ms3_set_option(ms3, MS3_OPT_USE_HTTP, NULL);
|
||||
}
|
||||
|
||||
if (s3port)
|
||||
{
|
||||
int port = atol(s3port);
|
||||
ms3_set_option(ms3, MS3_OPT_PORT_NUMBER, &port);
|
||||
}
|
||||
|
||||
ms3_debug(true);
|
||||
ASSERT_NOT_NULL(ms3);
|
||||
|
||||
ms3_set_content_type(ms3, "text/plain");
|
||||
res = ms3_put(ms3, s3bucket, "test/content_type.txt",
|
||||
(const uint8_t *)test_string,
|
||||
strlen(test_string));
|
||||
ASSERT_EQ_(res, 0, "Result: %u", res);
|
||||
|
||||
res = ms3_list(ms3, s3bucket, NULL, &list);
|
||||
ASSERT_EQ_(res, 0, "Result: %u", res);
|
||||
found = false;
|
||||
list_it = list;
|
||||
|
||||
while (list_it)
|
||||
{
|
||||
if (!strncmp(list_it->key, "test/content_type.txt", 21))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
list_it = list_it->next;
|
||||
}
|
||||
|
||||
ASSERT_EQ_(found, 1, "Created file not found");
|
||||
|
||||
if (list_it)
|
||||
{
|
||||
ASSERT_EQ_(list_it->length, 26, "Created file is unexpected length");
|
||||
ASSERT_NEQ_(list_it->created, 0, "Created file timestamp is bad");
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_TRUE_(false, "No resuts from list");
|
||||
}
|
||||
|
||||
res = ms3_get(ms3, s3bucket, "test/content_type.txt", &data, &length);
|
||||
ASSERT_EQ_(res, 0, "Result: %u", res);
|
||||
ASSERT_EQ(length, 26);
|
||||
ASSERT_STREQ((char *)data, test_string);
|
||||
|
||||
content_type_in = ms3_get_content_type(ms3);
|
||||
|
||||
ASSERT_STREQ(content_type_in, "text/plain");
|
||||
|
||||
for (i = 0; i <= 3; i++)
|
||||
{
|
||||
res = ms3_status(ms3, s3bucket, "test/content_type.txt", &status);
|
||||
|
||||
if (res == MS3_ERR_NOT_FOUND)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT_EQ_(res, 0, "Result: %u", res);
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_EQ(status.length, 26);
|
||||
ASSERT_NEQ(status.created, 0);
|
||||
res = ms3_delete(ms3, s3bucket, "test/content_type.txt");
|
||||
ASSERT_EQ_(res, 0, "Result: %u", res);
|
||||
ms3_free(data);
|
||||
res = ms3_get(ms3, s3bucket, "test/content_type.txt", &data, &length);
|
||||
ASSERT_NEQ_(res, 0, "Object should error");
|
||||
ASSERT_NULL_(data, "Data should be NULL");
|
||||
ASSERT_EQ_(length, 0, "There should be no data");
|
||||
ms3_deinit(ms3);
|
||||
ms3_library_deinit();
|
||||
return 0;
|
||||
}
|
||||
@@ -76,3 +76,8 @@ t_read_cb_SOURCES= tests/read_cb.c
|
||||
t_read_cb_LDADD= src/libmarias3.la
|
||||
check_PROGRAMS+= t/read_cb
|
||||
noinst_PROGRAMS+= t/read_cb
|
||||
|
||||
t_content_type_SOURCES= tests/content_type.c
|
||||
t_content_type_LDADD= src/libmarias3.la
|
||||
check_PROGRAMS+= t/content_type
|
||||
noinst_PROGRAMS+= t/content_type
|
||||
|
||||
Reference in New Issue
Block a user