mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-01-18 00:29:31 +03:00
create date and time to seconds since epoch processing utility function
currently NetSurf uses curl_getdate to convert textural date and time strings into seconds since epoch. It is betetr to move this functionality to a utility function so curl_getdate can easily be replaced if required.
This commit is contained in:
parent
33c7df0c40
commit
0bc5d2ca4c
@ -37,7 +37,6 @@
|
||||
#include <strings.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <nsutils/time.h>
|
||||
|
||||
#include "utils/config.h"
|
||||
@ -590,59 +589,79 @@ static nserror llcache_fetch_split_header(const uint8_t *data, size_t len,
|
||||
static nserror llcache_fetch_parse_header(llcache_object *object,
|
||||
const uint8_t *data, size_t len, char **name, char **value)
|
||||
{
|
||||
nserror error;
|
||||
nserror res;
|
||||
|
||||
/* Set fetch response time if not already set */
|
||||
if (object->cache.res_time == 0)
|
||||
if (object->cache.res_time == 0) {
|
||||
object->cache.res_time = time(NULL);
|
||||
}
|
||||
|
||||
/* Decompose header into name-value pair */
|
||||
error = llcache_fetch_split_header(data, len, name, value);
|
||||
if (error != NSERROR_OK)
|
||||
return error;
|
||||
res = llcache_fetch_split_header(data, len, name, value);
|
||||
if (res != NSERROR_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Parse cache headers to populate cache control data */
|
||||
#define SKIP_ST(p) while (*p != '\0' && (*p == ' ' || *p == '\t')) p++
|
||||
|
||||
if (5 < len && strcasecmp(*name, "Date") == 0) {
|
||||
if ((5 < len) &&
|
||||
strcasecmp(*name, "Date") == 0) {
|
||||
/* extract Date header */
|
||||
object->cache.date = curl_getdate(*value, NULL);
|
||||
} else if (4 < len && strcasecmp(*name, "Age") == 0) {
|
||||
nsc_strntimet(*value,
|
||||
strlen(*value),
|
||||
&object->cache.date);
|
||||
} else if ((4 < len) &&
|
||||
strcasecmp(*name, "Age") == 0) {
|
||||
/* extract Age header */
|
||||
if ('0' <= **value && **value <= '9')
|
||||
if ('0' <= **value && **value <= '9') {
|
||||
object->cache.age = atoi(*value);
|
||||
} else if (8 < len && strcasecmp(*name, "Expires") == 0) {
|
||||
}
|
||||
} else if ((8 < len) &&
|
||||
strcasecmp(*name, "Expires") == 0) {
|
||||
/* extract Expires header */
|
||||
object->cache.expires = curl_getdate(*value, NULL);
|
||||
} else if (14 < len && strcasecmp(*name, "Cache-Control") == 0) {
|
||||
res = nsc_strntimet(*value,
|
||||
strlen(*value),
|
||||
&object->cache.expires);
|
||||
if (res != NSERROR_OK) {
|
||||
object->cache.expires = (time_t)0x7fffffff;
|
||||
}
|
||||
} else if ((14 < len) &&
|
||||
strcasecmp(*name, "Cache-Control") == 0) {
|
||||
/* extract and parse Cache-Control header */
|
||||
const char *start = *value;
|
||||
const char *comma = *value;
|
||||
|
||||
while (*comma != '\0') {
|
||||
while (*comma != '\0' && *comma != ',')
|
||||
while (*comma != '\0' && *comma != ',') {
|
||||
comma++;
|
||||
}
|
||||
|
||||
if (8 < comma - start && (strncasecmp(start,
|
||||
"no-cache", 8) == 0 ||
|
||||
strncasecmp(start, "no-store", 8) == 0))
|
||||
/* When we get a disk cache we should
|
||||
* distinguish between these two */
|
||||
if ((8 < comma - start) &&
|
||||
(strncasecmp(start, "no-cache", 8) == 0 ||
|
||||
strncasecmp(start, "no-store", 8) == 0)) {
|
||||
/**
|
||||
* \todo When we get a disk cache we should
|
||||
* distinguish between these two.
|
||||
*/
|
||||
object->cache.no_cache = LLCACHE_VALIDATE_ALWAYS;
|
||||
else if (7 < comma - start &&
|
||||
strncasecmp(start, "max-age", 7) == 0) {
|
||||
} else if ((7 < comma - start) &&
|
||||
strncasecmp(start, "max-age", 7) == 0) {
|
||||
/* Find '=' */
|
||||
while (start < comma && *start != '=')
|
||||
while (start < comma && *start != '=') {
|
||||
start++;
|
||||
}
|
||||
|
||||
/* Skip over it */
|
||||
start++;
|
||||
|
||||
#define SKIP_ST(p) while (*p != '\0' && (*p == ' ' || *p == '\t')) p++
|
||||
|
||||
/* Skip whitespace */
|
||||
SKIP_ST(start);
|
||||
|
||||
if (start < comma)
|
||||
if (start < comma) {
|
||||
object->cache.max_age = atoi(start);
|
||||
}
|
||||
}
|
||||
|
||||
if (*comma != '\0') {
|
||||
@ -652,10 +671,13 @@ static nserror llcache_fetch_parse_header(llcache_object *object,
|
||||
SKIP_ST(comma);
|
||||
}
|
||||
|
||||
#undef SKIP_ST
|
||||
|
||||
/* Set start for next token */
|
||||
start = comma;
|
||||
}
|
||||
} else if (5 < len && strcasecmp(*name, "ETag") == 0) {
|
||||
} else if ((5 < len) &&
|
||||
(strcasecmp(*name, "ETag") == 0)) {
|
||||
/* extract ETag header */
|
||||
free(object->cache.etag);
|
||||
object->cache.etag = strdup(*value);
|
||||
@ -664,12 +686,14 @@ static nserror llcache_fetch_parse_header(llcache_object *object,
|
||||
free(*value);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
} else if (14 < len && strcasecmp(*name, "Last-Modified") == 0) {
|
||||
} else if ((14 < len) &&
|
||||
(strcasecmp(*name, "Last-Modified") == 0)) {
|
||||
/* extract Last-Modified header */
|
||||
object->cache.last_modified = curl_getdate(*value, NULL);
|
||||
nsc_strntimet(*value,
|
||||
strlen(*value),
|
||||
&object->cache.last_modified);
|
||||
}
|
||||
|
||||
#undef SKIP_ST
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
@ -95,7 +95,6 @@
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "utils/nsoption.h"
|
||||
#include "utils/log.h"
|
||||
@ -103,6 +102,7 @@
|
||||
#include "utils/url.h"
|
||||
#include "utils/utils.h"
|
||||
#include "utils/bloom.h"
|
||||
#include "utils/time.h"
|
||||
#include "image/bitmap.h"
|
||||
#include "desktop/cookie_manager.h"
|
||||
#include "desktop/gui_internal.h"
|
||||
@ -1587,22 +1587,21 @@ static bool urldb_parse_avpair(struct cookie_internal_data *c, char *n,
|
||||
} else if (strcasecmp(n, "Expires") == 0) {
|
||||
char *datenoday;
|
||||
time_t expires;
|
||||
nserror res;
|
||||
|
||||
/* Strip dayname from date (these are hugely
|
||||
* variable and liable to break the parser.
|
||||
* They also serve no useful purpose) */
|
||||
/* Strip dayname from date (these are hugely variable
|
||||
* and liable to break the parser. They also serve no
|
||||
* useful purpose) */
|
||||
for (datenoday = v; *datenoday && !isdigit(*datenoday);
|
||||
datenoday++)
|
||||
; /* do nothing */
|
||||
|
||||
expires = curl_getdate(datenoday, NULL);
|
||||
if (expires == -1) {
|
||||
/* assume we have an unrepresentable
|
||||
* date => force it to the maximum
|
||||
* possible value of a 32bit time_t
|
||||
* (this may break in 2038. We'll
|
||||
* deal with that once we come to
|
||||
* it) */
|
||||
res = nsc_strntimet(datenoday, strlen(datenoday), &expires);
|
||||
if (res != NSERROR_OK) {
|
||||
/* assume we have an unrepresentable date =>
|
||||
* force it to the maximum possible value of a
|
||||
* 32bit time_t (this may break in 2038. We'll
|
||||
* deal with that once we come to it) */
|
||||
expires = (time_t)0x7fffffff;
|
||||
}
|
||||
c->expires = expires;
|
||||
|
@ -91,8 +91,8 @@ struct gui_fetch_table {
|
||||
/**
|
||||
* Find a MIME type for a local file
|
||||
*
|
||||
* @note only used in curl fetcher on RISC OS otherwise its a
|
||||
* strdup of filetype.
|
||||
* @note only used in curl fetcher in form file controls on
|
||||
* RISC OS otherwise its a strdup of a filetype call.
|
||||
*
|
||||
* \param ro_path RISC OS style path to file on disk
|
||||
* \return MIME type string (on heap, caller should free), or NULL
|
||||
|
24
utils/time.h
24
utils/time.h
@ -48,6 +48,28 @@ int nsc_sntimet(char *str, size_t size, time_t *timep);
|
||||
* @param timep Pointer to result.
|
||||
* @return NSERROR_OK on success or error code on faliure.
|
||||
*/
|
||||
nserror nsc_snptimet(char *str, size_t size, time_t *timep);
|
||||
nserror nsc_snptimet(const char *str, size_t size, time_t *timep);
|
||||
|
||||
|
||||
/**
|
||||
* Converts a date string to a number of seconds since epoch
|
||||
*
|
||||
* returns the number of seconds since the Epoch, January 1st 1970
|
||||
* 00:00:00 in the UTC time zone, for the date and time that the
|
||||
* \a str parameter specifies.
|
||||
*
|
||||
* datetime strings passed must be in one of the formats specified in:
|
||||
* - RFC 822 (updated in RFC 1123) using time zone name or time zone delta
|
||||
* - RFC 850 (obsoleted by RFC 1036)
|
||||
* - ANSI C's asctime() format.
|
||||
*
|
||||
* @param[in] str The datetime string to parse
|
||||
* @param[in] size The length of the source string
|
||||
* @param[out] timep Pointer to result on success unmodified on error.
|
||||
* @return NSERROR_OK on success and timep updated else
|
||||
* NSERROR_INVALID if the string parsing failed otherwise a suitable
|
||||
* error code
|
||||
*/
|
||||
nserror nsc_strntimet(const char *str, size_t size, time_t *timep);
|
||||
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <regex.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "utils/config.h"
|
||||
#include "utils/log.h"
|
||||
@ -47,13 +48,15 @@ char *remove_underscores(const char *s, bool replacespace)
|
||||
char *ret;
|
||||
len = strlen(s);
|
||||
ret = malloc(len + 1);
|
||||
if (ret == NULL)
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0, ii = 0; i < len; i++) {
|
||||
if (s[i] != '_')
|
||||
if (s[i] != '_') {
|
||||
ret[ii++] = s[i];
|
||||
else if (replacespace)
|
||||
} else if (replacespace) {
|
||||
ret[ii++] = ' ';
|
||||
}
|
||||
}
|
||||
ret[ii] = '\0';
|
||||
return ret;
|
||||
@ -94,11 +97,14 @@ char *cnv_space2nbsp(const char *s)
|
||||
char *d, *d0;
|
||||
unsigned int numNBS;
|
||||
/* Convert space & TAB into non breaking space character (0xA0) */
|
||||
for (numNBS = 0, srcP = (const char *)s; *srcP != '\0'; ++srcP)
|
||||
if (*srcP == ' ' || *srcP == '\t')
|
||||
for (numNBS = 0, srcP = (const char *)s; *srcP != '\0'; ++srcP) {
|
||||
if (*srcP == ' ' || *srcP == '\t') {
|
||||
++numNBS;
|
||||
if ((d = (char *)malloc((srcP - s) + numNBS + 1)) == NULL)
|
||||
}
|
||||
}
|
||||
if ((d = (char *)malloc((srcP - s) + numNBS + 1)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (d0 = d, srcP = (const char *)s; *srcP != '\0'; ++srcP) {
|
||||
if (*srcP == ' ' || *srcP == '\t') {
|
||||
*d0++ = 0xC2;
|
||||
@ -116,8 +122,9 @@ bool is_dir(const char *path)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
if (stat(path, &s))
|
||||
if (stat(path, &s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISDIR(s.st_mode) ? true : false;
|
||||
}
|
||||
@ -227,7 +234,7 @@ nserror regcomp_wrapper(regex_t *preg, const char *regex, int cflags)
|
||||
* The size of buffers within human_friendly_bytesize.
|
||||
*
|
||||
* We can have a fairly good estimate of how long the buffer needs to
|
||||
* be. The unsigned long can store a value representing a maximum
|
||||
* be. The unsigned long can store a value representing a maximum
|
||||
* size of around 4 GB. Therefore the greatest space required is to
|
||||
* represent 1023MB. Currently that would be represented as "1023MB"
|
||||
* so 12 including a null terminator. Ideally we would be able to
|
||||
@ -500,7 +507,7 @@ int uname(struct utsname *buf) {
|
||||
strcpy(buf->release,"release");
|
||||
strcpy(buf->version,"version");
|
||||
strcpy(buf->machine,"pc");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -526,7 +533,7 @@ int inet_aton(const char *cp, struct in_addr *inp)
|
||||
unsigned int b1, b2, b3, b4;
|
||||
unsigned char c;
|
||||
|
||||
if (strspn(cp, "0123456789.") < strlen(cp))
|
||||
if (strspn(cp, "0123456789.") < strlen(cp))
|
||||
return 0;
|
||||
|
||||
if (sscanf(cp, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
|
||||
@ -550,17 +557,17 @@ int inet_pton(int af, const char *src, void *dst)
|
||||
|
||||
if (af == AF_INET) {
|
||||
ret = inet_aton(src, dst);
|
||||
}
|
||||
}
|
||||
#if !defined(NO_IPV6)
|
||||
else if (af == AF_INET6) {
|
||||
/* TODO: implement v6 address support */
|
||||
ret = -1;
|
||||
errno = EAFNOSUPPORT;
|
||||
}
|
||||
errno = EAFNOSUPPORT;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
ret = -1;
|
||||
errno = EAFNOSUPPORT;
|
||||
errno = EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -588,10 +595,11 @@ int nsc_sntimet(char *str, size_t size, time_t *timep)
|
||||
}
|
||||
|
||||
return strftime(str, size, "%s", ltm);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
nserror nsc_snptimet(char *str, size_t size, time_t *timep)
|
||||
/* exported function documented in utils/time.h */
|
||||
nserror nsc_snptimet(const char *str, size_t size, time_t *timep)
|
||||
{
|
||||
time_t time_out;
|
||||
|
||||
@ -628,3 +636,20 @@ nserror nsc_snptimet(char *str, size_t size, time_t *timep)
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/* exported function documented in utils/time.h */
|
||||
nserror nsc_strntimet(const char *str, size_t size, time_t *timep)
|
||||
{
|
||||
time_t result;
|
||||
|
||||
result = curl_getdate(str, NULL);
|
||||
|
||||
if (result == -1) {
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
|
||||
*timep = result;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user