//internal members internal XmlRpcAsyncResult( XmlRpcClientProtocol ClientProtocol, XmlRpcRequest XmlRpcReq, Encoding XmlEncoding, bool useEmptyParamsTag, bool useIndentation, int indentation, bool UseIntTag, bool UseStringTag, WebRequest Request, AsyncCallback UserCallback, object UserAsyncState, int retryNumber) { xmlRpcRequest = XmlRpcReq; clientProtocol = ClientProtocol; request = Request; userAsyncState = UserAsyncState; userCallback = UserCallback; completedSynchronously = true; xmlEncoding = XmlEncoding; _useEmptyParamsTag = useEmptyParamsTag; _useIndentation = useIndentation; _indentation = indentation; _useIntTag = UseIntTag; _useStringTag = UseStringTag; }
public XmlRpcResponse Invoke(XmlRpcRequest request) { MethodInfo mi = null; if (request.mi != null) { mi = request.mi; } else { mi = this.GetType().GetMethod(request.method); } // exceptions thrown during an MethodInfo.Invoke call are // package as inner of Object reto; try { reto = mi.Invoke(this, request.args); } catch(Exception ex) { if (ex.InnerException != null) throw ex.InnerException; throw ex; } XmlRpcResponse response = new XmlRpcResponse(reto); return response; }
public void SerializeRequest(Stream stm, XmlRpcRequest request) { // JB Change - Android tapatalk client needs the encoding to be uppercased if (m_encoding is UTF8Encoding) m_encoding = UpperCaseUTF8Encoding.UpperCaseUTF8; XmlTextWriter xtw = new XmlTextWriter(stm, m_encoding); ConfigureXmlFormat(xtw); xtw.WriteStartDocument(); xtw.WriteStartElement("", "methodCall", ""); { // TODO: use global action setting MappingAction mappingAction = MappingAction.Error; if (request.xmlRpcMethod == null) xtw.WriteElementString("methodName", request.method); else xtw.WriteElementString("methodName", request.xmlRpcMethod); if (request.args.Length > 0 || UseEmptyParamsTag) { xtw.WriteStartElement("", "params", ""); try { if (!IsStructParamsMethod(request.mi)) SerializeParams(xtw, request, mappingAction); else SerializeStructParams(xtw, request, mappingAction); } catch (XmlRpcUnsupportedTypeException ex) { throw new XmlRpcUnsupportedTypeException(ex.UnsupportedType, String.Format("A parameter is of, or contains an instance of, " + "type {0} which cannot be mapped to an XML-RPC type", ex.UnsupportedType)); } xtw.WriteEndElement(); } } xtw.WriteEndElement(); xtw.Flush(); }
public XmlRpcRequest DeserializeRequest(XmlDocument xdoc, Type svcType) { XmlRpcRequest request = new XmlRpcRequest(); XmlNode callNode = SelectSingleNode(xdoc, "methodCall"); if (callNode == null) { throw new XmlRpcInvalidXmlRpcException( "Request XML not valid XML-RPC - missing methodCall element."); } XmlNode methodNode = SelectSingleNode(callNode, "methodName"); if (methodNode == null) { throw new XmlRpcInvalidXmlRpcException( "Request XML not valid XML-RPC - missing methodName element."); } if (methodNode.FirstChild == null) { throw new XmlRpcInvalidXmlRpcException( "Request XML not valid XML-RPC - missing methodName element."); } request.method = methodNode.FirstChild.Value; if (request.method == "") { throw new XmlRpcInvalidXmlRpcException( "Request XML not valid XML-RPC - empty methodName."); } request.mi = null; ParameterInfo[] pis = new ParameterInfo[0]; if (svcType != null) { // retrieve info for the method which handles this XML-RPC method XmlRpcServiceInfo svcInfo = XmlRpcServiceInfo.CreateServiceInfo(svcType); request.mi = svcInfo.GetMethodInfo(request.method); // if a service type has been specified and we cannot find the requested // method then we must throw an exception if (request.mi == null) { string msg = String.Format("unsupported method called: {0}", request.method); throw new XmlRpcUnsupportedMethodException(msg); } // method must be marked with XmlRpcMethod attribute Attribute attr = Attribute.GetCustomAttribute(request.mi, typeof(XmlRpcMethodAttribute)); if (attr == null) { throw new XmlRpcMethodAttributeException( "Method must be marked with the XmlRpcMethod attribute."); } pis = request.mi.GetParameters(); } XmlNode paramsNode = SelectSingleNode(callNode, "params"); if (paramsNode == null) { if (svcType != null) { if (pis.Length == 0) { request.args = new object[0]; return request; } // JB Change // Sometimes tapatalk calls the same method with both parameters and no parameters // This allows us to handle that by changing the no parameter case into an empty parameter array else if(pis.Length == 1 && pis[0].ParameterType == typeof(object[])) { paramsNode = xdoc.CreateNode(XmlNodeType.Element, "params", ""); //var paramNode = xdoc.CreateNode(XmlNodeType.Element, "param", ""); //paramsNode.AppendChild(paramNode); // var valueNode = xdoc.CreateNode(XmlNodeType.Element, "value", ""); //paramNode.AppendChild(valueNode); // var arrayNode = xdoc.CreateNode(XmlNodeType.Element, "string", ""); //valueNode.AppendChild(arrayNode); // var dataNode = xdoc.CreateNode(XmlNodeType.Element, "data", ""); //arrayNode.AppendChild(dataNode); } else { throw new XmlRpcInvalidParametersException( "Method takes parameters and params element is missing."); } } else { request.args = new object[0]; return request; } } XmlNode[] paramNodes = SelectNodes(paramsNode, "param"); int paramsPos = GetParamsPos(pis); int minParamCount = paramsPos == -1 ? pis.Length : paramsPos; if (svcType != null && paramNodes.Length < minParamCount) { throw new XmlRpcInvalidParametersException( "Request contains too few param elements based on method signature."); } if (svcType != null && paramsPos == -1 && paramNodes.Length > pis.Length) { throw new XmlRpcInvalidParametersException( "Request contains too many param elements based on method signature."); } ParseStack parseStack = new ParseStack("request"); // TODO: use global action setting MappingAction mappingAction = MappingAction.Error; int paramObjCount = (paramsPos == -1 ? paramNodes.Length : paramsPos + 1); Object[] paramObjs = new Object[paramObjCount]; // parse ordinary parameters int ordinaryParams = (paramsPos == -1 ? paramNodes.Length : paramsPos); for (int i = 0; i < ordinaryParams; i++) { XmlNode paramNode = paramNodes[i]; XmlNode valueNode = SelectSingleNode(paramNode, "value"); if (valueNode == null) throw new XmlRpcInvalidXmlRpcException("Missing value element."); XmlNode node = SelectValueNode(valueNode); if (svcType != null) { parseStack.Push(String.Format("parameter {0}", i + 1)); // TODO: why following commented out? // parseStack.Push(String.Format("parameter {0} mapped to type {1}", // i, pis[i].ParameterType.Name)); paramObjs[i] = ParseValue(node, pis[i].ParameterType, parseStack, mappingAction); } else { parseStack.Push(String.Format("parameter {0}", i)); paramObjs[i] = ParseValue(node, null, parseStack, mappingAction); } parseStack.Pop(); } // parse params parameters if (paramsPos != -1) { Type paramsType = pis[paramsPos].ParameterType.GetElementType(); Object[] args = new Object[1]; args[0] = paramNodes.Length - paramsPos; Array varargs = (Array)CreateArrayInstance(pis[paramsPos].ParameterType, args); for (int i = 0; i < varargs.Length; i++) { XmlNode paramNode = paramNodes[i + paramsPos]; XmlNode valueNode = SelectSingleNode(paramNode, "value"); if (valueNode == null) throw new XmlRpcInvalidXmlRpcException("Missing value element."); XmlNode node = SelectValueNode(valueNode); parseStack.Push(String.Format("parameter {0}", i + 1 + paramsPos)); varargs.SetValue(ParseValue(node, paramsType, parseStack, mappingAction), i); parseStack.Pop(); } paramObjs[paramsPos] = varargs; } request.args = paramObjs; return request; }
void SerializeStructParams(XmlTextWriter xtw, XmlRpcRequest request, MappingAction mappingAction) { ParameterInfo[] pis = request.mi.GetParameters(); if (request.args.Length > pis.Length) throw new XmlRpcInvalidParametersException("Number of request " + "parameters greater than number of proxy method parameters."); if (Attribute.IsDefined(pis[request.args.Length - 1], typeof(ParamArrayAttribute))) { throw new XmlRpcInvalidParametersException("params parameter cannot " + "be used with StructParams."); } xtw.WriteStartElement("", "param", ""); xtw.WriteStartElement("", "value", ""); xtw.WriteStartElement("", "struct", ""); for (int i = 0; i < request.args.Length; i++) { if (request.args[i] == null) { throw new XmlRpcNullParameterException(String.Format( "Null method parameter #{0}", i + 1)); } xtw.WriteStartElement("", "member", ""); xtw.WriteElementString("name", pis[i].Name); Serialize(xtw, request.args[i], mappingAction); xtw.WriteEndElement(); } xtw.WriteEndElement(); xtw.WriteEndElement(); xtw.WriteEndElement(); }
void SerializeParams(XmlTextWriter xtw, XmlRpcRequest request, MappingAction mappingAction) { ParameterInfo[] pis = null; if (request.mi != null) { pis = request.mi.GetParameters(); } for (int i = 0; i < request.args.Length; i++) { if (pis != null) { if (i >= pis.Length) throw new XmlRpcInvalidParametersException("Number of request " + "parameters greater than number of proxy method parameters."); if (i == pis.Length - 1 && Attribute.IsDefined(pis[i], typeof(ParamArrayAttribute))) { Array ary = (Array)request.args[i]; foreach (object o in ary) { if (o == null) throw new XmlRpcNullParameterException( "Null parameter in params array"); xtw.WriteStartElement("", "param", ""); Serialize(xtw, o, mappingAction); xtw.WriteEndElement(); } break; } } if (request.args[i] == null) { throw new XmlRpcNullParameterException(String.Format( "Null method parameter #{0}", i + 1)); } xtw.WriteStartElement("", "param", ""); Serialize(xtw, request.args[i], mappingAction); xtw.WriteEndElement(); } }
XmlRpcResponse ReadResponse( XmlRpcRequest req, WebResponse webResp, Stream respStm, Type returnType) { HttpWebResponse httpResp = (HttpWebResponse)webResp; if (httpResp.StatusCode != HttpStatusCode.OK) { // status 400 is used for errors caused by the client // status 500 is used for server errors (not server application // errors which are returned as fault responses) if (httpResp.StatusCode == HttpStatusCode.BadRequest) throw new XmlRpcException(httpResp.StatusDescription); else throw new XmlRpcServerException(httpResp.StatusDescription); } XmlRpcSerializer serializer = new XmlRpcSerializer(); serializer.NonStandard = _nonStandard; Type retType = returnType; if (retType == null) retType = req.mi.ReturnType; XmlRpcResponse xmlRpcResp = serializer.DeserializeResponse(respStm, retType); return xmlRpcResp; }
XmlRpcRequest MakeXmlRpcRequest(WebRequest webReq, MethodInfo mi, object[] parameters, object clientObj, string xmlRpcMethod, Guid proxyId) { webReq.Method = "POST"; webReq.ContentType = "text/xml"; string rpcMethodName = GetRpcMethodName(clientObj, mi); XmlRpcRequest req = new XmlRpcRequest(rpcMethodName, parameters, mi, xmlRpcMethod, proxyId); return req; }
Header[] GetChannelHeaders( ITransportHeaders requestHeaders, XmlRpcRequest xmlRpcReq, Type svcType) { string requestUri = (string) requestHeaders["__RequestUri"]; XmlRpcServiceInfo svcInfo = XmlRpcServiceInfo.CreateServiceInfo(svcType); ArrayList hdrList = new ArrayList(); hdrList.Add(new Header("__Uri", requestUri)); hdrList.Add(new Header("__TypeName", svcType.AssemblyQualifiedName)); hdrList.Add(new Header("__MethodName", svcInfo.GetMethodName(xmlRpcReq.method))); hdrList.Add(new Header("__Args", xmlRpcReq.args)); return (Header[])hdrList.ToArray(typeof(Header)); }
// private methods // void SerializeMessage( IMethodCallMessage mcm, ref ITransportHeaders headers, ref Stream stream) { ITransportHeaders reqHeaders = new TransportHeaders(); reqHeaders["__Uri"] = mcm.Uri; reqHeaders["Content-Type"] = "text/xml; charset=\"utf-8\""; reqHeaders["__RequestVerb"] = "POST"; MethodInfo mi = (MethodInfo) mcm.MethodBase; string methodName = GetRpcMethodName(mi); XmlRpcRequest xmlRpcReq = new XmlRpcRequest(methodName, mcm.InArgs); // TODO: possibly call GetRequestStream from next sink in chain? // TODO: SoapClientFormatter sink uses ChunkedStream - check why? Stream stm = new MemoryStream(); XmlRpcSerializer serializer = new XmlRpcSerializer(); serializer.SerializeRequest(stm, xmlRpcReq); stm.Position = 0; headers = reqHeaders; stream = stm; }