String -> Time/Date casting in Varnish 3.0.4 - varnish

does anybody know how to cast header string (ie. Last-Modified Fri, 11 Dec 2015 07:31:48 GMT) to Time Type in Varnish 3.0.4. I know that in the newest version of Varsnih, there are time-specific methods in std vmod, but i don't know how can do similar thing in my version.

You can inline C this in your vcl. With Varnish 3 inline C is on by default. From here you can make it into a vmod but this should work as is (add this to vcl sub):
C{
char time_str[128];
// Format time however you need it
sprintf(time_str, "%ld", time());
VRT_SetHdr(sp, HDR_REQ, "\016Last-Modified:", time_str, vrt_magic_string_end);
}C

Related

Why tm_gmtoff field of struct tm is not documented in man page?

I need to get the difference between UTC and the local time using GCC on Linux.
It seems that the preferred way is to examine tm_gmtoff field of a struct tm returned by localtime function.
https://stackoverflow.com/a/47218792
However, tm_gmtoff is not documented in the man page of localtime, but
only tm_zone is.
https://man7.org/linux/man-pages/man3/localtime.3.html
It looks like tm_gmtoff and tm_zone exist in the header file.
19 # ifdef __USE_MISC
20 long int tm_gmtoff; /* Seconds east of UTC. */
21 const char *tm_zone; /* Timezone abbreviation. */
22 # else
23 long int __tm_gmtoff; /* Seconds east of UTC. */
24 const char *__tm_zone; /* Timezone abbreviation. */
25 # endif
https://sourceware.org/git/?p=glibc.git;a=blob;f=time/bits/types/struct_tm.h;h=b13b631228d0ec36691b25db2e1f9b1d66b54bb0;hb=HEAD
I'm not sure why tm_gmtoff is omitted in the man page. Could it be a man-page bug introduced in the following commit?
https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/man3/ctime.3?id=ba39b288ab07149417867533821300256f310615&h=master
I reported this to the maintainers. It has been fixed by the following commit.
https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/?id=20f1ee93171895341877b8c5679a33823c4ca582

Node.js C++ addons: how to create JS Date object by N-API and V8 in Node.js 10

The napi_create_date function appeared in Node.js starting with 11.11.0 version.
https://nodejs.org/api/n-api.html#n_api_napi_create_date
Which workarounds are there to create JS Date (from C++ double) on Node.js 10.15.3 using N-API and V8 API only?
Or maybe I can get V8 Isolate from N-API?
Or how can I combine N-API and NAN to create Date and use it in napi_call_function?
I need some way to create a Date value (from C++ double) for napi_call_function call.
For now I written such a workaround.
It is more correct to use env->context() instead of v8::Isolate::GetCurrent(), but napi_env is defined in src/js_native_api_v8.h, which does not exist in ~/.node-gyp/10.15.3/include/node, so I did not find a fast way to use env->context().
#include <v8.h>
// This asserts v8::Local<> will always be implemented with a single
// pointer field so that we can pass it around as a void*.
static_assert(sizeof(v8::Local<v8::Value>) == sizeof(napi_value),
"Cannot convert between v8::Local<v8::Value> and napi_value");
napi_status napi_create_date_by_v8(
double time,
napi_value* result
) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::MaybeLocal<v8::Value> maybe_date = v8::Date::New(isolate, time);
v8::Local<v8::Value> local = maybe_date.ToLocalChecked();
*result = reinterpret_cast<napi_value>(*local);
return napi_ok;
}

Inline C Varnish (VCL_deliver)

I am using Varnish 4.0.
My backend is adding to some responses an http header "x-count"
I would like to log the value of "x-count" into a file with a line break.
I assumed i should do it in VCL deliver.
Here is what i have so far :
sub vcl_deliver {
if (resp.http.x-count-this:) {
set resp.http.X-infodbg = "xx";
C{
FILE *fp;
fp = fopen("/tmp/test.txt", "w+");
fputs(VRT_GetHdr(sp, HDR_OBJ, "\013x-count-this:"), fp);
fputs("\n", fp);
fclose(fp);
}C
}
}
Of course it doesnt work and there is a couple of errors ..
./vcl.gK2lu7uM.c: In function ‘VGC_function_vcl_deliver’:
./vcl.gK2lu7uM.c:1049:22: error: ‘sp’ undeclared (first use in this
function) ./vcl.gK2lu7uM.c:1049:22: note: each undeclared identifier
is reported only once for each function it appears in
./vcl.gK2lu7uM.c:1049:5: error: passing argument 2 of ‘VRT_GetHdr’
makes pointer from integer without a cast [-Werror]
./vcl.gK2lu7uM.c:330:7: note: expected ‘const struct gethdr_s *’ but
argument is of type ‘int’ ./vcl.gK2lu7uM.c:1049:5: error: too many
arguments to function ‘VRT_GetHdr’ ./vcl.gK2lu7uM.c:330:7: note:
declared here
I have to say that i simply copy/pasted "sp" from some examples, but i have no idea where it comes from (i suppose the inline C was in a different context and therefore it was declared there but not in vcl_deliver)
So the probably undocumented differences between Varnish 4 and 3 in the above examples are :
VRT_GetHdr is now VRT_GetHdr(context, struct gethdr_s)
sp doesn't exist, but there is a "ctx" variable
Found this, there :
http://jan.bogutzki.de/Artikel/395/set-ttl-in-varnish-4.html
char *stuffid;
const struct gethdr_s hdr = { HDR_BERESP, "\015x-count-this:" };
stuffid = VRT_GetHdr(ctx, &hdr);
And now a different story: Varnish is crashing as soon as the backend sends back "count-this", but that is a different problem :p (my crappy C code probably)
I don't have Varnish 4.0 handy to test this out, but I was able to get your example working with Varnish 3.0. When I tried the VCL as is, I wasn't getting the exact error you are though. The first change:
if (resp.http.x-count-this:) {
needs to be:
if (resp.http.x-count-this) {
The colon should be left off of the header name when referred to this way. Next:
fputs(VRT_GetHdr(sp, HDR_OBJ, "\013x-count-this:"), fp);
needs to be:
fputs(VRT_GetHdr(sp, HDR_OBJ, "\015x-count-this:"), fp);
The length value in that string needs to be in octal for some reason, and 13 in octal is 15. Making those changes got this to work for me. That being said, you many want to look into using open and fcntl instead of fopen since without file locking I'm not sure what the effect of multiple requests contending for that file would be.

Understand successive call to ctime()

I have a question about how the glibc ctime() works.
Follows my snippet:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main (int argc,char** argv)
{
int ret=EXIT_SUCCESS;
time_t tm1;
time_t tm2;
tm1 = time(NULL);
tm2 = tm1 + 60; // 60 seconds later
puts("1st method-------");
printf("tm1 = %stm2 = %s",ctime(&tm1),ctime(&tm2));
puts("2nd method-------");
printf("tm1 = %s",ctime(&tm1));
printf("tm2 = %s",ctime(&tm2));
return(ret);
}
I got:
1st method-------
tm1 = Sat Jan 14 01:13:28 2012
tm2 = Sat Jan 14 01:13:28 2012
2nd method-------
tm1 = Sat Jan 14 01:13:28 2012
tm2 = Sat Jan 14 01:14:28 2012
As you see, in the first method both tm have the same value which is not correct. In the 2nd method I got correct values.
I know that ctime() puts those string in static buffer, and to overwrite it we need a successive call to ctime().
Q: Do I not doing successive call in 1st method?
Thank you for reply.
You've provided all the info necessary to solve the problem.
The second method works as you'd expect: ctime gets called, fills the buffer, and the results get printed; this process is then repeated. So you get the two distinct times printed.
For the first method, the order is different: ctime is called, then it is called again, and only then do the results get printed. The results from each call to ctime is the same, at least as far as printf is concerned: the address of the static buffer. But the contents of that buffer was changed by each call, and since printf doesn't look in the buffer until both ctime calls are done, it ends up printing the newer contents twice.
So you ARE making both calls in the first method, its just that the results of the first call get overwritten before they get printed.

Linux kernel compilation error: undefined reference to `__udivdi3' & `__umoddi3'

Here is the error I've got:
http://pastebin.com/VadUW6fy
drivers/built-in.o: In function `gem_rxmac_reset':
clkdev.c:(.text+0x212238): undefined reference to `__bad_udelay'
drivers/built-in.o: In function `divide.part.4':
clkdev.c:(.text.unlikely+0x7214): undefined reference to `__udivdi3'
clkdev.c:(.text.unlikely+0x7244): undefined reference to `__umoddi3'
I googled and found this patch: https://lkml.org/lkml/2008/4/7/82
--- a/include/linux/time.h
+++ b/include/linux/time.h
## -174,6 +174,10 ## static inline void timespec_add_ns(struct timespec *a, u64 ns)
{
ns += a->tv_nsec;
while(unlikely(ns >= NSEC_PER_SEC)) {
+ /* The following asm() prevents the compiler from
+ * optimising this loop into a modulo operation. */
+ asm("" : "+r"(ns));
+
ns -= NSEC_PER_SEC;
a->tv_sec++;
}
but failed to apply (may be due to new version of the file).
patching file linux/time.h
Hunk #1 FAILED at 174.
1 out of 1 hunk FAILED -- saving rejects to file linux/time.h.rej
surprisingly, the file time.h.rej is not present!
I should have read more closely. The patch is for timespec_add_ns(), and you have gem_rxmac_reset() and divide.part.4 functions failing. Probably unrelated to the patch you found -- instead, probably standard 64-bit div / mod functions don't have an implementation on your target platform.
Do you have a Sun GEM or Apple GMAC NIC? If not, you can probably just disable that driver and get rid of the first error message.
For the second, you might need to implement a similar asm trick in the clkdev.c file -- when I skimmed my copy for a repeated subtraction operation I didn't spot one -- but maybe you can simply steal a newer clkdev.c or clkdev.h to fix this problem? (It's a long shot, there's only one entry in git log drivers/clk/clkdev.c.)

Resources