diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
index ee6191b4c2..284fee63d3 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
@@ -147,9 +147,8 @@ namespace OpenSim.Framework.Servers.HttpServer
public IPEndPoint RemoteIPEndPoint
{
- get { return _remoteIPEndPoint; }
+ get { return _request.RemoteIPEndPoint; }
}
- private IPEndPoint _remoteIPEndPoint;
public Uri Url
{
@@ -206,29 +205,6 @@ namespace OpenSim.Framework.Servers.HttpServer
if (null != req.Headers["user-agent"])
_userAgent = req.Headers["user-agent"];
- if (null != req.Headers["remote_addr"])
- {
- try
- {
- IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]);
- // sometimes req.Headers["remote_port"] returns a comma separated list, so use
- // the first one in the list and log it
- string[] strPorts = req.Headers["remote_port"].Split(new char[] { ',' });
- if (strPorts.Length > 1)
- {
- _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring",
- req.Headers["remote_addr"], req.Headers["remote_port"]);
- }
- int port = Int32.Parse(strPorts[0]);
- _remoteIPEndPoint = new IPEndPoint(addr, port);
- }
- catch (FormatException)
- {
- _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring",
- req.Headers["remote_addr"], req.Headers["remote_port"]);
- }
- }
-
// Form = new Hashtable();
// foreach (HttpInputItem item in req.Form)
// {
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs
index f6eb85da5d..338faaf1a3 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs
@@ -89,6 +89,8 @@ namespace OSHttpServer
///
public event EventHandler Started;
+ public IPEndPoint LocalRemoteEndPoint {get; set;}
+
///
/// Initializes a new instance of the class.
///
@@ -105,8 +107,7 @@ namespace OSHttpServer
if (!stream.CanWrite || !stream.CanRead)
throw new ArgumentException("Stream must be writable and readable.");
- RemoteAddress = remoteEndPoint.Address.ToString();
- RemotePort = remoteEndPoint.Port.ToString();
+ LocalRemoteEndPoint = remoteEndPoint;
_log = NullLogWriter.Instance;
m_parser = parserFactory.CreateParser(_log);
m_parser.RequestCompleted += OnRequestCompleted;
@@ -185,8 +186,8 @@ namespace OSHttpServer
m_currentRequest.Method = e.HttpMethod;
m_currentRequest.HttpVersion = e.HttpVersion;
m_currentRequest.UriPath = e.UriPath;
- m_currentRequest.AddHeader("remote_addr", RemoteAddress);
- m_currentRequest.AddHeader("remote_port", RemotePort);
+ m_currentRequest.AddHeader("remote_addr", LocalRemoteEndPoint.Address.ToString());
+ m_currentRequest.AddHeader("remote_port", LocalRemoteEndPoint.Port.ToString());
FirstRequestLineReceived = true;
TriggerKeepalive = false;
@@ -290,16 +291,6 @@ namespace OSHttpServer
set { m_stream = value; }
}
- ///
- /// Gets or sets IP address that the client connected from.
- ///
- internal string RemoteAddress { get; set; }
-
- ///
- /// Gets or sets port that the client connected from.
- ///
- internal string RemotePort { get; set; }
-
///
/// Disconnect from client
///
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpContextFactory.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpContextFactory.cs
index 8c5fb2c328..6937aa8e3e 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpContextFactory.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpContextFactory.cs
@@ -54,8 +54,7 @@ namespace OSHttpServer
context.Stream = stream;
context.IsSecured = isSecured;
- context.RemotePort = endPoint.Port.ToString();
- context.RemoteAddress = endPoint.Address.ToString();
+ context.LocalRemoteEndPoint = endPoint;
ContextTimeoutManager.StartMonitoringContext(context);
m_activeContexts[context.contextID] = context;
context.Start();
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequest.cs
index 96f55d2ca6..9a25402048 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequest.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Specialized;
using System.IO;
+using System.Net;
using System.Text;
using System.Web;
using OSHttpServer.Exceptions;
@@ -31,6 +32,7 @@ namespace OSHttpServer
private Uri m_uri = null;
private string m_uriPath;
public readonly IHttpClientContext m_context;
+ IPEndPoint m_remoteIPEndPoint = null;
public HttpRequest(IHttpClientContext pContext)
{
@@ -268,6 +270,33 @@ namespace OSHttpServer
{
Cookies = cookies;
}
+
+ public IPEndPoint RemoteIPEndPoint
+ {
+ get
+ {
+ if(m_remoteIPEndPoint == null)
+ {
+ string addr = m_headers["x-forwarded-for"];
+ if(!string.IsNullOrEmpty(addr))
+ {
+ int port = m_context.LocalRemoteEndPoint.Port;
+ try
+ {
+ m_remoteIPEndPoint = new IPEndPoint(IPAddress.Parse(addr), port);
+ }
+ catch
+ {
+ m_remoteIPEndPoint = null;
+ }
+ }
+ }
+ if (m_remoteIPEndPoint == null)
+ m_remoteIPEndPoint = m_context.LocalRemoteEndPoint;
+
+ return m_remoteIPEndPoint;
+ }
+ }
/*
///
/// Create a response object.
@@ -306,8 +335,7 @@ namespace OSHttpServer
AcceptTypes[i] = AcceptTypes[i].Trim();
break;
case "content-length":
- int t;
- if (!int.TryParse(value, out t))
+ if (!int.TryParse(value, out int t))
throw new BadRequestException("Invalid content length.");
ContentLength = t;
break; //todo: maybe throw an exception
@@ -323,11 +351,44 @@ namespace OSHttpServer
}
break;
case "remote_addr":
- // to prevent hacking (since it's added by IHttpClientContext before parsing).
if (m_headers[name] == null)
m_headers.Add(name, value);
break;
+ case "forwarded":
+ string[] parts = value.Split(new char[]{';'});
+ string addr = string.Empty;
+ for(int i = 0; i < parts.Length; ++i)
+ {
+ string s = parts[i].TrimStart();
+ if(s.Length < 10)
+ continue;
+ if(s.StartsWith("for", StringComparison.InvariantCultureIgnoreCase))
+ {
+ int indx = s.IndexOf("=", 3);
+ if(indx < 0 || indx >= s.Length - 1)
+ continue;
+ s = s.Substring(indx);
+ addr = s.Trim();
+ }
+ }
+ if(addr.Length > 7)
+ {
+ m_headers.Add("x-forwarded-for", addr);
+ }
+ break;
+ case "x-forwarded-for":
+ if (value.Length > 7)
+ {
+ string[] xparts = value.Split(new char[]{','});
+ if(xparts.Length > 0)
+ {
+ string xs = xparts[0].Trim();
+ if(xs.Length > 7)
+ m_headers.Add("x-forwarded-for", xs);
+ }
+ }
+ break;
case "connection":
if (string.Compare(value, "close", true) == 0)
Connection = ConnectionType.Close;
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/IHttpClientContext.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/IHttpClientContext.cs
index 2dc11e19d4..99ae8d7dba 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/IHttpClientContext.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/IHttpClientContext.cs
@@ -16,6 +16,8 @@ namespace OSHttpServer
///
string SSLCommonName { get; }
+ IPEndPoint LocalRemoteEndPoint {get; set;}
+
///
/// Using SSL or other encryption method.
///
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/IHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/IHttpRequest.cs
index 36525828c0..5d43aa55b7 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/IHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/IHttpRequest.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Specialized;
using System.IO;
+using System.Net;
using OSHttpServer.Exceptions;
namespace OSHttpServer
@@ -8,7 +9,7 @@ namespace OSHttpServer
///
/// Contains server side HTTP request information.
///
- public interface IHttpRequest : ICloneable
+ public interface IHttpRequest
{
///
/// Gets kind of types accepted by the client.
@@ -134,5 +135,7 @@ namespace OSHttpServer
///
/// The cookies.
void SetCookies(RequestCookies cookies);
+
+ IPEndPoint RemoteIPEndPoint { get; }
}
}
\ No newline at end of file