[geocode-glib] server: Add GeoIP server
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geocode-glib] server: Add GeoIP server
- Date: Mon, 14 Jan 2013 07:01:18 +0000 (UTC)
commit 06b7deb28d255d3814aa66cf8dc8f98c86ce8d62
Author: Satabdi Das <satabdidas gmail com>
Date: Fri Jan 11 19:11:00 2013 +0530
server: Add GeoIP server
For use as a cgi-bin script for a web server.
configure.ac | 5 +
geocode-glib/Makefile.am | 2 +
geocode-glib/geocode-ip-server/Makefile.am | 13 ++
geocode-glib/geocode-ip-server/geoip-lookup.c | 236 +++++++++++++++++++++++++
4 files changed, 256 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a01ebed..bfa06ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -61,6 +61,10 @@ PKG_CHECK_MODULES(GEOCODE,
json-glib-1.0 >= 0.14
libsoup-2.4)
+# apart from the above GEOCODE packages, the server requires the following packages
+PKG_CHECK_MODULES(GEOCODE_SERVER,
+ geoip)
+
GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0`
AC_SUBST(GLIB_GENMARSHAL)
@@ -88,6 +92,7 @@ AC_CONFIG_FILES([
docs/version.xml
geocode-glib/Makefile
po/Makefile.in
+ geocode-glib/geocode-ip-server/Makefile
])
AC_OUTPUT
diff --git a/geocode-glib/Makefile.am b/geocode-glib/Makefile.am
index d742251..4630461 100644
--- a/geocode-glib/Makefile.am
+++ b/geocode-glib/Makefile.am
@@ -1,5 +1,7 @@
include $(top_srcdir)/Makefile.decl
+SUBDIRS = geocode-ip-server
+
EXTRA_DIST = geocode-glib.symbols
BUILT_GIRSOURCES =
diff --git a/geocode-glib/geocode-ip-server/Makefile.am b/geocode-glib/geocode-ip-server/Makefile.am
new file mode 100644
index 0000000..2de1265
--- /dev/null
+++ b/geocode-glib/geocode-ip-server/Makefile.am
@@ -0,0 +1,13 @@
+include $(top_srcdir)/Makefile.decl
+
+BUILT_GIRSOURCES =
+
+AM_CFLAGS = -I$(top_srcdir) $(GEOCODE_CFLAGS) $(GEOCODE_SERVER_CFLAGS) $(COMMON_CFLAGS) $(WARN_CFLAGS) $(DISABLE_DEPRECATED)
+
+TEST_PROGS += geoip-lookup
+noinst_PROGRAMS = $(TEST_PROGS)
+
+geoip_lookup_LDADD = $(GEOCODE_LIBS) $(GEOCODE_SERVER_LIBS)
+
+MAINTAINERCLEANFILES = Makefile.in
+
diff --git a/geocode-glib/geocode-ip-server/geoip-lookup.c b/geocode-glib/geocode-ip-server/geoip-lookup.c
new file mode 100644
index 0000000..5d35297
--- /dev/null
+++ b/geocode-glib/geocode-ip-server/geoip-lookup.c
@@ -0,0 +1,236 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+
+#include <GeoIP.h>
+#include <GeoIPCity.h>
+#include <glib.h>
+#include <json-glib/json-glib.h>
+#include <libsoup/soup.h>
+
+
+static const gchar *attribution_text = "This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com\n";
+
+enum ERROR_CODES {
+ PARSE_ERR = 0,
+ INVALID_DATA_ERR,
+ INVALID_IP_ADDRESS_ERR,
+ INVALID_ENTRY_ERR,
+ DATABASE_ERR
+};
+static char *error_message_array [] = {
+ "Can not parse the input",
+ "Invalid data",
+ "Invalid IP address format",
+ "Can not find the IP address in the database",
+ "Can not open the database. Set GEOIP_DATABASE_PATH env variable"
+};
+
+static void
+add_json_object_for_address (JsonBuilder *builder,
+ const char *name,
+ const char *code,
+ const char *type)
+{
+ if (!name && !code)
+ return;
+ json_builder_begin_object (builder);
+ if (name) {
+ json_builder_set_member_name (builder, "name");
+ json_builder_add_string_value (builder, name);
+ }
+ if (code) {
+ json_builder_set_member_name (builder, "code");
+ json_builder_add_string_value (builder, code);
+ }
+ json_builder_set_member_name (builder, "type");
+ json_builder_add_string_value (builder, type);
+ json_builder_end_object (builder);
+}
+
+static JsonBuilder*
+add_result_attr_to_json_tree (const char* ipaddress,
+ GeoIPRecord *gir)
+{
+ const char *timezone = NULL;
+ JsonBuilder *builder;
+
+ builder = json_builder_new ();
+
+ json_builder_begin_object (builder); /* begin */
+
+ json_builder_set_member_name (builder, "results");
+ json_builder_begin_object (builder); /* begin results object */
+
+ json_builder_set_member_name (builder, ipaddress);
+ json_builder_begin_array (builder); /* begin ipaddress array */
+
+ json_builder_begin_object (builder); /* begin ipaddress object */
+
+ json_builder_set_member_name (builder, "location");
+ json_builder_begin_object (builder); /* begin location object */
+ json_builder_set_member_name (builder, "latitude");
+ json_builder_add_double_value (builder, gir->latitude);
+ json_builder_set_member_name (builder, "longitude");
+ json_builder_add_double_value (builder, gir->longitude);
+ json_builder_end_object (builder); /* end location object */
+
+ json_builder_set_member_name (builder, "address");
+ json_builder_begin_array (builder); /* begin address array */
+
+ /* Before adding any entry check if that's NULL.
+ If NULL then don't add it to the JSON output.
+ */
+ add_json_object_for_address (builder, gir->city, NULL, "city");
+ add_json_object_for_address (builder,
+ GeoIP_region_name_by_code (gir->country_code, gir->region),
+ gir->region,
+ "region");
+ add_json_object_for_address (builder, NULL, gir->postal_code, "postalcode");
+ add_json_object_for_address (builder, gir->country_name, gir->country_code, "country");
+
+ json_builder_end_array (builder); /* end address array */
+
+ timezone = GeoIP_time_zone_by_country_and_region(gir->country_code, gir->region);
+ if (timezone) {
+ json_builder_set_member_name (builder, "timezone");
+ json_builder_add_string_value (builder, timezone);
+ }
+
+ json_builder_set_member_name (builder, "attribution");
+ json_builder_add_string_value (builder, attribution_text);
+
+ json_builder_end_object (builder); /* end ipaddress object */
+
+ json_builder_end_array (builder); /* end ipaddress array */
+
+ json_builder_end_object (builder); /* end results object */
+
+ json_builder_end_object (builder); /* end */
+
+ return builder;
+}
+
+static void
+print_json_data (JsonBuilder *builder)
+{
+ JsonNode *node;
+ JsonGenerator *generator;
+ gchar *json_data;
+ gsize length;
+
+ node = json_builder_get_root (builder);
+
+ generator = json_generator_new ();
+ json_generator_set_root (generator, node);
+ json_data = json_generator_to_data (generator, &length);
+ g_print ("%*s\n", (int)length, json_data);
+
+ g_free (json_data);
+ json_node_free (node);
+ g_object_unref (generator);
+}
+
+static void
+print_error_in_json (int error_code, const char *extra_info)
+{
+ g_print ("{\"results\":\"[error] %s",error_message_array[error_code]);
+ if (extra_info)
+ g_print (" - %s\"}\n", extra_info);
+ else
+ g_print ("\"}\n");
+}
+
+static void
+ip_addr_lookup (const gchar *ipaddress)
+{
+ GeoIP *gi;
+ GeoIPRecord *gir;
+ JsonBuilder *builder;
+ const gchar *db;
+
+ db = g_getenv ("GEOIP_DATABASE_PATH");
+ if (!db) {
+ print_error_in_json (DATABASE_ERR, NULL);
+ return;
+ }
+
+ gi = GeoIP_open (db, GEOIP_INDEX_CACHE);
+ if (gi == NULL) {
+ print_error_in_json (DATABASE_ERR, NULL);
+ return;
+ }
+
+ gir = GeoIP_record_by_addr (gi, ipaddress);
+ if (gir == NULL) {
+ print_error_in_json (INVALID_ENTRY_ERR, ipaddress);
+ GeoIP_delete (gi);
+ return;
+ }
+ /* Add the result attributes to the Json tree
+ at present only add the latitude and longitude
+ of the place*/
+ builder = add_result_attr_to_json_tree (ipaddress, gir);
+ print_json_data (builder);
+
+
+ g_object_unref (builder);
+ GeoIPRecord_delete (gir);
+ GeoIP_delete (gi);
+}
+
+static gchar *
+get_ipaddress (void)
+{
+ const gchar *data;
+ const gchar *value;
+ gchar *ipaddress;
+ GHashTable *table;
+ GInetAddress *inet_address;
+
+ data = g_getenv ("QUERY_STRING");
+ if (data == NULL) {
+ print_error_in_json (PARSE_ERR, NULL);
+ return NULL;
+ }
+
+ table = soup_form_decode (data);
+ value = g_hash_table_lookup (table, "ip");
+ if (!value) {
+ value = g_getenv ("REMOTE_ADDR");
+ if (!value) {
+ print_error_in_json (PARSE_ERR, NULL);
+ g_hash_table_destroy (table);
+ return NULL;
+ }
+ }
+
+ inet_address = g_inet_address_new_from_string (value);
+ if (!inet_address) {
+ print_error_in_json (INVALID_IP_ADDRESS_ERR, NULL);
+ g_hash_table_destroy (table);
+ return NULL;
+ }
+
+ ipaddress = g_strdup (value);
+ g_hash_table_destroy (table);
+ g_object_unref (inet_address);
+
+ return ipaddress;
+}
+
+int
+main (void)
+{
+ gchar *ipaddress;
+
+ g_type_init ();
+
+ g_print ("Content-type: text/plain;charset=us-ascii\n\n");
+ ipaddress = get_ipaddress ();
+ if (!ipaddress)
+ return 0;
+
+ ip_addr_lookup (ipaddress);
+
+ g_free (ipaddress);
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]