Improvements to geoip module

Hello Nginx users and committers,

Nginx is great - thanks for all the work.

I needed the continent code and the latitude/longitude returned from the
MaxMind geoip libraries and I modified ngx_http_geoip_module.c to add
more variables for this data.

Patch on version 0.8.20 is below (fairly straightforward, it seems
longer because of a slight refactoring to avoid cut/paste)

Any interest in merging this to the tree?

Arvind.

diff -crB …/orig/nginx-0.8.20/src/http/modules/ngx_http_geoip_module.c
src/http/modules/ngx_http_geoip_module.c
*** …/orig/nginx-0.8.20/src/http/modules/ngx_http_geoip_module.c
2009-08-19 10:44:33.000000000 -0700
— src/http/modules/ngx_http_geoip_module.c 2009-10-15
22:49:18.000000000 -0700


*** 30,35 ****
— 30,37 ----
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);

  • static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t
    *r,

  • ngx_http_variable_value_t *v, uintptr_t data);
    

    static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
    static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);


*** 102,107 ****
— 104,112 ----
{ ngx_string(“geoip_country_name”), NULL,
ngx_http_geoip_country_variable,
(uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 },

  • { ngx_string("geoip_city_continent_code"), NULL, 
    

ngx_http_geoip_city_variable,

  •   offsetof(GeoIPRecord, continent_code), 0, 0 },
    
  • { ngx_string("geoip_city_country_code"), NULL, 
    

ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, country_code), 0, 0 },


*** 124,129 ****
— 129,142 ----
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, postal_code), 0, 0 },

  • { ngx_string("geoip_latitude"), NULL,
    
  •   ngx_http_geoip_city_float_variable,
    
  •   offsetof(GeoIPRecord, latitude), 0, 0 },
    
  • { ngx_string("geoip_longitude"), NULL,
    
  •   ngx_http_geoip_city_float_variable,
    
  •   offsetof(GeoIPRecord, longitude), 0, 0 },
    
  • { ngx_null_string, NULL, NULL, 0, 0, 0 }
    
    };

*** 175,206 ****
}

! static ngx_int_t
! ngx_http_geoip_city_variable(ngx_http_request_t *r,
! ngx_http_variable_value_t *v, uintptr_t data)
{
u_long addr;

  • char                   *val;
    
  • size_t                  len;
    
  • GeoIPRecord            *gr;
    struct sockaddr_in     *sin;
    ngx_http_geoip_conf_t  *gcf;
    

!
gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);

  if (gcf->city == NULL) {

! goto not_found;
}

  if (r->connection->sockaddr->sa_family != AF_INET) {

! goto not_found;
}

  sin = (struct sockaddr_in *) r->connection->sockaddr;
  addr = ntohl(sin->sin_addr.s_addr);

! gr = GeoIP_record_by_ipnum(gcf->city, addr);

  if (gr == NULL) {
      goto not_found;
  }

— 188,226 ----
}

! static GeoIPRecord*
! ngx_http_geoip_get_city_record(ngx_http_request_t *r)
{
u_long addr;
struct sockaddr_in *sin;
ngx_http_geoip_conf_t *gcf;
!
gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);

  if (gcf->city == NULL) {

! return NULL;
}

  if (r->connection->sockaddr->sa_family != AF_INET) {

! return NULL;
}

  sin = (struct sockaddr_in *) r->connection->sockaddr;
  addr = ntohl(sin->sin_addr.s_addr);

! return GeoIP_record_by_ipnum(gcf->city, addr);
! }
!
!
! static ngx_int_t
! ngx_http_geoip_city_variable(ngx_http_request_t *r,
! ngx_http_variable_value_t *v, uintptr_t data)
! {
! char *val;
! size_t len;
! GeoIPRecord *gr;

  • gr = ngx_http_geoip_get_city_record(r);
    if (gr == NULL) {
        goto not_found;
    }
    

*** 241,246 ****
— 261,298 ----
return NGX_OK;
}

  • static ngx_int_t
  • ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
  • ngx_http_variable_value_t *v, uintptr_t data)
    
  • {
  • GeoIPRecord            *gr;
    
  • float                  float_val;
    
  • gr = ngx_http_geoip_get_city_record(r);
    
  • if (gr == NULL) {
    
  •     goto not_found;
    
  • }
    
  • v->data = ngx_pnalloc(r->pool, NGX_INT32_LEN + 10);
    
  • if (v->data == NULL) {
    
  •     GeoIPRecord_delete(gr);
    
  •     return NGX_ERROR;
    
  • }
    
  • float_val = *(float *) ((char *) gr + data);
    
  • v->len = ngx_sprintf(v->data, "%.4f", float_val) - v->data;
    
  • GeoIPRecord_delete(gr);
    
  • return NGX_OK;
    
  • not_found:
  • v->not_found = 1;
    
  • return NGX_OK;
    
  • }

static ngx_int_t
ngx_http_geoip_add_variables(ngx_conf_t *cf)

Posted at Nginx Forum:

Hi,

It says patch: **** malformed patch at line 7: ngx_http_variable_value_t
*v, uintptr_t data);

Can you please upload a patched version of the .c file or how can i fix
that issue ? Thanks.

Posted at Nginx Forum:

I recreated the patch on 0.8.28 and uploaded it to
http://xenon.stanford.edu/~arvind/ngx_http_geoip_module.c-patch.txt

(Not sure how to preserve formatting in pasting to this board and I
don’t see an upload mechanism).

Posted at Nginx Forum: