text: using System.Collections.Generic;
  using System.Net.Http;
  
  namespace Apress.Recipes.WebApi
  {
      public static class HttpRequestMessageExtensions
      {
          private const string HttpContext = "MS_HttpContext";
          private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
          private const string OwinContext = "MS_OwinContext";
          private const string OwinIp = "server.LocalIpAddress";
  
          public static string GetClientIpAddress(this HttpRequestMessage request)
          {
              if (request.Properties.ContainsKey(HttpContext))
              {
                  dynamic ctx = request.Properties[HttpContext];
                  if (ctx != null)
                  {
                      return ctx.Request.UserHostAddress;
                  }
              }
  
              if (request.Properties.ContainsKey(OwinContext))
              {
                  dynamic ctx = request.Properties[OwinContext];
                  if (ctx != null)
                  {
                      var env = ctx.Environment as IDictionary<string, object>;
                      if (env != null)
                      {
                          return env[OwinIp] as string;
                      }
                  }
              }
  
              if (request.Properties.ContainsKey(RemoteEndpointMessage))
              {
                  dynamic remoteEndpoint = request.Properties[RemoteEndpointMessage];
                  if (remoteEndpoint != null)
                  {
                      return remoteEndpoint.Address;
                  }
              }
  
              return null;
          }
      }
  }