1
0
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:
Andrew Hutchings
2024-09-05 09:59:31 +01:00
committed by Monty
parent 28e5459035
commit 93b1b1e5fd
7 changed files with 223 additions and 2 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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
View 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;
}

View File

@@ -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