Hi All!
I've been toying around with Varnish's source for some time and have
been looking for small tasks to get me started with the same. With
PHK's suggestion, I've implemented a small addition to the std VMOD
which reads (and caches) a file. I've attached the patch
(fileread-std-vmod.diff) for review. Once applied, it should allow VCL
to do things like
set resp.http.Some-Header = std.fileread("/tmp/foo");
It loads and caches the contents of "/tmp/foo" in memory and returns
the same; refreshing it whenever the file changes on disk.
While working on the above I ran into a small problem with the import
statement - VCC does not seem to like `import std':
'''
Message from VCC-compiler:
Could not load module std
XXX: XXX: no default path
XXX: XXX: no default path: cannot open shared object file: No
such file or directory
('input' Line 1 Pos 8)
import std;
-------###-
Running VCC-compiler failed, exit 1
'''
I fixed this by having VCC (I know that I may be way off on this one):
i. Load libvmod_std.so automagically for `import std;'
ii. Requiring something like `import foo
"mysuperdupersharedobject.so";' for other VMODs.
iii. Allow the same convention (ii) for std as well.
This is done by the other patch I've attached (vmod-load-so.diff).
Once applied, it makes VCC accept any of the following:
import std; /* dlopen libvmod_std.so as std automatically */
import std "some_other_std.so"; /* dlopen some_other_std.so as std */
import foo "foo.so"; /* dlopen foo.so and use it as VMOD foo */
Both patches are diffs against SVN revision 5531.
--
Regards,
Sanjoy Das.
http://playingwithpointers.com
Public Key at http://playingwithpointers.com/custom/public_key.txt
Index: varnish/varnish-cache/lib/libvcl/vcc_vmod.c
===================================================================
--- varnish.orig/varnish-cache/lib/libvcl/vcc_vmod.c 2010-11-10 11:09:01.000000000 +0530
+++ varnish/varnish-cache/lib/libvcl/vcc_vmod.c 2010-11-10 11:09:20.000000000 +0530
@@ -61,8 +61,6 @@
ExpectErr(tl, ID);
mod = tl->t;
- vcc_NextToken(tl);
-
osym = VCC_FindSymbol(tl, mod, SYM_NONE);
if (osym != NULL && osym->kind != SYM_VMOD) {
vsb_printf(tl->sb, "Module %.*s conflics with other symbol.\n",
@@ -88,9 +86,13 @@
if (tl->t->tok == ID) {
vcc_NextToken(tl);
- ExpectErr(tl, CSTR);
- bprintf(fn, "%s", tl->t->dec);
- vcc_NextToken(tl);
+ if (tl->t->tok == CSTR) {
+ bprintf(fn, "%s", tl->t->dec);
+ vcc_NextToken(tl);
+ } else if (vcc_IdIs(mod, "std"))
+ bprintf(fn, "%s", "libvmod_std.so");
+ else
+ ExpectErr(tl, CSTR);
} else {
Fi(tl, 0, ", NULL);\n");
bprintf(fn, "XXX: %s", "XXX: no default path");
Index: varnish/varnish-cache/lib/libvmod_std/vmod.vcc
===================================================================
--- varnish.orig/varnish-cache/lib/libvmod_std/vmod.vcc 2010-11-10 09:57:58.000000000 +0530
+++ varnish/varnish-cache/lib/libvmod_std/vmod.vcc 2010-11-10 11:11:51.000000000 +0530
@@ -33,3 +33,4 @@
Function REAL random(REAL, REAL)
Function VOID log(STRING_LIST)
Function VOID syslog(INT, STRING_LIST)
+Function STRING fileread(PRIV_CALL, STRING)
Index: varnish/varnish-cache/lib/libvmod_std/vmod_std.c
===================================================================
--- varnish.orig/varnish-cache/lib/libvmod_std/vmod_std.c 2010-11-10 09:57:58.000000000 +0530
+++ varnish/varnish-cache/lib/libvmod_std/vmod_std.c 2010-11-10 11:56:24.000000000 +0530
@@ -31,6 +31,12 @@
#include <stdlib.h>
#include <syslog.h>
#include <netinet/in.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+
#include "vrt.h"
#include "../../bin/varnishd/cache.h"
@@ -161,3 +167,85 @@
if (p != NULL)
syslog(fac, "%s", buf);
}
+
+VSLIST_HEAD(cached_file_list, cached_file);
+
+struct cached_file {
+ char *file_name;
+ char *contents;
+ time_t last_modification;
+ VSLIST_ENTRY(cached_file) next;
+};
+
+static void
+free_cached_files(void *file_list)
+{
+ struct cached_file *iter, *tmp;
+ VSLIST_FOREACH_SAFE(iter, (struct cached_file_list *)file_list,
+ next, tmp) {
+ free(iter->file_name);
+ free(iter->contents);
+ free(iter);
+ }
+ free(file_list);
+}
+
+const char *
+vmod_fileread(struct sess *sp, struct vmod_priv *priv, const char *file_name)
+{
+ struct cached_file *iter = NULL;
+ char *contents;
+ struct stat buf;
+ FILE *fptr;
+
+ (void)sp;
+
+ if (priv->free == NULL) {
+ priv->free = free_cached_files;
+ priv->priv = malloc(sizeof(struct cached_file_list));
+ VSLIST_INIT((struct cached_file_list *)priv->priv);
+ } else {
+ VSLIST_FOREACH(iter, (struct cached_file_list *)priv->priv, next) {
+ if (iter->file_name && strcmp(iter->file_name, file_name) == 0) {
+ if (stat(file_name, &buf) != -1) {
+ if (buf.st_mtime > iter->last_modification) {
+ free(iter->contents);
+ iter->last_modification = buf.st_mtime;
+ break;
+ } else {
+ return iter->contents;
+ }
+ } else {
+ free(iter->contents);
+ free(iter->file_name);
+ VSLIST_REMOVE((struct cached_file_list *)priv->priv,
+ iter, cached_file, next);
+ free(iter);
+ return ""; /* The file does not exist anymore. */
+ }
+ }
+ }
+ }
+
+ /* The file is either too new, or has not been cached.
+ * Either ways, it needs to be re-read. */
+
+ if (iter == NULL) {
+ /* The file has not been cached. */
+ if (stat(file_name, &buf) == -1)
+ return "";
+ iter = malloc(sizeof(struct cached_file));
+ iter->file_name = strdup(file_name);
+ iter->last_modification = buf.st_mtime;
+ VSLIST_INSERT_HEAD((struct cached_file_list *)priv->priv,
+ iter, next);
+ }
+
+ contents = malloc(buf.st_size);
+ if (!(fptr = fopen(file_name, "rb")))
+ return "";
+ fread(contents, buf.st_size, 1, fptr);
+ iter->contents = contents;
+ fclose(fptr);
+ return contents;
+}
_______________________________________________
varnish-dev mailing list
[email protected]
http://lists.varnish-cache.org/mailman/listinfo/varnish-dev