From a1f34090326d6d567aecb2052ec4ba0b6c4f52e2 Mon Sep 17 00:00:00 2001
From: Dr Scofield
Date: Mon, 6 Oct 2008 19:42:03 +0000
Subject: cleaning up OSHttpRequest removing old Http stuff. also adding test
case for OSHttpRequest (not very fancy yet, but still).
---
OpenSim/Framework/Servers/BaseHttpServer.cs | 186 +------------------
OpenSim/Framework/Servers/OSHttpRequest.cs | 216 +++++++++--------------
OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs | 7 +-
3 files changed, 92 insertions(+), 317 deletions(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs
index 2c0cb5c..d1c22d6 100644
--- a/OpenSim/Framework/Servers/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/BaseHttpServer.cs
@@ -103,120 +103,13 @@ namespace OpenSim.Framework.Servers
{
m_ssl = ssl;
m_port = port;
+
if (m_ssl)
{
- //SetupSsl((int)sslport, CN);
m_sslport = sslport;
}
}
-
- /*
- *
- public bool SetupSsl(int port, string CN)
- {
- string searchCN = Environment.MachineName.ToUpper();
-
- if (CN.Length > 0)
- searchCN = CN.ToUpper();
-
- m_SSLCommonName = searchCN;
-
- Type t = Type.GetType("Mono.Runtime");
- if (t != null)
- {
- // TODO Mono User Friendly HTTPS setup
- // if this doesn't exist, then mono people can still manually use httpcfg
- }
- else
- {
- // Windows.
- // Search through the store for a certificate with a Common name specified in OpenSim.ini.
- // We need to find it's hash so we can pass it to httpcfg
- X509Store store = new X509Store(StoreLocation.LocalMachine);
- //Use the first cert to configure Ssl
- store.Open(OpenFlags.ReadOnly);
- //Assumption is we have certs. If not then this call will fail :(
- try
- {
- bool found = false;
- //X509Certificate2.CreateFromCertFile("testCert.cer");
-
- foreach (X509Certificate2 cert in store.Certificates)
- {
- String certHash = cert.GetCertHashString();
- //Only install certs issued for the machine and has the name as the machine name
- if (cert.Subject.ToUpper().IndexOf(searchCN) >= 0)
- {
- string httpcfgparams = String.Format("set ssl -i 0.0.0.0:{1} -c \"MY\" -h {0}", certHash, port);
- try
- {
- found = true;
-
- ExecuteHttpcfgCommand(httpcfgparams);
-
- break;
- }
- catch (Exception e)
- {
- m_log.WarnFormat("[HTTPS]: Automatic HTTPS setup failed. Do you have httpcfg.exe in your path? If not, you can download it in the windowsXP Service Pack 2 Support Tools, here: http://www.microsoft.com/downloads/details.aspx?FamilyID=49ae8576-9bb9-4126-9761-ba8011fabf38&displaylang=en. When you get it installed type, httpcfg {0} - {1}", httpcfgparams, e);
- return false;
- }
- }
- }
-
- if (!found)
- {
- m_log.WarnFormat("[HTTPS]: We didn't find a certificate that matched the common name {0}. Automatic HTTPS setup failed, you may have certificate errors. To fix this, make sure you generate a certificate request(CSR) using OpenSSL or the IIS snap-in with the common name you specified in opensim.ini. Then get it signed by a certification authority or sign it yourself with OpenSSL and the junkCA. Finally, be sure to import the cert to the 'MY' store(StoreLocation.LocalMachine)", searchCN);
- return false;
- }
-
- }
- catch (Exception e)
- {
- m_log.WarnFormat("[HTTPS]: We didn't any certificates in your LocalMachine certificate store. Automatic HTTPS setup failed, you may have certificate errors. To fix this, make sure you generate a certificate request(CSR) using OpenSSL or the IIS snap-inwith the common name you specified in opensim.ini. Then get it signed by a certification authority or sign it yourself with OpenSSL and the junkCA. Finally, be sure to import the cert to the 'MY' store(StoreLocation.LocalMachine). The configured common name is {0} - {1}", searchCN, e);
- return false;
- }
- finally
- {
- if (store != null)
- {
- store.Close();
- }
- }
- }
- return true;
- }
-
- private void ExecuteHttpcfgCommand(string p)
- {
-
- string file = "httpcfg";
-
- ProcessStartInfo info = new ProcessStartInfo(file, p);
- // Redirect output so we can read it.
- info.RedirectStandardOutput = true;
- // To redirect, we must not use shell execute.
- info.UseShellExecute = false;
-
- // Create and execute the process.
- Process httpcfgprocess = Process.Start(info);
- httpcfgprocess.Start();
- string result = httpcfgprocess.StandardOutput.ReadToEnd();
- if (result.Contains("HttpSetServiceConfiguration completed with"))
- {
- //success
-
- }
- else
- {
- //fail
- m_log.WarnFormat("[HTTPS]:Error binding certificate with the requested port. Message:{0}", result);
- }
-
- }
- */
-
///
/// Add a stream handler to the http server. If the handler already exists, then nothing happens.
///
@@ -311,81 +204,6 @@ namespace OpenSim.Framework.Servers
return true;
}
- ///
- /// HttpListener Handle an individual http request. This method is given to a worker in the thread pool.
- ///
- ///
- public virtual void HandleRequest(Object stateinfo)
- {
- // force the culture to en-US
-
-
- // If we don't catch the exception here it will just disappear into the thread pool and we'll be none the wiser
- try
- {
- HttpListenerContext context = (HttpListenerContext)stateinfo;
-
- OSHttpRequest request = new OSHttpRequest(context.Request);
- OSHttpResponse response = new OSHttpResponse(context.Response);
-
- HandleRequest(request, response);
-
- }
- catch (SocketException e)
- {
- // At least on linux, it appears that if the client makes a request without requiring the response,
- // an unconnected socket exception is thrown when we close the response output stream. There's no
- // obvious way to tell if the client didn't require the response, so instead we'll catch and ignore
- // the exception instead.
- //
- // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
- // with the minimum first
- m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
- }
- }
-
- /*
- ///
- /// HttpListener Handle an individual http request. This method is given to a worker in the thread pool.
- ///
- ///
- public virtual void HandleRequestHttpServer(Object stateinfo)
- {
- // force the culture to en-US
-
-
- // If we don't catch the exception here it will just disappear into the thread pool and we'll be none the wiser
- try
- {
- HttpServerContextObj context = (HttpServerContextObj)stateinfo;
-
- OSHttpRequest request = new OSHttpRequest(context.Request);
- OSHttpResponse response = new OSHttpResponse(context.Response);
-
- HandleRequest(request, response);
-
- }
- catch (SocketException e)
- {
- // At least on linux, it appears that if the client makes a request without requiring the response,
- // an unconnected socket exception is thrown when we close the response output stream. There's no
- // obvious way to tell if the client didn't require the response, so instead we'll catch and ignore
- // the exception instead.
- //
- // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
- // with the minimum first
- m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
- }
- catch (Exception e)
- {
- m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
- }
- }
- */
public void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request)
{
OSHttpRequest req = new OSHttpRequest(context, request);
@@ -845,7 +663,7 @@ namespace OpenSim.Framework.Servers
if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV)
{
// we found a registered llsd handler to service this request
- llsdResponse = llsdhandler(request.RawUrl, llsdRequest, (request.RemoteIPEndPoint == null)? "" : request.RemoteIPEndPoint.ToString());
+ llsdResponse = llsdhandler(request.RawUrl, llsdRequest, request.RemoteIPEndPoint.ToString());
}
else
{
diff --git a/OpenSim/Framework/Servers/OSHttpRequest.cs b/OpenSim/Framework/Servers/OSHttpRequest.cs
index 25da97b..c47fe10 100644
--- a/OpenSim/Framework/Servers/OSHttpRequest.cs
+++ b/OpenSim/Framework/Servers/OSHttpRequest.cs
@@ -31,18 +31,25 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.IO;
+using System.Reflection;
using System.Text;
using HttpServer;
+using log4net;
namespace OpenSim.Framework.Servers
{
public class OSHttpRequest
{
+ private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ protected HttpServer.IHttpRequest _request = null;
+ protected HttpServer.IHttpClientContext _context = null;
+
+
public string[] AcceptTypes
{
- get { return _acceptTypes; }
+ get { return _request.AcceptTypes; }
}
- private string[] _acceptTypes;
public Encoding ContentEncoding
{
@@ -52,9 +59,8 @@ namespace OpenSim.Framework.Servers
public long ContentLength
{
- get { return _contentLength64; }
+ get { return _request.ContentLength; }
}
- private long _contentLength64;
public long ContentLength64
{
@@ -67,101 +73,72 @@ namespace OpenSim.Framework.Servers
}
private string _contentType;
- // public CookieCollection Cookies
- // {
- // get { return _cookies; }
- // }
- // private CookieCollection _cookies;
+ public bool HasEntityBody
+ {
+ get { return _request.ContentLength != 0; }
+ }
public NameValueCollection Headers
{
- get { return _headers; }
+ get { return _request.Headers; }
}
- private NameValueCollection _headers;
public string HttpMethod
{
- get { return _httpMethod; }
+ get { return _request.Method; }
}
- private string _httpMethod;
public Stream InputStream
{
- get { return _inputStream; }
+ get { return _request.Body; }
}
- private Stream _inputStream;
- // public bool IsSecureConnection
- // {
- // get { return _isSecureConnection; }
- // }
- // private bool _isSecureConnection;
-
- // public bool IsAuthenticated
- // {
- // get { return _isAuthenticated; }
- // }
- // private bool _isAuthenticated;
-
- public bool HasEntityBody
+ public bool IsSecured
{
- get { return _hasbody; }
+ get { return _context.Secured; }
}
- private bool _hasbody;
public bool KeepAlive
{
- get { return _keepAlive; }
+ get { return ConnectionType.KeepAlive == _request.Connection; }
}
- private bool _keepAlive;
- public string RawUrl
+ public NameValueCollection QueryString
{
- get { return _rawUrl; }
+ get { return _queryString; }
}
- private string _rawUrl;
+ private NameValueCollection _queryString;
- public Uri Url
+ public Hashtable Query
{
- get { return _url; }
+ get { return _query; }
}
- private Uri _url;
+ private Hashtable _query;
- public string UserAgent
+ public string RawUrl
{
- get { return _userAgent; }
+ get { return _request.Uri.AbsolutePath; }
}
- private string _userAgent;
- public NameValueCollection QueryString
+ public IPEndPoint RemoteIPEndPoint
{
- get { return _queryString; }
+ get { return _remoteIPEndPoint; }
}
- private NameValueCollection _queryString;
+ private IPEndPoint _remoteIPEndPoint;
- public Hashtable Query
+ public Uri Url
{
- get { return _query; }
+ get { return _request.Uri; }
}
- private Hashtable _query;
- public IPEndPoint RemoteIPEndPoint
+ public string UserAgent
{
- get { return _ipEndPoint; }
+ get { return _userAgent; }
}
- private IPEndPoint _ipEndPoint;
+ private string _userAgent;
+
- // internal HttpRequest HttpRequest
- // {
- // get { return _request; }
- // }
- // private HttpRequest _request;
- // internal HttpClientContext HttpClientContext
- // {
- // get { return _context; }
- // }
- // private HttpClientContext _context;
///
/// Internal whiteboard for handlers to store temporary stuff
@@ -173,81 +150,60 @@ namespace OpenSim.Framework.Servers
}
private Dictionary _whiteboard = new Dictionary();
+
public OSHttpRequest()
{
}
- public OSHttpRequest(HttpListenerRequest req)
+ public OSHttpRequest(HttpServer.IHttpClientContext context, HttpServer.IHttpRequest req)
{
- _acceptTypes = req.AcceptTypes;
- _contentEncoding = req.ContentEncoding;
- _contentLength64 = req.ContentLength64;
- _contentType = req.ContentType;
- _headers = req.Headers;
- _httpMethod = req.HttpMethod;
- _hasbody = req.HasEntityBody;
- _inputStream = req.InputStream;
- _keepAlive = req.KeepAlive;
- _rawUrl = req.RawUrl;
- _url = req.Url;
- _queryString = req.QueryString;
- _userAgent = req.UserAgent;
- _ipEndPoint = req.RemoteEndPoint;
-
- // _cookies = req.Cookies;
- // _isSecureConnection = req.IsSecureConnection;
- // _isAuthenticated = req.IsAuthenticated;
- }
+ _request = req;
+ _context = context;
+
+ if (null != req.Headers["content-encoding"])
+ _contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
+ if (null != req.Headers["content-type"])
+ _contentType = _request.Headers["content-type"];
+ 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"]);
+ int port = Int32.Parse(req.Headers["remote_port"]);
+ _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"]);
+ }
+ }
- public OSHttpRequest(HttpServer.IHttpClientContext context, HttpServer.IHttpRequest req)
- {
- //_context = context;
- HttpServer.IHttpRequest _request = req;
-
- _acceptTypes = req.AcceptTypes;
- if (null != req.Headers["content-encoding"])
- _contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
- _contentLength64 = req.ContentLength;
- if (null != req.Headers["content-type"])
- _contentType = _request.Headers["content-type"];
- _headers = req.Headers;
- _httpMethod = req.Method;
- _hasbody = req.ContentLength != 0;
- _inputStream = req.Body;
- _keepAlive = ConnectionType.KeepAlive == req.Connection;
- _rawUrl = req.Uri.AbsolutePath;
- _url = req.Uri;
- if (null != req.Headers["user-agent"])
- _userAgent = req.Headers["user-agent"];
- _queryString = new NameValueCollection();
- _query = new Hashtable();
- try
- {
- foreach (HttpInputItem item in req.QueryString)
- {
- try
- {
- _queryString.Add(item.Name, item.Value);
- _query[item.Name] = item.Value;
- }
- catch (InvalidCastException)
- {
- System.Console.WriteLine("[OSHttpRequest]: Errror parsing querystring.. but it was recoverable.. skipping on to the next one");
- continue;
- }
- }
- }
- catch (Exception)
- {
- System.Console.WriteLine("[OSHttpRequest]: Errror parsing querystring");
- }
- // TODO: requires change to HttpServer.HttpRequest
- _ipEndPoint = null;
-
- // _cookies = req.Cookies;
- // _isSecureConnection = req.IsSecureConnection;
- // _isAuthenticated = req.IsAuthenticated;
- }
+ _queryString = new NameValueCollection();
+ _query = new Hashtable();
+ try
+ {
+ foreach (HttpInputItem item in req.QueryString)
+ {
+ try
+ {
+ _queryString.Add(item.Name, item.Value);
+ _query[item.Name] = item.Value;
+ }
+ catch (InvalidCastException)
+ {
+ _log.DebugFormat("[OSHttpRequest]: error parsing {0} query item, skipping it", item.Name);
+ continue;
+ }
+ }
+ }
+ catch (Exception)
+ {
+ _log.ErrorFormat("[OSHttpRequest]: Error parsing querystring");
+ }
+ }
public override string ToString()
{
@@ -259,7 +215,7 @@ namespace OpenSim.Framework.Servers
}
if (null != RemoteIPEndPoint)
{
- me.Append(String.Format(" IP: {0}\n", RemoteIPEndPoint.ToString()));
+ me.Append(String.Format(" IP: {0}\n", RemoteIPEndPoint));
}
return me.ToString();
diff --git a/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs b/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
index 996e5dc..5a3d485 100644
--- a/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
+++ b/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
@@ -45,9 +45,10 @@ namespace OpenSim.Framework.Servers
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
///
- /// An OSHttpHandler that matches on the "content-type" header can
- /// supply an OSHttpContentTypeChecker delegate which will be
- /// invoked by the request matcher in OSHttpRequestPump.
+ /// XmlRpcMethodMatch tries to reify (deserialize) an incoming
+ /// XmlRpc request (and posts it to the "whiteboard") and
+ /// checks whether the method name is one we are interested
+ /// in.
///
/// true if the handler is interested in the content;
/// false otherwise
--
cgit v1.1