1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Parse dates in storageS3InfoList() and storageS3Info().

Previously dates were not being filled by these functions which was fine since dates were not used.

We plan to use dates for the ls command plus it makes sense for the driver to be complete since it will be used as an example.
This commit is contained in:
David Steele 2020-01-06 15:53:53 -07:00
parent d2fb4f977c
commit 61538f932c
3 changed files with 36 additions and 2 deletions

View File

@ -64,6 +64,14 @@
<p>Add <code>httpLastModifiedToTime()</code> to parse HTTP <id>last-modified</id> header.</p> <p>Add <code>httpLastModifiedToTime()</code> to parse HTTP <id>last-modified</id> header.</p>
</release-item> </release-item>
<release-item>
<release-item-contributor-list>
<release-item-reviewer id="cynthia.shang"/>
</release-item-contributor-list>
<p>Parse dates in <code>storageS3InfoList()</code> and <code>storageS3Info()</code>.</p>
</release-item>
</release-development-list> </release-development-list>
</release-core-list> </release-core-list>
</release> </release>

View File

@ -4,7 +4,6 @@ S3 Storage
#include "build.auto.h" #include "build.auto.h"
#include <string.h> #include <string.h>
#include <time.h>
#include "common/crypto/hash.h" #include "common/crypto/hash.h"
#include "common/encode.h" #include "common/encode.h"
@ -59,6 +58,7 @@ STRING_STATIC(S3_XML_TAG_CONTENTS_STR, "Contents");
STRING_STATIC(S3_XML_TAG_DELETE_STR, "Delete"); STRING_STATIC(S3_XML_TAG_DELETE_STR, "Delete");
STRING_STATIC(S3_XML_TAG_ERROR_STR, "Error"); STRING_STATIC(S3_XML_TAG_ERROR_STR, "Error");
STRING_STATIC(S3_XML_TAG_KEY_STR, "Key"); STRING_STATIC(S3_XML_TAG_KEY_STR, "Key");
STRING_STATIC(S3_XML_TAG_LAST_MODIFIED_STR, "LastModified");
STRING_STATIC(S3_XML_TAG_MESSAGE_STR, "Message"); STRING_STATIC(S3_XML_TAG_MESSAGE_STR, "Message");
STRING_STATIC(S3_XML_TAG_NEXT_CONTINUATION_TOKEN_STR, "NextContinuationToken"); STRING_STATIC(S3_XML_TAG_NEXT_CONTINUATION_TOKEN_STR, "NextContinuationToken");
STRING_STATIC(S3_XML_TAG_OBJECT_STR, "Object"); STRING_STATIC(S3_XML_TAG_OBJECT_STR, "Object");
@ -574,6 +574,7 @@ storageS3Info(THIS_VOID, const String *file, StorageInterfaceInfoParam param)
result.exists = true; result.exists = true;
result.type = storageTypeFile; result.type = storageTypeFile;
result.size = cvtZToUInt64(strPtr(httpHeaderGet(httpResult.responseHeader, HTTP_HEADER_CONTENT_LENGTH_STR))); result.size = cvtZToUInt64(strPtr(httpHeaderGet(httpResult.responseHeader, HTTP_HEADER_CONTENT_LENGTH_STR)));
result.timeModified = httpLastModifiedToTime(httpHeaderGet(httpResult.responseHeader, HTTP_HEADER_LAST_MODIFIED_STR));
} }
FUNCTION_LOG_RETURN(STORAGE_INFO, result); FUNCTION_LOG_RETURN(STORAGE_INFO, result);
@ -586,6 +587,22 @@ typedef struct StorageS3InfoListData
void *callbackData; // User-supplied callback data void *callbackData; // User-supplied callback data
} StorageS3InfoListData; } StorageS3InfoListData;
// Helper to convert YYYY-MM-DDTHH:MM:SS.MSECZ format to time_t. This format is very nearly ISO-8601 except for the inclusion of
// milliseconds which are discarded here.
static time_t
storageS3CvtTime(const String *time)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, time);
FUNCTION_TEST_END();
FUNCTION_TEST_RETURN(
epochFromParts(
cvtZToInt(strPtr(strSubN(time, 0, 4))), cvtZToInt(strPtr(strSubN(time, 5, 2))),
cvtZToInt(strPtr(strSubN(time, 8, 2))), cvtZToInt(strPtr(strSubN(time, 11, 2))),
cvtZToInt(strPtr(strSubN(time, 14, 2))), cvtZToInt(strPtr(strSubN(time, 17, 2)))));
}
static void static void
storageS3InfoListCallback(StorageS3 *this, void *callbackData, const String *name, StorageType type, const XmlNode *xml) storageS3InfoListCallback(StorageS3 *this, void *callbackData, const String *name, StorageType type, const XmlNode *xml)
{ {
@ -609,6 +626,8 @@ storageS3InfoListCallback(StorageS3 *this, void *callbackData, const String *nam
.type = type, .type = type,
.name = name, .name = name,
.size = type == storageTypeFile ? cvtZToUInt64(strPtr(xmlNodeContent(xmlNodeChild(xml, S3_XML_TAG_SIZE_STR, true)))) : 0, .size = type == storageTypeFile ? cvtZToUInt64(strPtr(xmlNodeContent(xmlNodeChild(xml, S3_XML_TAG_SIZE_STR, true)))) : 0,
.timeModified = type == storageTypeFile ?
storageS3CvtTime(xmlNodeContent(xmlNodeChild(xml, S3_XML_TAG_LAST_MODIFIED_STR, true))) : 0,
}; };
data->callback(data->callbackData, &info); data->callback(data->callbackData, &info);

View File

@ -200,7 +200,11 @@ testS3Server(void)
// File exists // File exists
harnessTlsServerExpect(testS3ServerRequest(HTTP_VERB_HEAD, "/subdir/file1.txt", NULL)); harnessTlsServerExpect(testS3ServerRequest(HTTP_VERB_HEAD, "/subdir/file1.txt", NULL));
harnessTlsServerReply(testS3ServerResponse(200, "OK", "content-length:9999", NULL)); harnessTlsServerReply(testS3ServerResponse(
200, "OK",
"content-length:9999\r\n"
"Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT",
NULL));
// InfoList() // InfoList()
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
@ -213,6 +217,7 @@ testS3Server(void)
"<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">" "<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">"
" <Contents>" " <Contents>"
" <Key>path/to/test_file</Key>" " <Key>path/to/test_file</Key>"
" <LastModified>2009-10-12T17:50:30.000Z</LastModified>"
" <Size>787</Size>" " <Size>787</Size>"
" </Contents>" " </Contents>"
" <CommonPrefixes>" " <CommonPrefixes>"
@ -817,6 +822,7 @@ testRun(void)
TEST_RESULT_BOOL(info.exists, true, " check exists"); TEST_RESULT_BOOL(info.exists, true, " check exists");
TEST_RESULT_UINT(info.type, storageTypeFile, " check type"); TEST_RESULT_UINT(info.type, storageTypeFile, " check type");
TEST_RESULT_UINT(info.size, 9999, " check exists"); TEST_RESULT_UINT(info.size, 9999, " check exists");
TEST_RESULT_UINT(info.timeModified, 1445412480, " check time");
// InfoList() // InfoList()
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
@ -833,6 +839,7 @@ testRun(void)
TEST_RESULT_UINT(testStorageInfoList[0].type, storageTypePath, " check type"); TEST_RESULT_UINT(testStorageInfoList[0].type, storageTypePath, " check type");
TEST_RESULT_STR_Z(testStorageInfoList[1].name, "test_file", " check name"); TEST_RESULT_STR_Z(testStorageInfoList[1].name, "test_file", " check name");
TEST_RESULT_UINT(testStorageInfoList[1].size, 787, " check size"); TEST_RESULT_UINT(testStorageInfoList[1].size, 787, " check size");
TEST_RESULT_UINT(testStorageInfoList[1].timeModified, 1255369830, " check time");
TEST_RESULT_UINT(testStorageInfoList[1].type, storageTypeFile, " check type"); TEST_RESULT_UINT(testStorageInfoList[1].type, storageTypeFile, " check type");
// storageDriverList() // storageDriverList()