diff options
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs')
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 163 |
1 files changed, 109 insertions, 54 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 77fce9e..bfbc480 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,74 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
986 | return buffer; | 1026 | return buffer; |
987 | } | 1027 | } |
988 | 1028 | ||
1029 | // JsonRpc (v2.0 only) | ||
1030 | private byte[] HandleJsonRpcRequests(OSHttpRequest request, OSHttpResponse response) | ||
1031 | { | ||
1032 | Stream requestStream = request.InputStream; | ||
1033 | JsonRpcResponse jsonRpcResponse = new JsonRpcResponse(); | ||
1034 | OSDMap jsonRpcRequest = null; | ||
1035 | |||
1036 | try | ||
1037 | { | ||
1038 | jsonRpcRequest = (OSDMap)OSDParser.DeserializeJson(requestStream); | ||
1039 | } | ||
1040 | catch (LitJson.JsonException e) | ||
1041 | { | ||
1042 | jsonRpcResponse.Error.Code = ErrorCode.InternalError; | ||
1043 | jsonRpcResponse.Error.Message = e.Message; | ||
1044 | } | ||
1045 | |||
1046 | requestStream.Close(); | ||
1047 | |||
1048 | if (jsonRpcRequest != null) | ||
1049 | { | ||
1050 | if (jsonRpcRequest.ContainsKey("jsonrpc") || jsonRpcRequest["jsonrpc"].AsString() == "2.0") | ||
1051 | { | ||
1052 | jsonRpcResponse.JsonRpc = "2.0"; | ||
1053 | |||
1054 | // If we have no id, then it's a "notification" | ||
1055 | if (jsonRpcRequest.ContainsKey("id")) | ||
1056 | { | ||
1057 | jsonRpcResponse.Id = jsonRpcRequest["id"].AsString(); | ||
1058 | } | ||
1059 | |||
1060 | string methodname = jsonRpcRequest["method"]; | ||
1061 | JsonRPCMethod method; | ||
1062 | |||
1063 | if (jsonRpcHandlers.ContainsKey(methodname)) | ||
1064 | { | ||
1065 | lock(jsonRpcHandlers) | ||
1066 | { | ||
1067 | jsonRpcHandlers.TryGetValue(methodname, out method); | ||
1068 | } | ||
1069 | |||
1070 | method(jsonRpcRequest, ref jsonRpcResponse); | ||
1071 | } | ||
1072 | else // Error no hanlder defined for requested method | ||
1073 | { | ||
1074 | jsonRpcResponse.Error.Code = ErrorCode.InvalidRequest; | ||
1075 | jsonRpcResponse.Error.Message = string.Format ("No handler defined for {0}", methodname); | ||
1076 | } | ||
1077 | } | ||
1078 | else // not json-rpc 2.0 could be v1 | ||
1079 | { | ||
1080 | jsonRpcResponse.Error.Code = ErrorCode.InvalidRequest; | ||
1081 | jsonRpcResponse.Error.Message = "Must be valid json-rpc 2.0 see: http://www.jsonrpc.org/specification"; | ||
1082 | |||
1083 | if (jsonRpcRequest.ContainsKey("id")) | ||
1084 | jsonRpcResponse.Id = jsonRpcRequest["id"].AsString(); | ||
1085 | } | ||
1086 | } | ||
1087 | |||
1088 | response.KeepAlive = true; | ||
1089 | string responseData = string.Empty; | ||
1090 | |||
1091 | responseData = jsonRpcResponse.Serialize(); | ||
1092 | |||
1093 | byte[] buffer = Encoding.UTF8.GetBytes(responseData); | ||
1094 | return buffer; | ||
1095 | } | ||
1096 | |||
989 | private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response) | 1097 | private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response) |
990 | { | 1098 | { |
991 | //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); | 1099 | //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); |
@@ -1283,59 +1391,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1283 | map["login"] = OSD.FromString("false"); | 1391 | map["login"] = OSD.FromString("false"); |
1284 | return map; | 1392 | return map; |
1285 | } | 1393 | } |
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 | 1394 | ||
1340 | public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) | 1395 | public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) |
1341 | { | 1396 | { |