aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs')
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs184
1 files changed, 130 insertions, 54 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 77fce9e..e3f2e7a 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -77,6 +77,7 @@ namespace OpenSim.Framework.Servers.HttpServer
77 // protected HttpListener m_httpListener; 77 // protected HttpListener m_httpListener;
78 protected CoolHTTPListener m_httpListener2; 78 protected CoolHTTPListener m_httpListener2;
79 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>(); 79 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
80 protected Dictionary<string, JsonRPCMethod> jsonRpcHandlers = new Dictionary<string, JsonRPCMethod>();
80 protected Dictionary<string, bool> m_rpcHandlersKeepAlive = new Dictionary<string, bool>(); 81 protected Dictionary<string, bool> m_rpcHandlersKeepAlive = new Dictionary<string, bool>();
81 protected DefaultLLSDMethod m_defaultLlsdHandler = null; // <-- Moving away from the monolithic.. and going to /registered/ 82 protected DefaultLLSDMethod m_defaultLlsdHandler = null; // <-- Moving away from the monolithic.. and going to /registered/
82 protected Dictionary<string, LLSDMethod> m_llsdHandlers = new Dictionary<string, LLSDMethod>(); 83 protected Dictionary<string, LLSDMethod> m_llsdHandlers = new Dictionary<string, LLSDMethod>();
@@ -217,6 +218,37 @@ namespace OpenSim.Framework.Servers.HttpServer
217 return new List<string>(m_rpcHandlers.Keys); 218 return new List<string>(m_rpcHandlers.Keys);
218 } 219 }
219 220
221 // JsonRPC
222 public bool AddJsonRPCHandler(string method, JsonRPCMethod handler)
223 {
224 lock(jsonRpcHandlers)
225 {
226 jsonRpcHandlers.Add(method, handler);
227 }
228 return true;
229 }
230
231 public JsonRPCMethod GetJsonRPCHandler(string method)
232 {
233 lock (jsonRpcHandlers)
234 {
235 if (jsonRpcHandlers.ContainsKey(method))
236 {
237 return jsonRpcHandlers[method];
238 }
239 else
240 {
241 return null;
242 }
243 }
244 }
245
246 public List<string> GetJsonRpcHandlerKeys()
247 {
248 lock (jsonRpcHandlers)
249 return new List<string>(jsonRpcHandlers.Keys);
250 }
251
220 public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler) 252 public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler)
221 { 253 {
222 //m_log.DebugFormat("[BASE HTTP SERVER]: Registering {0}", methodName); 254 //m_log.DebugFormat("[BASE HTTP SERVER]: Registering {0}", methodName);
@@ -437,7 +469,7 @@ namespace OpenSim.Framework.Servers.HttpServer
437// reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]); 469// reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]);
438 //m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl); 470 //m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
439 471
440 Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); 472 Culture.SetCurrentCulture();
441 473
442// // This is the REST agent interface. We require an agent to properly identify 474// // This is the REST agent interface. We require an agent to properly identify
443// // itself. If the REST handler recognizes the prefix it will attempt to 475// // itself. If the REST handler recognizes the prefix it will attempt to
@@ -557,10 +589,18 @@ namespace OpenSim.Framework.Servers.HttpServer
557 589
558 buffer = HandleLLSDRequests(request, response); 590 buffer = HandleLLSDRequests(request, response);
559 break; 591 break;
592
593 case "application/json-rpc":
594 if (DebugLevel >= 3)
595 LogIncomingToContentTypeHandler(request);
596
597 buffer = HandleJsonRpcRequests(request, response);
598 break;
560 599
561 case "text/xml": 600 case "text/xml":
562 case "application/xml": 601 case "application/xml":
563 case "application/json": 602 case "application/json":
603
564 default: 604 default:
565 //m_log.Info("[Debug BASE HTTP SERVER]: in default handler"); 605 //m_log.Info("[Debug BASE HTTP SERVER]: in default handler");
566 // Point of note.. the DoWeHaveA methods check for an EXACT path 606 // Point of note.. the DoWeHaveA methods check for an EXACT path
@@ -986,6 +1026,93 @@ namespace OpenSim.Framework.Servers.HttpServer
986 return buffer; 1026 return buffer;
987 } 1027 }
988 1028
1029 // JsonRpc (v2.0 only)
1030 // Batch requests not yet supported
1031 private byte[] HandleJsonRpcRequests(OSHttpRequest request, OSHttpResponse response)
1032 {
1033 Stream requestStream = request.InputStream;
1034 JsonRpcResponse jsonRpcResponse = new JsonRpcResponse();
1035 OSDMap jsonRpcRequest = null;
1036
1037 try
1038 {
1039 jsonRpcRequest = (OSDMap)OSDParser.DeserializeJson(requestStream);
1040 }
1041 catch (LitJson.JsonException e)
1042 {
1043 jsonRpcResponse.Error.Code = ErrorCode.InternalError;
1044 jsonRpcResponse.Error.Message = e.Message;
1045 }
1046
1047 requestStream.Close();
1048
1049 if (jsonRpcRequest != null)
1050 {
1051 if (jsonRpcRequest.ContainsKey("jsonrpc") || jsonRpcRequest["jsonrpc"].AsString() == "2.0")
1052 {
1053 jsonRpcResponse.JsonRpc = "2.0";
1054
1055 // If we have no id, then it's a "notification"
1056 if (jsonRpcRequest.ContainsKey("id"))
1057 {
1058 jsonRpcResponse.Id = jsonRpcRequest["id"].AsString();
1059 }
1060
1061 string methodname = jsonRpcRequest["method"];
1062 JsonRPCMethod method;
1063
1064 if (jsonRpcHandlers.ContainsKey(methodname))
1065 {
1066 lock(jsonRpcHandlers)
1067 {
1068 jsonRpcHandlers.TryGetValue(methodname, out method);
1069 }
1070 bool res = false;
1071 try
1072 {
1073 res = method(jsonRpcRequest, ref jsonRpcResponse);
1074 if(!res)
1075 {
1076 // The handler sent back an unspecified error
1077 if(jsonRpcResponse.Error.Code == 0)
1078 {
1079 jsonRpcResponse.Error.Code = ErrorCode.InternalError;
1080 }
1081 }
1082 }
1083 catch (Exception e)
1084 {
1085 string ErrorMessage = string.Format("[BASE HTTP SERVER]: Json-Rpc Handler Error method {0} - {1}", methodname, e.Message);
1086 m_log.Error(ErrorMessage);
1087 jsonRpcResponse.Error.Code = ErrorCode.InternalError;
1088 jsonRpcResponse.Error.Message = ErrorMessage;
1089 }
1090 }
1091 else // Error no hanlder defined for requested method
1092 {
1093 jsonRpcResponse.Error.Code = ErrorCode.InvalidRequest;
1094 jsonRpcResponse.Error.Message = string.Format ("No handler defined for {0}", methodname);
1095 }
1096 }
1097 else // not json-rpc 2.0 could be v1
1098 {
1099 jsonRpcResponse.Error.Code = ErrorCode.InvalidRequest;
1100 jsonRpcResponse.Error.Message = "Must be valid json-rpc 2.0 see: http://www.jsonrpc.org/specification";
1101
1102 if (jsonRpcRequest.ContainsKey("id"))
1103 jsonRpcResponse.Id = jsonRpcRequest["id"].AsString();
1104 }
1105 }
1106
1107 response.KeepAlive = true;
1108 string responseData = string.Empty;
1109
1110 responseData = jsonRpcResponse.Serialize();
1111
1112 byte[] buffer = Encoding.UTF8.GetBytes(responseData);
1113 return buffer;
1114 }
1115
989 private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response) 1116 private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
990 { 1117 {
991 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); 1118 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
@@ -1283,59 +1410,6 @@ namespace OpenSim.Framework.Servers.HttpServer
1283 map["login"] = OSD.FromString("false"); 1410 map["login"] = OSD.FromString("false");
1284 return map; 1411 return map;
1285 } 1412 }
1286 /// <summary>
1287 /// A specific agent handler was provided. Such a handler is expecetd to have an
1288 /// intimate, and highly specific relationship with the client. Consequently,
1289 /// nothing is done here.
1290 /// </summary>
1291 /// <param name="handler"></param>
1292 /// <param name="request"></param>
1293 /// <param name="response"></param>
1294
1295 private bool HandleAgentRequest(IHttpAgentHandler handler, OSHttpRequest request, OSHttpResponse response)
1296 {
1297 // In the case of REST, then handler is responsible for ALL aspects of
1298 // the request/response handling. Nothing is done here, not even encoding.
1299
1300 try
1301 {
1302 return handler.Handle(request, response);
1303 }
1304 catch (Exception e)
1305 {
1306 // If the handler did in fact close the stream, then this will blow
1307 // chunks. So that that doesn't disturb anybody we throw away any
1308 // and all exceptions raised. We've done our best to release the
1309 // client.
1310 try
1311 {
1312 m_log.Warn("[HTTP-AGENT]: Error - " + e.Message);
1313 response.SendChunked = false;
1314 response.KeepAlive = true;
1315 response.StatusCode = (int)OSHttpStatusCode.ServerErrorInternalError;
1316 //response.OutputStream.Close();
1317 try
1318 {
1319 response.Send();
1320 //response.FreeContext();
1321 }
1322 catch (SocketException f)
1323 {
1324 // This has to be here to prevent a Linux/Mono crash
1325 m_log.Warn(
1326 String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f);
1327 }
1328 }
1329 catch(Exception)
1330 {
1331 }
1332 }
1333
1334 // Indicate that the request has been "handled"
1335
1336 return true;
1337
1338 }
1339 1413
1340 public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) 1414 public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
1341 { 1415 {
@@ -1775,6 +1849,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1775 HTTPDRunning = false; 1849 HTTPDRunning = false;
1776 try 1850 try
1777 { 1851 {
1852// m_PollServiceManager.Stop();
1853
1778 m_httpListener2.ExceptionThrown -= httpServerException; 1854 m_httpListener2.ExceptionThrown -= httpServerException;
1779 //m_httpListener2.DisconnectHandler = null; 1855 //m_httpListener2.DisconnectHandler = null;
1780 1856