diff --git a/buildconf/base.ini b/buildconf/base.ini index 7c146bb5..df849106 100644 --- a/buildconf/base.ini +++ b/buildconf/base.ini @@ -17,7 +17,7 @@ plugins = bin_name = uwsgi append_version = plugin_dir = . -embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall, transformation_tofile, transformation_gzip, transformation_chunked, transformation_offload, router_memcached, router_redis, router_hash +embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall, transformation_tofile, transformation_gzip, transformation_chunked, transformation_offload, router_memcached, router_redis, router_hash, router_expires as_shared_library = false locking = auto diff --git a/core/buffer.c b/core/buffer.c index 42638e69..cf2f98b1 100644 --- a/core/buffer.c +++ b/core/buffer.c @@ -3,6 +3,9 @@ extern struct uwsgi_server uwsgi; struct uwsgi_buffer *uwsgi_buffer_new(size_t len) { +#ifdef UWSGI_DEBUG_BUFFER + uwsgi_log("[uwsgi-buffer] allocating a new buffer of %llu\n", (unsigned long long) len); +#endif struct uwsgi_buffer *ub = uwsgi_calloc(sizeof(struct uwsgi_buffer)); if (len) { @@ -271,8 +274,9 @@ int uwsgi_buffer_append_base64(struct uwsgi_buffer *ub, char *s, size_t len) { void uwsgi_buffer_destroy(struct uwsgi_buffer *ub) { #ifdef UWSGI_DEBUG_BUFFER + uwsgi_log("[uwsgi-buffer] destroying buffer of %llu bytes\n", (unsigned long long) ub->len); if (ub->freed) { - uwsgi_log("[BUG] buffer at %p already destroyed !!!\n", ub); + uwsgi_log("[uwsgi-buffer][BUG] buffer at %p already destroyed !!!\n", ub); } ub->freed = 1; #endif diff --git a/plugins/router_expires/expires.c b/plugins/router_expires/expires.c new file mode 100644 index 00000000..310ae00b --- /dev/null +++ b/plugins/router_expires/expires.c @@ -0,0 +1,125 @@ +#include + +#ifdef UWSGI_ROUTING + +extern struct uwsgi_server uwsgi; + +/* + + by Unbit + + syntax: + + route = /^foobar1(.*)/ expires:filename=foo$1poo,value=30 + route = /^foobar1(.*)/ expires:unix=${time[unix]},value=30 + +*/ + +struct uwsgi_router_expires_conf { + + char *filename; + size_t filename_len; + + char *unix; + size_t unix_len; + + char *value; + size_t value_len; +}; + +static int uwsgi_routing_func_expires(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){ + + struct uwsgi_router_expires_conf *urec = (struct uwsgi_router_expires_conf *) ur->data2; + + char **subject = (char **) (((char *)(wsgi_req))+ur->subject); + uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); + + uint64_t expires = 0; + + if (urec->filename) { + + struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urec->filename, urec->filename_len); + if (!ub) return UWSGI_ROUTE_BREAK; + + struct stat st; + if (stat(ub->buf, &st)) { + uwsgi_buffer_destroy(ub); + return UWSGI_ROUTE_BREAK; + } + + expires = st.st_mtime; + uwsgi_buffer_destroy(ub); + + } + else if (urec->unix) { + struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urec->unix, urec->unix_len); + if (!ub) return UWSGI_ROUTE_BREAK; + + expires = strtoul(ub->buf, NULL, 10); + uwsgi_buffer_destroy(ub); + } + + if (urec->value) { + struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urec->value, urec->value_len); + if (!ub) return UWSGI_ROUTE_BREAK; + + expires += atoi(ub->buf); + uwsgi_buffer_destroy(ub); + } + + char expires_str[7 + 2 + 31]; + int len = uwsgi_http_date((time_t) expires, expires_str + 9); + if (!len) return UWSGI_ROUTE_BREAK; + + memcpy(expires_str, "Expires: ", 9); + + uwsgi_additional_header_add(wsgi_req, expires_str, 9 + len); + + return UWSGI_ROUTE_NEXT; +} + +static int uwsgi_router_expires(struct uwsgi_route *ur, char *args) { + ur->func = uwsgi_routing_func_expires; + ur->data = args; + ur->data_len = strlen(args); + struct uwsgi_router_expires_conf *urec = uwsgi_calloc(sizeof(struct uwsgi_router_expires_conf)); + if (uwsgi_kvlist_parse(ur->data, ur->data_len, ',', '=', + "filename", &urec->filename, + "file", &urec->filename, + "unix", &urec->unix, + "value", &urec->value, + NULL)) { + uwsgi_log("invalid route syntax: %s\n", args); + exit(1); + } + + if (urec->filename) { + urec->filename_len = strlen(urec->filename); + } + + if (urec->unix) { + urec->unix_len = strlen(urec->unix); + } + + if (urec->value) { + urec->value_len = strlen(urec->value); + } + + ur->data2 = urec; + return 0; +} + +static void router_expires_register() { + uwsgi_register_router("expires", uwsgi_router_expires); +} + +struct uwsgi_plugin router_expires_plugin = { + .name = "router_expires", + .on_load = router_expires_register, +}; + +#else +struct uwsgi_plugin router_expires_plugin = { + .name = "router_expires", +}; +#endif diff --git a/plugins/router_expires/uwsgiplugin.py b/plugins/router_expires/uwsgiplugin.py new file mode 100644 index 00000000..aecefd71 --- /dev/null +++ b/plugins/router_expires/uwsgiplugin.py @@ -0,0 +1,6 @@ +NAME='router_expires' + +CFLAGS = [] +LDFLAGS = [] +LIBS = [] +GCC_LIST = ['expires']