From 54e089c3a1382795f00adb6d8aa0244e39ca904f Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Sat, 6 Dec 2014 13:42:20 -0800 Subject: [PATCH 1/2] Support all MaxMind DB data types --- ngx_http_geoip2_module.c | 48 ++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/ngx_http_geoip2_module.c b/ngx_http_geoip2_module.c index 51baadb..b76999e 100644 --- a/ngx_http_geoip2_module.c +++ b/ngx_http_geoip2_module.c @@ -9,6 +9,7 @@ #include #include +#include #include @@ -50,6 +51,15 @@ static ngx_int_t ngx_http_geoip2_cidr_value(ngx_conf_t *cf, ngx_str_t *net, static void ngx_http_geoip2_cleanup(void *data); +#define FORMAT(fmt, ...) \ + p = ngx_palloc(r->pool, NGX_OFF_T_LEN); \ + if (p == NULL) { \ + return NGX_ERROR; \ + } \ + v->len = ngx_sprintf(p, fmt, __VA_ARGS__) - p; \ + v->data = p; \ + break + static ngx_command_t ngx_http_geoip2_commands[] = { { ngx_string("geoip2"), @@ -184,18 +194,42 @@ ngx_http_geoip2_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, } switch (entry_data.type) { + case MMDB_DATA_TYPE_BOOLEAN: + FORMAT("%d", entry_data.boolean); case MMDB_DATA_TYPE_UTF8_STRING: v->data = (u_char *) entry_data.utf8_string; v->len = entry_data.data_size; break; - case MMDB_DATA_TYPE_UINT32: - p = ngx_palloc(r->pool, NGX_OFF_T_LEN); - if (p == NULL) { - return NGX_ERROR; - } - v->len = ngx_sprintf(p, "%O", entry_data.uint32) - p; - v->data = p; + case MMDB_DATA_TYPE_BYTES: + v->data = (u_char *) entry_data.bytes; + v->len = entry_data.data_size; break; + case MMDB_DATA_TYPE_FLOAT: + FORMAT("%.5f", entry_data.float_value); + case MMDB_DATA_TYPE_DOUBLE: + FORMAT("%.5f", entry_data.double_value); + case MMDB_DATA_TYPE_UINT16: + FORMAT("%" PRIu16, entry_data.uint16); + case MMDB_DATA_TYPE_UINT32: + FORMAT("%" PRIu32, entry_data.uint32); + case MMDB_DATA_TYPE_INT32: + FORMAT("%" PRIi32, entry_data.int32); + case MMDB_DATA_TYPE_UINT64: + FORMAT("%" PRIu64, entry_data.uint64); + case MMDB_DATA_TYPE_UINT128: ; +#if MMDB_UINT128_IS_BYTE_ARRAY + uint8_t *val = (uint8_t *)entry_data.uint128; + FORMAT( "0x%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x", + val[0], val[1], val[2], val[3], + val[4], val[5], val[6], val[7], + val[8], val[9], val[10], val[11], + val[12], val[13], val[14], val[15]); +#else + mmdb_uint128_t val = entry_data.uint128; + FORMAT("0x%016" PRIx64 "%016" PRIx64, + (uint64_t) (val >> 64), (uint64_t) val); +#endif default: goto not_found; } From 21ffc356d2f5c8477beb28db18fda914be13ff11 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Mon, 8 Dec 2014 16:18:21 -0800 Subject: [PATCH 2/2] Use Nginx's non-standard printf format spec --- ngx_http_geoip2_module.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ngx_http_geoip2_module.c b/ngx_http_geoip2_module.c index b76999e..61ffdd3 100644 --- a/ngx_http_geoip2_module.c +++ b/ngx_http_geoip2_module.c @@ -9,7 +9,6 @@ #include #include -#include #include @@ -209,13 +208,13 @@ ngx_http_geoip2_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, case MMDB_DATA_TYPE_DOUBLE: FORMAT("%.5f", entry_data.double_value); case MMDB_DATA_TYPE_UINT16: - FORMAT("%" PRIu16, entry_data.uint16); + FORMAT("%uD", entry_data.uint16); case MMDB_DATA_TYPE_UINT32: - FORMAT("%" PRIu32, entry_data.uint32); + FORMAT("%uD", entry_data.uint32); case MMDB_DATA_TYPE_INT32: - FORMAT("%" PRIi32, entry_data.int32); + FORMAT("%D", entry_data.int32); case MMDB_DATA_TYPE_UINT64: - FORMAT("%" PRIu64, entry_data.uint64); + FORMAT("%uL", entry_data.uint64); case MMDB_DATA_TYPE_UINT128: ; #if MMDB_UINT128_IS_BYTE_ARRAY uint8_t *val = (uint8_t *)entry_data.uint128; @@ -227,7 +226,7 @@ ngx_http_geoip2_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, val[12], val[13], val[14], val[15]); #else mmdb_uint128_t val = entry_data.uint128; - FORMAT("0x%016" PRIx64 "%016" PRIx64, + FORMAT("0x%016uxL%016uxL", (uint64_t) (val >> 64), (uint64_t) val); #endif default: