forked from Imagelibrary/rtems
cpukit/mttpd: Add a callback to generate a per file HTTP etag
Close #3323.
This commit is contained in:
@@ -124,6 +124,19 @@ struct mg_callbacks {
|
|||||||
// Parameters:
|
// Parameters:
|
||||||
// status: HTTP error status code.
|
// status: HTTP error status code.
|
||||||
int (*http_error)(struct mg_connection *, int status);
|
int (*http_error)(struct mg_connection *, int status);
|
||||||
|
|
||||||
|
// Called when mongoose needs to generate an HTTP etag.
|
||||||
|
// Implementing this callback allows a custom etag to be generated. If
|
||||||
|
// not implemented the standard etag generator is used which is the
|
||||||
|
// modification time as a hex value and the file size.
|
||||||
|
// Use this callback if the modification time cannot be controlled.
|
||||||
|
// Parameters:
|
||||||
|
// path: path to the file being requested
|
||||||
|
// etag: buffer to write the etag into
|
||||||
|
// etag_len: the length of the etag buffer
|
||||||
|
// Return value:
|
||||||
|
int (*http_etag)(const struct mg_connection *,
|
||||||
|
const char *path, char *etag, size_t etag_len);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start web server.
|
// Start web server.
|
||||||
|
|||||||
@@ -2989,11 +2989,17 @@ static void gmt_time_string(char *buf, size_t buf_len, time_t *t) {
|
|||||||
strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(t));
|
strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void construct_etag(char *buf, size_t buf_len,
|
static void construct_etag(const struct mg_connection *conn, const char *path,
|
||||||
|
char *buf, size_t buf_len,
|
||||||
const struct file *filep) {
|
const struct file *filep) {
|
||||||
|
if (conn->ctx->callbacks.http_etag != NULL &&
|
||||||
|
conn->ctx->callbacks.http_etag(conn, path, buf, buf_len)) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
snprintf(buf, buf_len, "\"%lx.%" INT64_FMT "\"",
|
snprintf(buf, buf_len, "\"%lx.%" INT64_FMT "\"",
|
||||||
(unsigned long) filep->modification_time, filep->size);
|
(unsigned long) filep->modification_time, filep->size);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void fclose_on_exec(struct file *filep) {
|
static void fclose_on_exec(struct file *filep) {
|
||||||
if (filep != NULL && filep->fp != NULL) {
|
if (filep != NULL && filep->fp != NULL) {
|
||||||
@@ -3061,7 +3067,7 @@ static void handle_file_request(struct mg_connection *conn, const char *path,
|
|||||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
|
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
|
||||||
gmt_time_string(date, sizeof(date), &curtime);
|
gmt_time_string(date, sizeof(date), &curtime);
|
||||||
gmt_time_string(lm, sizeof(lm), &filep->modification_time);
|
gmt_time_string(lm, sizeof(lm), &filep->modification_time);
|
||||||
construct_etag(etag, sizeof(etag), filep);
|
construct_etag(conn, path, etag, sizeof(etag), filep);
|
||||||
|
|
||||||
(void) mg_printf(conn,
|
(void) mg_printf(conn,
|
||||||
"HTTP/1.1 %d %s\r\n"
|
"HTTP/1.1 %d %s\r\n"
|
||||||
@@ -3221,11 +3227,12 @@ static int substitute_index_file(struct mg_connection *conn, char *path,
|
|||||||
|
|
||||||
// Return True if we should reply 304 Not Modified.
|
// Return True if we should reply 304 Not Modified.
|
||||||
static int is_not_modified(const struct mg_connection *conn,
|
static int is_not_modified(const struct mg_connection *conn,
|
||||||
|
const char *path,
|
||||||
const struct file *filep) {
|
const struct file *filep) {
|
||||||
char etag[64];
|
char etag[64];
|
||||||
const char *ims = mg_get_header(conn, "If-Modified-Since");
|
const char *ims = mg_get_header(conn, "If-Modified-Since");
|
||||||
const char *inm = mg_get_header(conn, "If-None-Match");
|
const char *inm = mg_get_header(conn, "If-None-Match");
|
||||||
construct_etag(etag, sizeof(etag), filep);
|
construct_etag(conn, path, etag, sizeof(etag), filep);
|
||||||
return (inm != NULL && !mg_strcasecmp(etag, inm)) ||
|
return (inm != NULL && !mg_strcasecmp(etag, inm)) ||
|
||||||
(ims != NULL && filep->modification_time <= parse_date_string(ims));
|
(ims != NULL && filep->modification_time <= parse_date_string(ims));
|
||||||
}
|
}
|
||||||
@@ -4591,7 +4598,7 @@ static void handle_request(struct mg_connection *conn) {
|
|||||||
strlen(conn->ctx->config[SSI_EXTENSIONS]),
|
strlen(conn->ctx->config[SSI_EXTENSIONS]),
|
||||||
path) > 0) {
|
path) > 0) {
|
||||||
handle_ssi_file_request(conn, path);
|
handle_ssi_file_request(conn, path);
|
||||||
} else if (is_not_modified(conn, &file)) {
|
} else if (is_not_modified(conn, path, &file)) {
|
||||||
send_http_error(conn, 304, "Not Modified", "%s", "");
|
send_http_error(conn, 304, "Not Modified", "%s", "");
|
||||||
} else {
|
} else {
|
||||||
handle_file_request(conn, path, &file);
|
handle_file_request(conn, path, &file);
|
||||||
|
|||||||
Reference in New Issue
Block a user