aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Servers/BaseHttpServer.cs186
-rw-r--r--OpenSim/Framework/Servers/OSHttpRequest.cs216
-rw-r--r--OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs7
3 files changed, 92 insertions, 317 deletions
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
103 { 103 {
104 m_ssl = ssl; 104 m_ssl = ssl;
105 m_port = port; 105 m_port = port;
106
106 if (m_ssl) 107 if (m_ssl)
107 { 108 {
108 //SetupSsl((int)sslport, CN);
109 m_sslport = sslport; 109 m_sslport = sslport;
110 } 110 }
111 } 111 }
112 112
113
114 /*
115 *
116 public bool SetupSsl(int port, string CN)
117 {
118 string searchCN = Environment.MachineName.ToUpper();
119
120 if (CN.Length > 0)
121 searchCN = CN.ToUpper();
122
123 m_SSLCommonName = searchCN;
124
125 Type t = Type.GetType("Mono.Runtime");
126 if (t != null)
127 {
128 // TODO Mono User Friendly HTTPS setup
129 // if this doesn't exist, then mono people can still manually use httpcfg
130 }
131 else
132 {
133 // Windows.
134 // Search through the store for a certificate with a Common name specified in OpenSim.ini.
135 // We need to find it's hash so we can pass it to httpcfg
136 X509Store store = new X509Store(StoreLocation.LocalMachine);
137 //Use the first cert to configure Ssl
138 store.Open(OpenFlags.ReadOnly);
139 //Assumption is we have certs. If not then this call will fail :(
140 try
141 {
142 bool found = false;
143 //X509Certificate2.CreateFromCertFile("testCert.cer");
144
145 foreach (X509Certificate2 cert in store.Certificates)
146 {
147 String certHash = cert.GetCertHashString();
148 //Only install certs issued for the machine and has the name as the machine name
149 if (cert.Subject.ToUpper().IndexOf(searchCN) >= 0)
150 {
151 string httpcfgparams = String.Format("set ssl -i 0.0.0.0:{1} -c \"MY\" -h {0}", certHash, port);
152 try
153 {
154 found = true;
155
156 ExecuteHttpcfgCommand(httpcfgparams);
157
158 break;
159 }
160 catch (Exception e)
161 {
162 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);
163 return false;
164 }
165 }
166 }
167
168 if (!found)
169 {
170 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);
171 return false;
172 }
173
174 }
175 catch (Exception e)
176 {
177 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);
178 return false;
179 }
180 finally
181 {
182 if (store != null)
183 {
184 store.Close();
185 }
186 }
187 }
188 return true;
189 }
190
191 private void ExecuteHttpcfgCommand(string p)
192 {
193
194 string file = "httpcfg";
195
196 ProcessStartInfo info = new ProcessStartInfo(file, p);
197 // Redirect output so we can read it.
198 info.RedirectStandardOutput = true;
199 // To redirect, we must not use shell execute.
200 info.UseShellExecute = false;
201
202 // Create and execute the process.
203 Process httpcfgprocess = Process.Start(info);
204 httpcfgprocess.Start();
205 string result = httpcfgprocess.StandardOutput.ReadToEnd();
206 if (result.Contains("HttpSetServiceConfiguration completed with"))
207 {
208 //success
209
210 }
211 else
212 {
213 //fail
214 m_log.WarnFormat("[HTTPS]:Error binding certificate with the requested port. Message:{0}", result);
215 }
216
217 }
218 */
219
220 /// <summary> 113 /// <summary>
221 /// Add a stream handler to the http server. If the handler already exists, then nothing happens. 114 /// Add a stream handler to the http server. If the handler already exists, then nothing happens.
222 /// </summary> 115 /// </summary>
@@ -311,81 +204,6 @@ namespace OpenSim.Framework.Servers
311 return true; 204 return true;
312 } 205 }
313 206
314 /// <summary>
315 /// HttpListener Handle an individual http request. This method is given to a worker in the thread pool.
316 /// </summary>
317 /// <param name="stateinfo"></param>
318 public virtual void HandleRequest(Object stateinfo)
319 {
320 // force the culture to en-US
321
322
323 // If we don't catch the exception here it will just disappear into the thread pool and we'll be none the wiser
324 try
325 {
326 HttpListenerContext context = (HttpListenerContext)stateinfo;
327
328 OSHttpRequest request = new OSHttpRequest(context.Request);
329 OSHttpResponse response = new OSHttpResponse(context.Response);
330
331 HandleRequest(request, response);
332
333 }
334 catch (SocketException e)
335 {
336 // At least on linux, it appears that if the client makes a request without requiring the response,
337 // an unconnected socket exception is thrown when we close the response output stream. There's no
338 // obvious way to tell if the client didn't require the response, so instead we'll catch and ignore
339 // the exception instead.
340 //
341 // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
342 // with the minimum first
343 m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
344 }
345 catch (Exception e)
346 {
347 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
348 }
349 }
350
351 /*
352 /// <summary>
353 /// HttpListener Handle an individual http request. This method is given to a worker in the thread pool.
354 /// </summary>
355 /// <param name="stateinfo"></param>
356 public virtual void HandleRequestHttpServer(Object stateinfo)
357 {
358 // force the culture to en-US
359
360
361 // If we don't catch the exception here it will just disappear into the thread pool and we'll be none the wiser
362 try
363 {
364 HttpServerContextObj context = (HttpServerContextObj)stateinfo;
365
366 OSHttpRequest request = new OSHttpRequest(context.Request);
367 OSHttpResponse response = new OSHttpResponse(context.Response);
368
369 HandleRequest(request, response);
370
371 }
372 catch (SocketException e)
373 {
374 // At least on linux, it appears that if the client makes a request without requiring the response,
375 // an unconnected socket exception is thrown when we close the response output stream. There's no
376 // obvious way to tell if the client didn't require the response, so instead we'll catch and ignore
377 // the exception instead.
378 //
379 // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
380 // with the minimum first
381 m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
382 }
383 catch (Exception e)
384 {
385 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
386 }
387 }
388 */
389 public void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request) 207 public void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request)
390 { 208 {
391 OSHttpRequest req = new OSHttpRequest(context, request); 209 OSHttpRequest req = new OSHttpRequest(context, request);
@@ -845,7 +663,7 @@ namespace OpenSim.Framework.Servers
845 if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV) 663 if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV)
846 { 664 {
847 // we found a registered llsd handler to service this request 665 // we found a registered llsd handler to service this request
848 llsdResponse = llsdhandler(request.RawUrl, llsdRequest, (request.RemoteIPEndPoint == null)? "" : request.RemoteIPEndPoint.ToString()); 666 llsdResponse = llsdhandler(request.RawUrl, llsdRequest, request.RemoteIPEndPoint.ToString());
849 } 667 }
850 else 668 else
851 { 669 {
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;
31using System.Collections.Specialized; 31using System.Collections.Specialized;
32using System.Net; 32using System.Net;
33using System.IO; 33using System.IO;
34using System.Reflection;
34using System.Text; 35using System.Text;
35using HttpServer; 36using HttpServer;
37using log4net;
36 38
37namespace OpenSim.Framework.Servers 39namespace OpenSim.Framework.Servers
38{ 40{
39 public class OSHttpRequest 41 public class OSHttpRequest
40 { 42 {
43 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 protected HttpServer.IHttpRequest _request = null;
46 protected HttpServer.IHttpClientContext _context = null;
47
48
41 public string[] AcceptTypes 49 public string[] AcceptTypes
42 { 50 {
43 get { return _acceptTypes; } 51 get { return _request.AcceptTypes; }
44 } 52 }
45 private string[] _acceptTypes;
46 53
47 public Encoding ContentEncoding 54 public Encoding ContentEncoding
48 { 55 {
@@ -52,9 +59,8 @@ namespace OpenSim.Framework.Servers
52 59
53 public long ContentLength 60 public long ContentLength
54 { 61 {
55 get { return _contentLength64; } 62 get { return _request.ContentLength; }
56 } 63 }
57 private long _contentLength64;
58 64
59 public long ContentLength64 65 public long ContentLength64
60 { 66 {
@@ -67,101 +73,72 @@ namespace OpenSim.Framework.Servers
67 } 73 }
68 private string _contentType; 74 private string _contentType;
69 75
70 // public CookieCollection Cookies 76 public bool HasEntityBody
71 // { 77 {
72 // get { return _cookies; } 78 get { return _request.ContentLength != 0; }
73 // } 79 }
74 // private CookieCollection _cookies;
75 80
76 public NameValueCollection Headers 81 public NameValueCollection Headers
77 { 82 {
78 get { return _headers; } 83 get { return _request.Headers; }
79 } 84 }
80 private NameValueCollection _headers;
81 85
82 public string HttpMethod 86 public string HttpMethod
83 { 87 {
84 get { return _httpMethod; } 88 get { return _request.Method; }
85 } 89 }
86 private string _httpMethod;
87 90
88 public Stream InputStream 91 public Stream InputStream
89 { 92 {
90 get { return _inputStream; } 93 get { return _request.Body; }
91 } 94 }
92 private Stream _inputStream;
93 95
94 // public bool IsSecureConnection 96 public bool IsSecured
95 // {
96 // get { return _isSecureConnection; }
97 // }
98 // private bool _isSecureConnection;
99
100 // public bool IsAuthenticated
101 // {
102 // get { return _isAuthenticated; }
103 // }
104 // private bool _isAuthenticated;
105
106 public bool HasEntityBody
107 { 97 {
108 get { return _hasbody; } 98 get { return _context.Secured; }
109 } 99 }
110 private bool _hasbody;
111 100
112 public bool KeepAlive 101 public bool KeepAlive
113 { 102 {
114 get { return _keepAlive; } 103 get { return ConnectionType.KeepAlive == _request.Connection; }
115 } 104 }
116 private bool _keepAlive;
117 105
118 public string RawUrl 106 public NameValueCollection QueryString
119 { 107 {
120 get { return _rawUrl; } 108 get { return _queryString; }
121 } 109 }
122 private string _rawUrl; 110 private NameValueCollection _queryString;
123 111
124 public Uri Url 112 public Hashtable Query
125 { 113 {
126 get { return _url; } 114 get { return _query; }
127 } 115 }
128 private Uri _url; 116 private Hashtable _query;
129 117
130 public string UserAgent 118 public string RawUrl
131 { 119 {
132 get { return _userAgent; } 120 get { return _request.Uri.AbsolutePath; }
133 } 121 }
134 private string _userAgent;
135 122
136 public NameValueCollection QueryString 123 public IPEndPoint RemoteIPEndPoint
137 { 124 {
138 get { return _queryString; } 125 get { return _remoteIPEndPoint; }
139 } 126 }
140 private NameValueCollection _queryString; 127 private IPEndPoint _remoteIPEndPoint;
141 128
142 public Hashtable Query 129 public Uri Url
143 { 130 {
144 get { return _query; } 131 get { return _request.Uri; }
145 } 132 }
146 private Hashtable _query;
147 133
148 public IPEndPoint RemoteIPEndPoint 134 public string UserAgent
149 { 135 {
150 get { return _ipEndPoint; } 136 get { return _userAgent; }
151 } 137 }
152 private IPEndPoint _ipEndPoint; 138 private string _userAgent;
139
153 140
154 // internal HttpRequest HttpRequest
155 // {
156 // get { return _request; }
157 // }
158 // private HttpRequest _request;
159 141
160 // internal HttpClientContext HttpClientContext
161 // {
162 // get { return _context; }
163 // }
164 // private HttpClientContext _context;
165 142
166 /// <summary> 143 /// <summary>
167 /// Internal whiteboard for handlers to store temporary stuff 144 /// Internal whiteboard for handlers to store temporary stuff
@@ -173,81 +150,60 @@ namespace OpenSim.Framework.Servers
173 } 150 }
174 private Dictionary<string, object> _whiteboard = new Dictionary<string, object>(); 151 private Dictionary<string, object> _whiteboard = new Dictionary<string, object>();
175 152
153
176 public OSHttpRequest() 154 public OSHttpRequest()
177 { 155 {
178 } 156 }
179 157
180 public OSHttpRequest(HttpListenerRequest req) 158 public OSHttpRequest(HttpServer.IHttpClientContext context, HttpServer.IHttpRequest req)
181 { 159 {
182 _acceptTypes = req.AcceptTypes; 160 _request = req;
183 _contentEncoding = req.ContentEncoding; 161 _context = context;
184 _contentLength64 = req.ContentLength64; 162
185 _contentType = req.ContentType; 163 if (null != req.Headers["content-encoding"])
186 _headers = req.Headers; 164 _contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
187 _httpMethod = req.HttpMethod; 165 if (null != req.Headers["content-type"])
188 _hasbody = req.HasEntityBody; 166 _contentType = _request.Headers["content-type"];
189 _inputStream = req.InputStream; 167 if (null != req.Headers["user-agent"])
190 _keepAlive = req.KeepAlive; 168 _userAgent = req.Headers["user-agent"];
191 _rawUrl = req.RawUrl; 169 if (null != req.Headers["remote_addr"])
192 _url = req.Url; 170 {
193 _queryString = req.QueryString; 171 try
194 _userAgent = req.UserAgent; 172 {
195 _ipEndPoint = req.RemoteEndPoint; 173 IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]);
196 174 int port = Int32.Parse(req.Headers["remote_port"]);
197 // _cookies = req.Cookies; 175 _remoteIPEndPoint = new IPEndPoint(addr, port);
198 // _isSecureConnection = req.IsSecureConnection; 176 }
199 // _isAuthenticated = req.IsAuthenticated; 177 catch (FormatException)
200 } 178 {
179 _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring",
180 req.Headers["remote_addr"], req.Headers["remote_port"]);
181 }
182 }
201 183
202 public OSHttpRequest(HttpServer.IHttpClientContext context, HttpServer.IHttpRequest req) 184 _queryString = new NameValueCollection();
203 { 185 _query = new Hashtable();
204 //_context = context; 186 try
205 HttpServer.IHttpRequest _request = req; 187 {
206 188 foreach (HttpInputItem item in req.QueryString)
207 _acceptTypes = req.AcceptTypes; 189 {
208 if (null != req.Headers["content-encoding"]) 190 try
209 _contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]); 191 {
210 _contentLength64 = req.ContentLength; 192 _queryString.Add(item.Name, item.Value);
211 if (null != req.Headers["content-type"]) 193 _query[item.Name] = item.Value;
212 _contentType = _request.Headers["content-type"]; 194 }
213 _headers = req.Headers; 195 catch (InvalidCastException)
214 _httpMethod = req.Method; 196 {
215 _hasbody = req.ContentLength != 0; 197 _log.DebugFormat("[OSHttpRequest]: error parsing {0} query item, skipping it", item.Name);
216 _inputStream = req.Body; 198 continue;
217 _keepAlive = ConnectionType.KeepAlive == req.Connection; 199 }
218 _rawUrl = req.Uri.AbsolutePath; 200 }
219 _url = req.Uri; 201 }
220 if (null != req.Headers["user-agent"]) 202 catch (Exception)
221 _userAgent = req.Headers["user-agent"]; 203 {
222 _queryString = new NameValueCollection(); 204 _log.ErrorFormat("[OSHttpRequest]: Error parsing querystring");
223 _query = new Hashtable(); 205 }
224 try 206 }
225 {
226 foreach (HttpInputItem item in req.QueryString)
227 {
228 try
229 {
230 _queryString.Add(item.Name, item.Value);
231 _query[item.Name] = item.Value;
232 }
233 catch (InvalidCastException)
234 {
235 System.Console.WriteLine("[OSHttpRequest]: Errror parsing querystring.. but it was recoverable.. skipping on to the next one");
236 continue;
237 }
238 }
239 }
240 catch (Exception)
241 {
242 System.Console.WriteLine("[OSHttpRequest]: Errror parsing querystring");
243 }
244 // TODO: requires change to HttpServer.HttpRequest
245 _ipEndPoint = null;
246
247 // _cookies = req.Cookies;
248 // _isSecureConnection = req.IsSecureConnection;
249 // _isAuthenticated = req.IsAuthenticated;
250 }
251 207
252 public override string ToString() 208 public override string ToString()
253 { 209 {
@@ -259,7 +215,7 @@ namespace OpenSim.Framework.Servers
259 } 215 }
260 if (null != RemoteIPEndPoint) 216 if (null != RemoteIPEndPoint)
261 { 217 {
262 me.Append(String.Format(" IP: {0}\n", RemoteIPEndPoint.ToString())); 218 me.Append(String.Format(" IP: {0}\n", RemoteIPEndPoint));
263 } 219 }
264 220
265 return me.ToString(); 221 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
45 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 /// <summary> 47 /// <summary>
48 /// An OSHttpHandler that matches on the "content-type" header can 48 /// XmlRpcMethodMatch tries to reify (deserialize) an incoming
49 /// supply an OSHttpContentTypeChecker delegate which will be 49 /// XmlRpc request (and posts it to the "whiteboard") and
50 /// invoked by the request matcher in OSHttpRequestPump. 50 /// checks whether the method name is one we are interested
51 /// in.
51 /// </summary> 52 /// </summary>
52 /// <returns>true if the handler is interested in the content; 53 /// <returns>true if the handler is interested in the content;
53 /// false otherwise</returns> 54 /// false otherwise</returns>