aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-05-09 17:39:59 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-05-09 17:39:59 +0300
commit120a4b5f8100bf4477e1b024a2c65e760f87ac14 (patch)
tree5e1dfb617ab6a90707ccd49e52b1a1276d0f0293
parent6aef53078ec3fdc39dc89316d31616b5fb874b91 (diff)
downloadvmod-geoip-120a4b5f8100bf4477e1b024a2c65e760f87ac14.tar.gz
vmod-geoip-120a4b5f8100bf4477e1b024a2c65e760f87ac14.tar.bz2
Properly convert non-string values on output; improve documentation
-rw-r--r--src/vmod_geoip.c71
-rw-r--r--src/vmod_geoip.vcc27
2 files changed, 94 insertions, 4 deletions
diff --git a/src/vmod_geoip.c b/src/vmod_geoip.c
index 6ad23e2..fd85030 100644
--- a/src/vmod_geoip.c
+++ b/src/vmod_geoip.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <inttypes.h>
#include "vcl.h"
#include "vrt.h"
#include "vcc_if.h"
@@ -94,8 +95,70 @@ conv_utf_string (struct ws *ws, MMDB_entry_data_s *dptr)
return retval;
}
+static char *
+wsprintf(struct ws *ws, char const *fmt, ...)
+{
+ va_list ap;
+ size_t u, n;
+ char *p;
+
+ va_start(ap, fmt);
+ u = WS_Reserve(ws, 0);
+ p = ws->f;
+ n = vsnprintf(p, u, fmt, ap);
+ va_end(ap);
+ if (n)
+ n++;
+ else
+ p = NULL;
+ WS_Release(ws, n);
+ return p;
+}
+
+static char *
+conv_uint16(struct ws *ws, MMDB_entry_data_s *dptr)
+{
+ return wsprintf(ws, "%" PRIu16, dptr->uint16);
+}
+
+static char *
+conv_uint32(struct ws *ws, MMDB_entry_data_s *dptr)
+{
+ return wsprintf(ws, "%" PRIu32, dptr->uint32);
+}
+
+static char *
+conv_int32(struct ws *ws, MMDB_entry_data_s *dptr)
+{
+ return wsprintf(ws, "%" PRIi32, dptr->int32);
+}
+
+static char *
+conv_bool(struct ws *ws, MMDB_entry_data_s *dptr)
+{
+ return wsprintf(ws, "%01d", dptr->boolean ? 1 : 0);
+}
+
+static char *
+conv_double(struct ws *ws, MMDB_entry_data_s *dptr)
+{
+ return wsprintf(ws, "%g", dptr->double_value);
+}
+
+static char *
+conv_float(struct ws *ws, MMDB_entry_data_s *dptr)
+{
+ return wsprintf(ws, "%g", dptr->float_value);
+}
+
static char *(*entry_conv[]) (struct ws *, MMDB_entry_data_s *) = {
- [MMDB_DATA_TYPE_UTF8_STRING] = conv_utf_string
+ [MMDB_DATA_TYPE_UTF8_STRING] = conv_utf_string,
+ [MMDB_DATA_TYPE_UINT16] = conv_uint16,
+ [MMDB_DATA_TYPE_UINT32] = conv_uint32,
+ [MMDB_DATA_TYPE_INT32] = conv_int32,
+ [MMDB_DATA_TYPE_BOOLEAN] = conv_bool,
+ [MMDB_DATA_TYPE_DOUBLE] = conv_double,
+ [MMDB_DATA_TYPE_FLOAT] = conv_float
};
static char *
@@ -125,7 +188,8 @@ lookup_geoip_database(struct ws *ws,
if (!result.found_entry)
return NULL;
- rc = MMDB_aget_value(&result.entry, &entry_data, (const char * const* const) path);
+ rc = MMDB_aget_value(&result.entry, &entry_data,
+ (const char * const* const) path);
if (rc != MMDB_SUCCESS) {
fprintf(stderr, "%s %s: MMDB_aget_value %s\n",
pathstr, ipstr, MMDB_strerror(rc));
@@ -140,7 +204,8 @@ lookup_geoip_database(struct ws *ws,
&& entry_conv[entry_data.type]) {
retval = entry_conv[entry_data.type] (ws, &entry_data);
} else
- retval = NULL;
+ retval = wsprintf(ws, "[%s: can't format %s of type %d]",
+ ipstr, pathstr, entry_data.type);
return retval;
}
diff --git a/src/vmod_geoip.vcc b/src/vmod_geoip.vcc
index 5e2c85e..700cdb3 100644
--- a/src/vmod_geoip.vcc
+++ b/src/vmod_geoip.vcc
@@ -22,7 +22,32 @@ $Function STRING get(PRIV_VCL, STRING ip, STRING path)
Description
Look up in the database a value described by **path** corresponding to the
IP address **ip**. The lookup path must consist of one or more lookup
- keys separated by dots.
+ keys separated by dots. If the lookup path is found, the function returns
+ the requested value converted to string. Otherwise, **NULL** is returned.
+
+ The following data types can be represented as string:
+
+ - utf8_string
+ - int32
+ - uint16
+ - uint32
+ - boolean
+ (**0** for *false*, **1** for *true*)
+ - double
+ (formatted using **%g**)
+ - float
+ (formatted using **%g**)
+
+ For types not listed above, the following string is returned:
+
+ [*X.X.X.X*: can't format *A.B.C* of type *N*]
+
+ where *X.X.X.X* stands for IP address, *A.B.C* for lookup path, and
+ *N* for the data type in decimal.
+
+ Note that the function takes as its argument the IP address in string
+ representation. Care should be taken to ensure proper conversion when
+ passing IP addresses, as shown in the example below.
Example
::

Return to:

Send suggestions and report system problems to the System administrator.