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/Servers') 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