mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 21:51:30 +00:00
added support for expires header
This commit is contained in:
+55
-5
@@ -16,7 +16,8 @@ static size_t get_content_length(char *buf, uint16_t size) {
|
||||
return val;
|
||||
}
|
||||
|
||||
void set_http_date(time_t t, char *dst) {
|
||||
|
||||
int set_http_date(time_t t, char *header, int header_len, char *dst, int last) {
|
||||
|
||||
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
static char *months[] = {
|
||||
@@ -26,12 +27,58 @@ void set_http_date(time_t t, char *dst) {
|
||||
};
|
||||
|
||||
struct tm *hdtm = gmtime(&t);
|
||||
snprintf(dst, 49, "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\r\n",
|
||||
|
||||
if (last) {
|
||||
return snprintf(dst, 36+header_len, "%.*s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\r\n",
|
||||
header_len, header,
|
||||
week[hdtm->tm_wday], hdtm->tm_mday,
|
||||
months[hdtm->tm_mon], hdtm->tm_year+1900,
|
||||
hdtm->tm_hour, hdtm->tm_min, hdtm->tm_sec);
|
||||
}
|
||||
|
||||
return snprintf(dst, 34+header_len, "%.*s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||||
header_len, header,
|
||||
week[hdtm->tm_wday], hdtm->tm_mday,
|
||||
months[hdtm->tm_mon], hdtm->tm_year+1900,
|
||||
hdtm->tm_hour, hdtm->tm_min, hdtm->tm_sec);
|
||||
}
|
||||
|
||||
void uwsgi_add_expires_type(struct wsgi_request *wsgi_req, char *mime_type, int mime_type_len, struct stat *st) {
|
||||
|
||||
struct uwsgi_dyn_dict *udd = uwsgi.static_expires_type;
|
||||
time_t now = wsgi_req->start_of_request.tv_sec;
|
||||
// Expires+34+1
|
||||
char expires[42];
|
||||
|
||||
while(udd) {
|
||||
if (!uwsgi_strncmp(udd->key, udd->keylen, mime_type, mime_type_len)) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(now+delta, "Expires", 7, expires, 0);
|
||||
if (size > 0) {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, expires, size);
|
||||
wsgi_req->header_cnt++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
udd = udd->next;
|
||||
}
|
||||
|
||||
udd = uwsgi.static_expires_type_mtime;
|
||||
while(udd) {
|
||||
if (!uwsgi_strncmp(udd->key, udd->keylen, mime_type, mime_type_len)) {
|
||||
int delta = uwsgi_str_num(udd->value, udd->vallen);
|
||||
int size = set_http_date(st->st_mtime+delta, "Expires", 7, expires, 0);
|
||||
if (size > 0) {
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, expires, size);
|
||||
wsgi_req->header_cnt++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
udd = udd->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// only RFC 1123 is supported
|
||||
time_t parse_http_date(char *date, uint16_t len) {
|
||||
|
||||
@@ -1723,6 +1770,9 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
headers_vec[2].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 3);
|
||||
wsgi_req->header_cnt++;
|
||||
|
||||
// check for content-type related headers
|
||||
uwsgi_add_expires_type(wsgi_req, mime_type, mime_type_size, &st);
|
||||
}
|
||||
|
||||
// nginx
|
||||
@@ -1732,7 +1782,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
headers_vec[2].iov_base = "\r\n"; headers_vec[2].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 3);
|
||||
// this is the final header (\r\n added)
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
set_http_date(st.st_mtime, "Last-Modified", 13, http_last_modified, 1);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
wsgi_req->header_cnt += 2;
|
||||
}
|
||||
@@ -1743,7 +1793,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
headers_vec[2].iov_base = "\r\n"; headers_vec[2].iov_len = 2;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 3);
|
||||
// this is the final header (\r\n added)
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
set_http_date(st.st_mtime, "Last-Modified", 13, http_last_modified, 1);
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, http_last_modified, 48);
|
||||
wsgi_req->header_cnt += 2;
|
||||
}
|
||||
@@ -1757,7 +1807,7 @@ int uwsgi_file_serve(struct wsgi_request *wsgi_req, char *document_root, uint16_
|
||||
headers_vec[2].iov_base = "\r\n";
|
||||
headers_vec[2].iov_len = 2;
|
||||
// this is the final header (\r\n added)
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
set_http_date(st.st_mtime, "Last-Modified", 13, http_last_modified, 1);
|
||||
headers_vec[3].iov_base = http_last_modified;
|
||||
headers_vec[3].iov_len = 48;
|
||||
wsgi_req->headers_size += wsgi_req->socket->proto_writev_header(wsgi_req, headers_vec, 4);
|
||||
|
||||
@@ -363,17 +363,21 @@ static struct uwsgi_option uwsgi_base_options[] = {
|
||||
{"route-qs", required_argument, 0, "add a route based on QUERY_STRING", uwsgi_opt_add_route, "query_string", 0},
|
||||
#endif
|
||||
{"add-header", required_argument, 0, "automatically add HTTP headers to response", uwsgi_opt_add_string_list, &uwsgi.additional_headers, 0},
|
||||
{"check-static", required_argument, 0, "check for static files in the specified directory", uwsgi_opt_check_static, NULL, 0},
|
||||
{"check-static-docroot", no_argument, 0, "check for static files in the requested DOCUMENT_ROOT", uwsgi_opt_true, &uwsgi.check_static_docroot, UWSGI_OPT_MIME},
|
||||
{"static-check", required_argument, 0, "check for static files in the specified directory", uwsgi_opt_check_static, NULL, 0},
|
||||
{"static-map", required_argument, 0, "map mountpoint to static directory", uwsgi_opt_static_map, NULL, 0},
|
||||
{"static-skip-ext", required_argument, 0, "skip specified extension from staticfile checks", uwsgi_opt_add_string_list, &uwsgi.static_skip_ext, 0},
|
||||
{"static-index", required_argument, 0, "search for specified file if a directory is requested", uwsgi_opt_add_string_list, &uwsgi.static_index, 0},
|
||||
{"mimefile", required_argument, 0, "set mime types file path (default /etc/mime.types)", uwsgi_opt_set_str, &uwsgi.mime_file, 0},
|
||||
{"mime-file", required_argument, 0, "set mime types file path (default /etc/mime.types)", uwsgi_opt_set_str, &uwsgi.mime_file, 0},
|
||||
|
||||
{"file-serve-mode", required_argument, 0, "set static file serving mode", uwsgi_opt_fileserve_mode, NULL,0},
|
||||
{"fileserve-mode", required_argument, 0, "set static file serving mode", uwsgi_opt_fileserve_mode, NULL,0},
|
||||
{"check-static", required_argument, 0, "check for static files in the specified directory", uwsgi_opt_check_static, NULL, UWSGI_OPT_MIME},
|
||||
{"check-static-docroot", no_argument, 0, "check for static files in the requested DOCUMENT_ROOT", uwsgi_opt_true, &uwsgi.check_static_docroot, UWSGI_OPT_MIME},
|
||||
{"static-check", required_argument, 0, "check for static files in the specified directory", uwsgi_opt_check_static, NULL, UWSGI_OPT_MIME},
|
||||
{"static-map", required_argument, 0, "map mountpoint to static directory", uwsgi_opt_static_map, NULL, UWSGI_OPT_MIME},
|
||||
{"static-skip-ext", required_argument, 0, "skip specified extension from staticfile checks", uwsgi_opt_add_string_list, &uwsgi.static_skip_ext, UWSGI_OPT_MIME},
|
||||
{"static-index", required_argument, 0, "search for specified file if a directory is requested", uwsgi_opt_add_string_list, &uwsgi.static_index, UWSGI_OPT_MIME},
|
||||
{"mimefile", required_argument, 0, "set mime types file path (default /etc/mime.types)", uwsgi_opt_set_str, &uwsgi.mime_file, UWSGI_OPT_MIME},
|
||||
{"mime-file", required_argument, 0, "set mime types file path (default /etc/mime.types)", uwsgi_opt_set_str, &uwsgi.mime_file, UWSGI_OPT_MIME},
|
||||
|
||||
{"static-expires-type", required_argument, 0, "set the Expires header base on content type", uwsgi_opt_add_dyn_dict, &uwsgi.static_expires_type, UWSGI_OPT_MIME},
|
||||
{"static-expires-type-mtime", required_argument, 0, "set the Expires header base on content type and file mtime", uwsgi_opt_add_dyn_dict, &uwsgi.static_expires_type_mtime, UWSGI_OPT_MIME},
|
||||
|
||||
{"file-serve-mode", required_argument, 0, "set static file serving mode", uwsgi_opt_fileserve_mode, NULL, UWSGI_OPT_MIME},
|
||||
{"fileserve-mode", required_argument, 0, "set static file serving mode", uwsgi_opt_fileserve_mode, NULL, UWSGI_OPT_MIME},
|
||||
|
||||
{"check-cache", no_argument, 0, "check for response data in the cache", uwsgi_opt_true, &uwsgi.check_cache, 0},
|
||||
{"close-on-exec", no_argument, 0, "set close-on-exec on sockets (could be required for spawning processes in requests)", uwsgi_opt_true, &uwsgi.close_on_exec, 0},
|
||||
@@ -3689,6 +3693,20 @@ void uwsgi_opt_check_static(char *opt, char *value, void *foobar) {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_opt_add_dyn_dict(char *opt, char *value, void *dict) {
|
||||
|
||||
char *equal = strchr(value, '=');
|
||||
if (!equal) {
|
||||
uwsgi_log("invalid dictionary syntax for %s\n", opt);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct uwsgi_dyn_dict **udd = (struct uwsgi_dyn_dict **) dict;
|
||||
|
||||
uwsgi_dyn_dict_new(udd, value, equal-value, equal+1, strlen(equal+1));
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_opt_fileserve_mode(char *opt, char *value, void *foobar) {
|
||||
|
||||
if (!strcasecmp("x-sendfile", value)) {
|
||||
|
||||
@@ -1274,6 +1274,10 @@ struct uwsgi_server {
|
||||
struct uwsgi_dyn_dict *mimetypes;
|
||||
struct uwsgi_string_list *static_skip_ext;
|
||||
struct uwsgi_string_list *static_index;
|
||||
|
||||
struct uwsgi_dyn_dict *static_expires_type;
|
||||
struct uwsgi_dyn_dict *static_expires_type_mtime;
|
||||
|
||||
int check_static_docroot;
|
||||
|
||||
char *daemonize;
|
||||
@@ -2637,6 +2641,7 @@ void uwsgi_opt_set_str(char *, char *, void *);
|
||||
void uwsgi_opt_set_logger(char *, char *, void *);
|
||||
void uwsgi_opt_set_str_spaced(char *, char *, void *);
|
||||
void uwsgi_opt_add_string_list(char *, char *, void *);
|
||||
void uwsgi_opt_add_dyn_dict(char *, char *, void *);
|
||||
void uwsgi_opt_set_int(char *, char *, void *);
|
||||
void uwsgi_opt_set_64bit(char *, char *, void *);
|
||||
void uwsgi_opt_set_megabytes(char *, char *, void *);
|
||||
|
||||
Reference in New Issue
Block a user