diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-05-09 17:39:59 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-05-09 17:39:59 +0300 |
commit | 120a4b5f8100bf4477e1b024a2c65e760f87ac14 (patch) | |
tree | 5e1dfb617ab6a90707ccd49e52b1a1276d0f0293 | |
parent | 6aef53078ec3fdc39dc89316d31616b5fb874b91 (diff) | |
download | vmod-geoip-120a4b5f8100bf4477e1b024a2c65e760f87ac14.tar.gz vmod-geoip-120a4b5f8100bf4477e1b024a2c65e760f87ac14.tar.bz2 |
Properly convert non-string values on output; improve documentation
-rw-r--r-- | src/vmod_geoip.c | 71 | ||||
-rw-r--r-- | src/vmod_geoip.vcc | 27 |
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 @@ | |||
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | #include <inttypes.h> | ||
10 | #include "vcl.h" | 11 | #include "vcl.h" |
11 | #include "vrt.h" | 12 | #include "vrt.h" |
12 | #include "vcc_if.h" | 13 | #include "vcc_if.h" |
@@ -94,8 +95,70 @@ conv_utf_string (struct ws *ws, MMDB_entry_data_s *dptr) | |||
94 | return retval; | 95 | return retval; |
95 | } | 96 | } |
96 | 97 | ||
98 | static char * | ||
99 | wsprintf(struct ws *ws, char const *fmt, ...) | ||
100 | { | ||
101 | va_list ap; | ||
102 | size_t u, n; | ||
103 | char *p; | ||
104 | |||
105 | va_start(ap, fmt); | ||
106 | u = WS_Reserve(ws, 0); | ||
107 | p = ws->f; | ||
108 | n = vsnprintf(p, u, fmt, ap); | ||
109 | va_end(ap); | ||
110 | if (n) | ||
111 | n++; | ||
112 | else | ||
113 | p = NULL; | ||
114 | WS_Release(ws, n); | ||
115 | return p; | ||
116 | } | ||
117 | |||
118 | static char * | ||
119 | conv_uint16(struct ws *ws, MMDB_entry_data_s *dptr) | ||
120 | { | ||
121 | return wsprintf(ws, "%" PRIu16, dptr->uint16); | ||
122 | } | ||
123 | |||
124 | static char * | ||
125 | conv_uint32(struct ws *ws, MMDB_entry_data_s *dptr) | ||
126 | { | ||
127 | return wsprintf(ws, "%" PRIu32, dptr->uint32); | ||
128 | } | ||
129 | |||
130 | static char * | ||
131 | conv_int32(struct ws *ws, MMDB_entry_data_s *dptr) | ||
132 | { | ||
133 | return wsprintf(ws, "%" PRIi32, dptr->int32); | ||
134 | } | ||
135 | |||
136 | static char * | ||
137 | conv_bool(struct ws *ws, MMDB_entry_data_s *dptr) | ||
138 | { | ||
139 | return wsprintf(ws, "%01d", dptr->boolean ? 1 : 0); | ||
140 | } | ||
141 | |||
142 | static char * | ||
143 | conv_double(struct ws *ws, MMDB_entry_data_s *dptr) | ||
144 | { | ||
145 | return wsprintf(ws, "%g", dptr->double_value); | ||
146 | } | ||
147 | |||
148 | static char * | ||
149 | conv_float(struct ws *ws, MMDB_entry_data_s *dptr) | ||
150 | { | ||
151 | return wsprintf(ws, "%g", dptr->float_value); | ||
152 | } | ||
153 | |||
97 | static char *(*entry_conv[]) (struct ws *, MMDB_entry_data_s *) = { | 154 | static char *(*entry_conv[]) (struct ws *, MMDB_entry_data_s *) = { |
98 | [MMDB_DATA_TYPE_UTF8_STRING] = conv_utf_string | 155 | [MMDB_DATA_TYPE_UTF8_STRING] = conv_utf_string, |
156 | [MMDB_DATA_TYPE_UINT16] = conv_uint16, | ||
157 | [MMDB_DATA_TYPE_UINT32] = conv_uint32, | ||
158 | [MMDB_DATA_TYPE_INT32] = conv_int32, | ||
159 | [MMDB_DATA_TYPE_BOOLEAN] = conv_bool, | ||
160 | [MMDB_DATA_TYPE_DOUBLE] = conv_double, | ||
161 | [MMDB_DATA_TYPE_FLOAT] = conv_float | ||
99 | }; | 162 | }; |
100 | 163 | ||
101 | static char * | 164 | static char * |
@@ -125,7 +188,8 @@ lookup_geoip_database(struct ws *ws, | |||
125 | if (!result.found_entry) | 188 | if (!result.found_entry) |
126 | return NULL; | 189 | return NULL; |
127 | 190 | ||
128 | rc = MMDB_aget_value(&result.entry, &entry_data, (const char * const* const) path); | 191 | rc = MMDB_aget_value(&result.entry, &entry_data, |
192 | (const char * const* const) path); | ||
129 | if (rc != MMDB_SUCCESS) { | 193 | if (rc != MMDB_SUCCESS) { |
130 | fprintf(stderr, "%s %s: MMDB_aget_value %s\n", | 194 | fprintf(stderr, "%s %s: MMDB_aget_value %s\n", |
131 | pathstr, ipstr, MMDB_strerror(rc)); | 195 | pathstr, ipstr, MMDB_strerror(rc)); |
@@ -140,7 +204,8 @@ lookup_geoip_database(struct ws *ws, | |||
140 | && entry_conv[entry_data.type]) { | 204 | && entry_conv[entry_data.type]) { |
141 | retval = entry_conv[entry_data.type] (ws, &entry_data); | 205 | retval = entry_conv[entry_data.type] (ws, &entry_data); |
142 | } else | 206 | } else |
143 | retval = NULL; | 207 | retval = wsprintf(ws, "[%s: can't format %s of type %d]", |
208 | ipstr, pathstr, entry_data.type); | ||
144 | 209 | ||
145 | return retval; | 210 | return retval; |
146 | } | 211 | } |
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,8 +22,33 @@ $Function STRING get(PRIV_VCL, STRING ip, STRING path) | |||
22 | Description | 22 | Description |
23 | Look up in the database a value described by **path** corresponding to the | 23 | Look up in the database a value described by **path** corresponding to the |
24 | IP address **ip**. The lookup path must consist of one or more lookup | 24 | IP address **ip**. The lookup path must consist of one or more lookup |
25 | keys separated by dots. | 25 | keys separated by dots. If the lookup path is found, the function returns |
26 | the requested value converted to string. Otherwise, **NULL** is returned. | ||
26 | 27 | ||
28 | The following data types can be represented as string: | ||
29 | |||
30 | - utf8_string | ||
31 | - int32 | ||
32 | - uint16 | ||
33 | - uint32 | ||
34 | - boolean | ||
35 | (**0** for *false*, **1** for *true*) | ||
36 | - double | ||
37 | (formatted using **%g**) | ||
38 | - float | ||
39 | (formatted using **%g**) | ||
40 | |||
41 | For types not listed above, the following string is returned: | ||
42 | |||
43 | [*X.X.X.X*: can't format *A.B.C* of type *N*] | ||
44 | |||
45 | where *X.X.X.X* stands for IP address, *A.B.C* for lookup path, and | ||
46 | *N* for the data type in decimal. | ||
47 | |||
48 | Note that the function takes as its argument the IP address in string | ||
49 | representation. Care should be taken to ensure proper conversion when | ||
50 | passing IP addresses, as shown in the example below. | ||
51 | |||
27 | Example | 52 | Example |
28 | :: | 53 | :: |
29 | 54 | ||