Skip to content

Commit

Permalink
Add httpLastModifiedToTime() to parse HTTP last-modified header.
Browse files Browse the repository at this point in the history
  • Loading branch information
dwsteele committed Jan 6, 2020
1 parent a08298c commit d2fb4f9
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 2 deletions.
8 changes: 8 additions & 0 deletions doc/xml/release.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/common/io/http/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/common/io/http/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 44 additions & 0 deletions src/common/io/http/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/common/io/http/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion test/define.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ unit:

# ----------------------------------------------------------------------------------------------------------------------------
- name: io-http
total: 5
total: 6

coverage:
common/io/http/cache: full
Expand Down
10 changes: 10 additions & 0 deletions test/src/module/common/ioHttpTest.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
{
Expand Down

0 comments on commit d2fb4f9

Please sign in to comment.