1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-18 04:58:51 +02:00

Add httpLastModifiedToTime() to parse HTTP last-modified header.

This commit is contained in:
David Steele 2020-01-06 15:24:49 -07:00
parent a08298ce1b
commit d2fb4f977c
8 changed files with 72 additions and 2 deletions

View File

@ -56,6 +56,14 @@
<p>Add basic time management functions.</p>
</release-item>
<release-item>
<release-item-contributor-list>
<release-item-reviewer id="cynthia.shang"/>
</release-item-contributor-list>
<p>Add <code>httpLastModifiedToTime()</code> to parse HTTP <id>last-modified</id> header.</p>
</release-item>
</release-development-list>
</release-core-list>
</release>

View File

@ -380,7 +380,7 @@ common/io/http/cache.o: common/io/http/cache.c build.auto.h common/assert.h comm
common/io/http/client.o: common/io/http/client.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/common.h common/io/http/header.h common/io/http/query.h common/io/io.h common/io/read.h common/io/read.intern.h common/io/tls/client.h common/io/write.h common/log.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/list.h common/type/param.h common/type/string.h common/type/stringList.h common/type/stringz.h common/type/variant.h common/type/variantList.h common/wait.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c common/io/http/client.c -o common/io/http/client.o
common/io/http/common.o: common/io/http/common.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/http/common.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h common/type/stringz.h
common/io/http/common.o: common/io/http/common.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/http/common.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/string.h common/type/stringz.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c common/io/http/common.c -o common/io/http/common.o
common/io/http/header.o: common/io/http/header.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/http/header.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/list.h common/type/param.h common/type/string.h common/type/stringList.h common/type/stringz.h common/type/variant.h common/type/variantList.h

View File

@ -32,6 +32,7 @@ STRING_EXTERN(HTTP_HEADER_CONTENT_MD5_STR, HTTP_HEADER_
#define HTTP_HEADER_TRANSFER_ENCODING "transfer-encoding"
STRING_STATIC(HTTP_HEADER_TRANSFER_ENCODING_STR, HTTP_HEADER_TRANSFER_ENCODING);
STRING_EXTERN(HTTP_HEADER_ETAG_STR, HTTP_HEADER_ETAG);
STRING_EXTERN(HTTP_HEADER_LAST_MODIFIED_STR, HTTP_HEADER_LAST_MODIFIED);
#define HTTP_VALUE_CONNECTION_CLOSE "close"
STRING_STATIC(HTTP_VALUE_CONNECTION_CLOSE_STR, HTTP_VALUE_CONNECTION_CLOSE);

View File

@ -45,6 +45,8 @@ HTTP Constants
STRING_DECLARE(HTTP_HEADER_CONTENT_MD5_STR);
#define HTTP_HEADER_ETAG "etag"
STRING_DECLARE(HTTP_HEADER_ETAG_STR);
#define HTTP_HEADER_LAST_MODIFIED "last-modified"
STRING_DECLARE(HTTP_HEADER_LAST_MODIFIED_STR);
#define HTTP_RESPONSE_CODE_FORBIDDEN 403
#define HTTP_RESPONSE_CODE_NOT_FOUND 404

View File

@ -3,8 +3,52 @@ Http Common
***********************************************************************************************************************************/
#include "build.auto.h"
#include <string.h>
#include "common/debug.h"
#include "common/io/http/common.h"
#include "common/time.h"
/***********************************************************************************************************************************
Convert the time using the format specified in https://tools.ietf.org/html/rfc7231#section-7.1.1.1 which is used by HTTP 1.1 (the
only version we support).
***********************************************************************************************************************************/
time_t
httpLastModifiedToTime(const String *lastModified)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, lastModified);
FUNCTION_TEST_END();
time_t result = 0;
MEM_CONTEXT_TEMP_BEGIN()
{
// Find the month
static const char *monthList[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
const char *month = strPtr(strSubN(lastModified, 8, 3));
unsigned int monthIdx = 0;
for (; monthIdx < sizeof(monthList) / sizeof(char *); monthIdx++)
{
if (strcmp(month, monthList[monthIdx]) == 0)
break;
}
if (monthIdx == sizeof(monthList) / sizeof(char *))
THROW_FMT(FormatError, "invalid month '%s'", month);
// Convert to time_t
result = epochFromParts(
cvtZToInt(strPtr(strSubN(lastModified, 12, 4))), (int)monthIdx + 1, cvtZToInt(strPtr(strSubN(lastModified, 5, 2))),
cvtZToInt(strPtr(strSubN(lastModified, 17, 2))), cvtZToInt(strPtr(strSubN(lastModified, 20, 2))),
cvtZToInt(strPtr(strSubN(lastModified, 23, 2))));
}
MEM_CONTEXT_TEMP_END();
FUNCTION_TEST_RETURN(result);
}
/***********************************************************************************************************************************
Encode string to conform with URI specifications

View File

@ -6,11 +6,16 @@ Http common functions.
#ifndef COMMON_IO_HTTP_COMMON_H
#define COMMON_IO_HTTP_COMMON_H
#include <time.h>
#include "common/type/string.h"
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
// Convert Last-Modified header to time_t
time_t httpLastModifiedToTime(const String *lastModified);
String *httpUriEncode(const String *uri, bool path);
#endif

View File

@ -247,7 +247,7 @@ unit:
# ----------------------------------------------------------------------------------------------------------------------------
- name: io-http
total: 5
total: 6
coverage:
common/io/http/cache: full

View File

@ -311,6 +311,16 @@ testRun(void)
TEST_RESULT_STR_Z(httpUriEncode(strNew("0-9_~/A Z.az"), true), "0-9_~/A%20Z.az", "path encoding");
}
// *****************************************************************************************************************************
if (testBegin("httpLastModifiedToTime()"))
{
TEST_ERROR(httpLastModifiedToTime(STRDEF("Wed, 21 Bog 2015 07:28:00 GMT")), FormatError, "invalid month 'Bog'");
TEST_ERROR(
httpLastModifiedToTime(STRDEF("Wed, 1 Oct 2015 07:28:00 GMT")), FormatError,
"unable to convert base 10 string ' 1' to int");
TEST_RESULT_INT(httpLastModifiedToTime(STRDEF("Wed, 21 Oct 2015 07:28:00 GMT")), 1445412480, "convert gmt datetime");
}
// *****************************************************************************************************************************
if (testBegin("HttpHeader"))
{