Code Monkey home page Code Monkey logo

maxmind-db-reader-dotnet's Introduction

MaxMind DB Reader

NuGet API Docs

Description

This is the .NET API for reading MaxMind DB files. MaxMind DB is a binary file format that stores data indexed by IP address subnets (IPv4 or IPv6).

Installation

NuGet

We recommend installing this library with NuGet. To do this, type the following into the Visual Studio Package Manager Console:

install-package MaxMind.Db

Usage

Note: For accessing MaxMind GeoIP2 databases, we generally recommend using the GeoIP2 .NET API rather than using this package directly.

To use the API, you must first create a Reader object. The constructor for the reader object takes a string with the path to the MaxMind DB file. Optionally you may pass a second parameter with a FileAccessMode enum with the value MemoryMapped or Memory. The default mode is MemoryMapped, which maps the file to virtual memory. This often provides performance comparable to loading the file into real memory with the Memory mode while using significantly less memory.

To look up an IP address, pass a System.Net.IPAddress object to the Find<T> method on Reader. This method will return the result as type T. T may either be a generic collection or a class using the [MaxMind.Db.Constructor] attribute to declare which constructor to use during deserialization and the [MaxMind.Db.Parameter("name")] to map the database key name to a particular constructor parameter.

We recommend reusing the Reader object rather than creating a new one for each lookup. The creation of this object is relatively expensive as it must read in metadata for the file.

Example Decoding to a Dictionary

using (var reader = new Reader("GeoIP2-City.mmdb"))
{
    var ip = IPAddress.Parse("24.24.24.24");
    var data = reader.Find<Dictionary<string, object>>(ip);
    ...
}

Example Decoding to a Model Class

using MaxMind.Db;
using System.Net;

namespace MyCode
{
    public class Asn
    {
        [Constructor]
        public AsnResponse(
            // The Parameter attribute tells the reader to map the database
            // key to the specified constructor parameter.
            [Parameter("autonomous_system_number")] long? autonomousSystemNumber,
            [Parameter("autonomous_system_organization")] string autonomousSystemOrganization,

            // The Inject attribute allows you to inject arbitrary values
            // when deserializing.
            [Inject("ip_address")] IPAddress ipAddress),

            // The Network attribute tells the reader to set the constructor
            // parameter to be the network associated with the record in the
            // database.
            [Network] Network network
        {
          ...
        }

        ...
    }


    public class Program
    {
        private static void Main(string[] args)
        {
            using (var reader = new Reader("GeoLite2-ASN.mmdb"))
            {
                var ip = IPAddress.Parse("24.24.24.24");
                var injectables = new InjectableValues();
                injectables.AddValue("ip_address", ip);
                var data = reader.Find<Asn>(ip, injectables);
                ...
            }
        }
    }
}

Multi-Threaded Use

This API fully supports use in multi-threaded applications. In such applications, we suggest creating one Reader object and sharing that among threads.

Format

The MaxMind DB format is an open format for quickly mapping IP addresses to records. See the specification for more information on the format.

Bug Tracker

Please report all issues with this code using the GitHub issue tracker.

If you are having an issue with a MaxMind database or service that is not specific to this reader, please contact MaxMind support.

Contributing

Patches and pull requests are encouraged. Please include unit tests whenever possible.

Versioning

The MaxMind DB Reader API uses Semantic Versioning.

Copyright and License

This software is Copyright (c) 2013-2022 by MaxMind, Inc.

This is free software, licensed under the Apache License, Version 2.0.

maxmind-db-reader-dotnet's People

Contributors

2shortplanks avatar am11 avatar andyjack avatar autarch avatar bmsullivan avatar borisz avatar coolkev avatar dependabot-preview[bot] avatar dependabot[bot] avatar eilara avatar faktas2 avatar horgh avatar jjxtra avatar maartenba avatar oschwald avatar quppa avatar rafl avatar sarus avatar shadromani avatar ugexe avatar wesrice avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

maxmind-db-reader-dotnet's Issues

IOException when using Parallel

Hi everyone,

I've been using MaxMind GeoIP2 for .NET from Nuget to process IP addresses but kept getting an IOException - 'IOException: Not enough storage is available to process this command'.

I downloaded the source code and did some sleuthing, and the problem appears to be with the use of ThreadLocal in MaxMind.Db.Reader. ThreadLocal creates a new Stream every time a new thread uses the Reader but the Streams are not cleaned up until the entire Reader is disposed. ThreadLocal does not seems to have any capabilities to dispose dormant values until the entire object is collected.

I have been using Parallel.ForEach to give my code multithreading so I have no direct access to the threads, but it is clear that .NET has has no bias to reusing threads. As you can see from the screenshot this exception occurred after initialising 45 separate Streams.

This problem only occurred for me on 32 bit builds after 10 - 30 minutes. 64 bit builds didn't crash over the several hours I tested, although I suspect the same exception would happen eventually. As I intend to run this program over several days I want the code to be as solid as possible.

For now I've worked around the problem by managing my own threads, although I'd like to use the Parallel.ForEach again if a fix is available.

Let me know if you need any more information.
Thanks,
Tom
maxmindexception

Registered Country

The CountryResponse does not contain a valid/meaningful RegisteredCountry property.

var dbfile = "GeoIP2-Country.mmdb";
DatabaseReader reader = new DatabaseReader(dbfile);

CountryResponse countryResponse;
if (reader.TryCountry("8.8.8.8", out countryResponse))
{
Console.WriteLine("Country ISO code: " + countryResponse.Country.IsoCode);
Console.WriteLine("RegisteredCountry ISO code: " + countryResponse.RegisteredCountry.IsoCode);
}
else
{
Console.WriteLine("error in db query");
}

countryResponse.RegisteredCountry.IsoCode is null but should be set to "US" in this case.

MaxMind.Db 2.1.1 Strong name signature could not be verified

After updating to MaxMind.GeoIP2 2.7 and MaxMind.Db 2.1.1 in my ASP.NET MVC 5 application, I get the following error:

Could not load file or assembly MaxMind.Db' or one of its dependencies. Strong name signature could not be verified. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key

The error went away when I downgraded to MaxMind.GeoIP2 2.6 and MaxMind.Db 2.0.0.

Featuring NetCore (CoreCLR) port

Hello,

I have ported this lib to CoreCLR: https://github.com/am11/MaxMind-DB-Reader-dotnet/tree/coreclr-port.

At the moment, it builds with latest dotnet/cli (https://github.com/dotnet/cli#installers-and-binaries) and VS15 preview only; as VS14.2 (sometimes known as: VS2015 Update 2) does not have CLI support yet https://github.com/dotnet/cli/issues/1556.

To build this with dotnet/cli in text mode (without VS15 preview) using Windows Command Prompt:

  • First download and install Windows binary https://github.com/dotnet/cli#installers-and-binaries
  • git clone https://github.com/am11/MaxMind-DB-Reader-dotnet -b coreclr-port
  • cd MaxMind-DB-Reader-dotnet
  • cd MaxMind.DB
  • dotnet restore && dotnet build
  • cd ..\MaxMind.Benchmark
  • dotnet restore && dotnet build

To run benchmark with net451 TFM CLR:

  • dotnet run -f net451

To run benchmark with CoreCLR:

  • dotnet run -f netcoreapp1.0 or simply dotnet run (as netcoreapp1.0 target framework moniker is default in dotnet CLI)

Random notes: ๐Ÿ˜บ

  • .csprojs are replaced with .xproj.
  • The library project has netstandard1.4 TFM, while benchmark and test are Console projects, aka netcoreapp using netcoreapp1.0 TFM.
  • There are imports statements in all three PJs (project.jsons), which would probably be deprecated once the long overdue dotner-core RC2 is out.
  • Test project is Console app because the Nunit-lite runner requires it to be a console project (http://www.alteridem.net/2015/11/04/testing-net-core-using-nunit-3/ <- the difference is I changed the main signature to static Main so to emit a pure console app).
    • Tip: to make any lib / dll-emitting xproj to exe-emitting xproj, add "buildOptions": { "emitEntryPoint": true },line inproject.jsonand acquire dependency onSystem.Console`.
  • I used https://github.com/microsoft/dotnet-apiport and https://github.com/dotnet/corefx as reference point for all the #if-#elif preprocessor directive changes to satisfy NetCore std surface area.

Sad part: ๐Ÿ˜ฟ

  • While all three projects succeed dotnet restore ; dotnet build and Benchmark runs fine with dotnet run for netcoreapp1.0 moniker, I get error similar to #4 when I execute the test project with dotnet run. Seems like the mmdb file in TestData/ directory is corrupted.

If this is acceptable progress, I can add TFM for mono and Unices' runtimes in project.jsons and send a PR. ๐Ÿš€

Otherwise ๐Ÿ’ก, feel free to cherry-pick and use as you see fit. My ultimate interest is to run GeoIP2-dotnet under CoreCLR, for which I have some local patches awaiting DB-Reader dependency ready for CoreCLR.

Thanks for your patience. ๐Ÿฌ

Database contains a non-string as map key: Uint16

Using this database:

{
  "BinaryFormatMajorVersion": 2,
  "BinaryFormatMinorVersion": 0,
  "BuildDate": "2018-08-07T23:25:47Z",
  "DatabaseType": "GeoLite2-City",
  "Description": {
    "en": "GeoLite2 City database"
  },
  "IPVersion": 6,
  "Languages": [
    "de",
    "en",
    "es",
    "fr",
    "ja",
    "pt-BR",
    "ru",
    "zh-CN"
  ]
}

When i call this in version 3.0.0 of MaxMind.GeoIP2 nuget package:
using (var db = new DatabaseReader(_db.FullName)) { return db.City("216.206.142.2"); }
I get this exception:

{MaxMind.Db.InvalidDatabaseException: Database contains a non-string as map key: Uint16
   at MaxMind.Db.Decoder.DecodeKey(Int64 offset, Int64& outOffset)
   at MaxMind.Db.Decoder.DecodeMapToType(Type expectedType, Int64 offset, Int32 size, Int64& outOffset, InjectableValues injectables)
   at MaxMind.Db.Decoder.DecodeByType(Type expectedType, ObjectType type, Int64 offset, Int32 size, Int64& outOffset, InjectableValues injectables)
   at MaxMind.Db.Decoder.DecodeByType(Type expectedType, ObjectType type, Int64 offset, Int32 size, Int64& outOffset, InjectableValues injectables)
   at MaxMind.Db.Decoder.Decode[T](Int64 offset, Int64& outOffset, InjectableValues injectables)
   at MaxMind.Db.Reader.ResolveDataPointer[T](Int32 pointer, InjectableValues injectables)
   at MaxMind.Db.Reader.Find[T](IPAddress ipAddress, Int32& prefixLength, InjectableValues injectables)
   at MaxMind.Db.Reader.Find[T](IPAddress ipAddress, InjectableValues injectables)
   at MaxMind.GeoIP2.DatabaseReader.Execute[T](String ipStr, IPAddress ipAddress, String type, Boolean throwOnNullResponse)
   at MaxMind.GeoIP2.DatabaseReader.City(IPAddress ipAddress)
   at LGPlayersService.Services.GeoIPDatabase.ResolveIPAddress(IPAddress ip)

This just started happening after I updated to the latest database

case statement perf in DecodeByType

I added an array of counters to the DecodeByType function, one for each ObjectType, and noticed that the vast majority of values decoded are strings when using the GeoIP2-City.mmdb file. You can save a lot of branches if ObjectType.Utf8String is the first case checked. It doesn't make a lot of difference when you're looking up one IP at a time, but when you're looking up millions at a time it's pretty noticeable (almost half an hour shaved over 30MM lookups when passing the file in as a memory stream).

Reading GeoLiteCity.dat

The Reader creates exception "Could not find a MaxMind Db metadata marker in this file"
Is there another utility to read GeoLitCity.dat file directly

.Net Core

Is it possible to have this library .Net Core compatible ?

Feedback for Travis CI C# support

Hey, I'm one of the contributors of the Travis CI C# support and saw that you enabled it on your repository.

I'd be really interested to hear how your experience was. Is the documentation easy to understand? Can we improve something? Did you encounter any problems?

Thanks for your time ๐Ÿ˜„

How simply read lat and lon?

Hello

using (var reader = new Reader("GeoIP2-City.mmdb"))
{
    var ip = IPAddress.Parse("24.24.24.24");
    var data = reader.Find<Dictionary<string, object>>(ip);
    ...
   what here?
}

i try somthing like:

foreach (KeyValuePair<string, object> author in data)
{
    Console.WriteLine(author.Key+"="+ author.Value.ToString());
}

but the result is anoother dictionary, how get lat and lon?

sincerely giancarlo

Reader performance

I did a mini code review of your code and I'm not sure what specifically is going on, but I'll describe the behavior that I'm seeing. I have some geo tests that have a time assert on them. After moving from the reader overload that reads the file from disk and puts it in memory to reading it from a stream the time to return the same city location has doubled. With no other changes to my code.

Decoder.DecodePointer() unclear ternary op

Decoder.DecodePointer() contains this code:

var b = pointerSize == 4 ? 0 : size & 0x7;

This code would be easier to read if it had composite parts of ternary op enclosed in braces:

var b = (pointerSize == 4) ? 0 : (size & 0x7);

Version 1.1.0 and 1.2.0 fail to compile with Mono

Not sure why https://build.opensuse.org/package/show/games:openra/maxmind-db

[   19s]        Target CoreCompile:
[   19s]                Tool /usr/lib/mono/4.5/mcs.exe execution started with arguments: /noconfig /debug:full /debug+ /keyfile:../MaxMind.snk /optimize- /out:obj/Debug/MaxMind.Db.dll Decoder.cs ArrayReader.cs GlobalSuppressions.cs IByteReader.cs InvalidDatabaseException.cs MemoryMapReader.cs Reader.cs Metadata.cs Properties/AssemblyInfo.cs obj/Debug/.NETFramework,Version=v4.5.AssemblyAttribute.cs /target:library /define:"DEBUG;TRACE" /nostdlib /reference:/usr/lib/mono/gac/Newtonsoft.Json/7.0.0.0__b9a188c8922137c6/Newtonsoft.Json.dll /reference:/usr/lib/mono/4.5/System.dll /reference:/usr/lib/mono/4.5/System.Numerics.dll /reference:/usr/lib/mono/4.5/System.Xml.Linq.dll /reference:/usr/lib/mono/4.5/System.Data.DataSetExtensions.dll /reference:/usr/lib/mono/4.5/System.Data.dll /reference:/usr/lib/mono/4.5/System.Xml.dll /reference:/usr/lib/mono/4.5/System.Core.dll /reference:/usr/lib/mono/4.5/mscorlib.dll /warn:4
[   19s] MemoryMapReader.cs(22,27): error CS1056: Unexpected character `$'
[   19s] MemoryMapReader.cs(22,57): error CS1525: Unexpected symbol `\'
[   19s] MemoryMapReader.cs(29,37): error CS1525: Unexpected symbol `when', expecting `{' or `if'
[   19s] MemoryMapReader.cs(30,16): error CS1525: Unexpected symbol `{'
[   19s]        Task "Csc" execution -- FAILED
[   19s]        Done building target "CoreCompile" in project "/home/abuild/rpmbuild/BUILD/MaxMind-DB-Reader-dotnet-1.2.0/MaxMind.Db/MaxMind.Db.csproj".-- FAILED
[   19s] Done building project "/home/abuild/rpmbuild/BUILD/MaxMind-DB-Reader-dotnet-1.2.0/MaxMind.Db/MaxMind.Db.csproj".-- FAILED
[   19s] 
[   19s] Build FAILED.
[   19s] Errors:
[   19s] 
[   19s] /home/abuild/rpmbuild/BUILD/MaxMind-DB-Reader-dotnet-1.2.0/MaxMind.Db/MaxMind.Db.csproj (default targets) ->
[   19s] /usr/lib/mono/4.5/Microsoft.CSharp.targets (CoreCompile target) ->
[   19s] 
[   19s]        MemoryMapReader.cs(22,27): error CS1056: Unexpected character `$'
[   19s]        MemoryMapReader.cs(22,57): error CS1525: Unexpected symbol `\'
[   19s]        MemoryMapReader.cs(29,37): error CS1525: Unexpected symbol `when', expecting `{' or `if'
[   19s]        MemoryMapReader.cs(30,16): error CS1525: Unexpected symbol `{'

See also https://bugzilla.redhat.com/show_bug.cgi?id=1270525

Publishing a new beta 3 version on nuget?

Hello,

We're interested in using the latest PR you accepted to get access to an IPs routing prefix. I wanted to check and see if you would be willing to publish a beta version on nuget or if you think this will hit 2.0 release soon and be made generally available. We're actually using GeoIP2-dotnet rather than the DB reader directly right now but we're willing to use both to get the routing prefix info until a version of GeoIP2-dotnet is released that includes the latest DB reader.

If you think it'll be a while before the beta version is available via Nuget that is not a problem and we'll build a version ourselves until he official version is available. I just wanted to get a sense of timing so we know which option to pursue.

Thank you!

UnauthorizedAccessException when accessing same memory mapped file from separate IIS AppPools

Here is the exception:

[UnauthorizedAccessException: Access to the path is denied.]
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +634
System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(String mapName, HandleInheritability inheritability, Int32 desiredAccessRights, Boolean createOrOpen) +102
System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability) +119
MaxMind.Db.MemoryMapBuffer..ctor(String file, FileInfo fileInfo) +344
MaxMind.Db.Reader.BufferForMode(String file, FileAccessMode mode) +144
MaxMind.GeoIP2.DatabaseReader..ctor(String file, IEnumerable`1 locales, FileAccessMode mode) +91

I have confirmed it is not a permissions issue, and it works fine when using FileAccessMode.Memory.

The problem only occurs when the second app pool (running under a different identity) tries to open the memory mapped file.

Returning parent block of an IP

Hello,

I posted a related issue (maxmind/GeoIP2-dotnet#54) over on the GeoIP2-dotnet github issue tracker and it was suggested to submit a PR to this repo to add the ability to get the network block for an IP.

I'm looking over the code now and wanted to see how you'd like to expose this functionality. I could see adding a method like this

public T FindWithBlock<T>(IPAddress ipAddress, InjectableValues injectables = null) where T : class

Which would inject a new block attribute into the returned data so usage would be something like:

    public class GeoIP2Block
    {
        public string Block;

        [Constructor]
        public GeoIP2Block([InjectAttribute("block")] string block)
        {
            Block = block;
        }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            using (var reader = new Reader("GeoLite2-City.mmdb", FileAccessMode.Memory))
            {
                var result = reader.FindWithBlock<GeoIP2Block>(IPAddress.Parse("1.188.0.56"));
                Console.WriteLine(result.Block);
                // result.Block in this example would be "1.188.0.0/14"
            }
        }
}

The other option would be to create a method specific to returning the block data

public string GetIpBlock(IPAddress ip);

Which would just return the block. Rather than return just a string representation of the block I would probably include other information. I could see returning the IP address and the routing prefix separately and maybe the range as well:

public IPGeoBlock GetIpBlock(IPAddress ip);
//IpGeoBlock would contain:
block: 1.188.0.0/14
ip: 1.188.0.0
routingPrefix: 14
start: 29097984
end: 29360127

Maybe instead of start and end integers use a byte array?

Thanks for your feedback! Happy to submit a PR once I know which direction to go in.

Mockable Metadata

Hi,

Is there any chance to define the Metadata property also on the IGeoIP2DatabaseReader interface?
It would serve well in unit testing.

No close method in Reader

Hi guys,
in your example you use the following code:
var reader = new Reader("GeoIP2-City.mmdb");
var response = reader.Find("24.24.24.24");
Console.WriteLine(response.ToString());
reader.close();
But your class Reader provides no method 'close'. I have changed the example a bit to help the developers to better understand the usage of your lib.
Here is my code:

        using (var reader = new Reader("DB/GeoLite2-City.mmdb"))
        {
            JToken response = reader.Find("24.24.24.24");                
            var city_de =
                JObject.Parse(response.ToString())
                            .SelectToken("city")
                            .SelectToken("names")
                            .Select(l => (string) l).ToList();
            Console.WriteLine(city_de.FirstOrDefault());

            JObject cc = JObject.Parse(response.ToString());                
            var state = (string)cc.SelectToken("subdivisions[0].names.en");
            Console.WriteLine(state);

            string country = (string)cc.SelectToken("country.names.en");
            Console.WriteLine(country);

            string continent = (string)cc.SelectToken("continent.names.en");
            Console.WriteLine(continent);
        }

Regards
Christoph

MaxMind.Db.InvalidDatabaseException: Could not find a MaxMind Db metadata marker in this file (). Is this a valid MaxMind Db file?

I'm downloading and extracting (http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz) and loading the file from a stream. This works in .net 4.7. However when I run the same code on netcoreapp2.0 using the latest dependency I get the following exception.

[12/03/2017 00:30:37 > d55c6a: INFO] MaxMind.Db.InvalidDatabaseException: Could not find a MaxMind Db metadata marker in this file (). Is this a valid MaxMind Db file?
[12/03/2017 00:30:37 > d55c6a: INFO]    at MaxMind.Db.Reader.FindMetadataStart()
[12/03/2017 00:30:37 > d55c6a: INFO]    at MaxMind.Db.Reader..ctor(Buffer buffer)
[12/03/2017 00:30:37 > d55c6a: INFO]    at MaxMind.GeoIP2.DatabaseReader..ctor(Stream stream, IEnumerable`1 locales)
[12/03/2017 00:30:37 > d55c6a: INFO]    at MaxMind.GeoIP2.DatabaseReader..ctor(Stream stream)
[12/03/2017 00:30:37 > d55c6a: INFO]    at Exceptionless.Core.Geo.MaxMindGeoIpService.<GetDatabaseAsync>d__8.MoveNext() in 

issue - powershell-core

Works fine in powershell 5.1.
However, in version 7.1 of the PowerShell-core, the following error occurs.

'[MaxMind.Db.Reader]::new($Database)
Exception calling ".ctor" with "1" argument(s): "Could not load type 'System.IO.MemoryMappedFiles.MemoryMappedFileSecurity' from
| assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'."

Slow memory leak.

We are seeing a slow memory leak when using MaxMind GeoIP.
The underlying call uses Reader.

48 Hours

We are retaining the DatabaseReader as an instance for re-use. But for some reason there is a high amount of array retention when profiled.

As you can see in the chart, it's a very slow leak that is easy to miss if not monitored. Over time, this leak will consume memory until eventually an alert is triggered.

And to be sure, multiple people have looked over our code and there is no obvious point where we ourselves could be leaking. The pathway is synchronous and simply passes an IP and subsequently gets a city or country.

Iterate all records

There is no way to do a foreach (var item in reader) {} without writing code against the maxmind binary format, which in my opinion is a waste of time.

This would be very helpful for building custom data structures, such as a country with it's list of ip ranges.

Data Mismatch Between .NET Reader and the mmdbinspect tool

Hello! Been working with Maxmind support regarding a discrepancy in the information returned by the .NET Reader, the mmdbinspect tool and the demo website at https://www.maxmind.com/en/geoip-demo.

Specifically, 147.161.215.112 has a country and location value of Australia for both the mmdbinspect tool and the demo site. Both also report a registered country of Switzerland. However, running it through the .NET Reader, it is reporting the country, location and registered country as Switzerland.

I have confirmed I am using the latest version (even pulled the source code down to run locally) of the reader as well as the latest GeoIP2 -City.mmdb file.

Any ideas why this discrepancy might be occurring?

New release

Are there plans to do a new release soon-ish? There's a few changes that have been merged that would be useful to us.

Re-reading mmdb file

What is the proper way to re-read a mmdb file for a running application without restarting it?

// Initializing the reader
var reader = new Reader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "conf//GeoLite2-ASN.mmdb"));

// Somewhere in the code, GeoLite-ASN.mmdb has changed, we want to reload it.
reader.Dispose();
reader = new Reader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "conf//GeoLite2-ASN.mmdb"));

Is this the way to go?

System.IO.IOException: The process cannot access the file 'D:\home\site\wwwroot\Content\GeoLite2-City.mmdb' because it is being used by another process.

I am building ASP.NET MVC 5 application and I ninject the reader into my service with the following code:
kernel.Bind(typeof(Reader)).ToSelf().InSingletonScope().WithConstructorArgument("file", ninject => HttpContext.Current.Server.MapPath("/Content/GeoLite2-City.mmdb"));

I am making it into a singleton following the advice to "creating one Reader object and sharing that among threads".

Now when I deploy it to azure it sometimes causes IOException and freezes the server, because it's not able to construct a Controller with this service, due to file being used by another process.

I am not sure if that a bug or if I'm not using it correctly.

Support reading .gz file directly

Could you add support for reading the .gz file directly (without having to decompress first)?

I've done similar in one of my projects. The change involves not very much more than wrapping the stream in a GZipStream.

So instead of writing:

using (var reader = new Reader("GeoIP2-City.mmdb"))

I could write:

using (var reader = new Reader("GeoIP2-City.mmdb.gz"))

The same can, currently, be achieved with the following:

using (var fs = File.OpenRead("GeoIP2-City.mmdb.gz"))
using (var gs = new GZipStream(fs, CompressionMode.Decompress))
using (var r = new Reader(gs))
{
    // ...
}

But this bypasses the ArrayBuffer or MemoryMapBuffer, both of which are internal.
This is not true; the ctor involved passes it on to an ArrayBuffer which I didn't notice at first.

You could:

  • 'autodetect' wether it's a gz file by
    • (simple) looking at the filename (e.g. .EndsWith(".gz"))
    • looking for a signature (first three bytes should be 1F 8B 08)
  • add an (optional, defaulting to "plain" or "autodetect") enum argument specifying the desired type (like this)

or a combination of the above (where you add another enum value besided Plain and GZip; like AutoDetect).

I'm willing to implement it and make a PR; I'm not (that) familiar with this codebase yet so that might take a little while.

Async Support?

It would be nice to be able to create a DatabaseReader async.

Fast country name request

Hi,
can you suggest please the most speed efficient way to access the country name info?

I'm using the following code:

                var ip = IPAddress.Parse(ip_address);
                var data = reader.Find<Dictionary<string, object>>(ip);

                if (data == null) return "";
                if (!data.ContainsKey("country")) return "";
                if (data["country"] == null) return "";

                Dictionary<string, object> country = (Dictionary<string, object>)data["country"];
                Dictionary<string, object> namesCountry = (Dictionary<string, object>)country["names"];

                if (namesCountry["en"] == null) return "";
                return namesCountry["en"].ToString();

Can we simplify something to be both fast and safe?

Also, perhaps, you may want to append your code snippet on the main page of the project (for ease of use by newcomers)?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.