public byte[] TwoWayRequest(WsWsaHeader header, WsXmlDocument envelope) { WsXmlNode tempNode; WsFault fault = new WsFault(); if ((tempNode = envelope.SelectSingleNode("Body/TwoWayRequest/X", false)) == null) { return(fault.RaiseFault(header, WsExceptionFaultType.XmlException, "Body/TwoWay X value is missing.")); } int X = Convert.ToInt32(tempNode.Value); if ((tempNode = envelope.SelectSingleNode("Body/TwoWayRequest/Y", false)) == null) { return(fault.RaiseFault(header, WsExceptionFaultType.XmlException, "Body/TwoWay Y value is missing.")); } int Y = Convert.ToInt32(tempNode.Value); Debug.Print(""); Debug.Print("X = " + X.ToString() + " Y = " + Y.ToString()); Debug.Print(X.ToString() + " + " + Y.ToString() + " = " + ((int)(X + Y)).ToString()); Debug.Print(""); return(TwoWayResponse(header, X + Y)); }
/// <summary> /// Parses a Udp transport message and builds a header object and envelope document then calls processRequest /// on a service endpoint contained. /// </summary> /// <param name="soapRequest">A byte array containing a raw soap request message. If null no check is performed.</param> /// <param name="messageCheck">A WsMessageCheck objct used to test for duplicate request.</param> /// <param name="remoteEP">The remote endpoint address of the requestor.</param> /// <returns>A byte array containing a soap response message returned from a service endpoint.</returns> public WsMessage ProcessRequestMessage(RequestContext request) { // Parse and validate the soap message WsMessage message = request.Message; WsWsaHeader header = message.Header; // Check Udp service endpoints collection for a target service. int count = m_serviceEndpoints.Count; // DO NOT USE the subscript operator for endpoint addresses (WsServiceEndpoints[EnpointAddress]) // for local host testing there are multiple endpoints with the same address but different operations for (int i = 0; i < count; i++) { IWsServiceEndpoint serviceEndpoint = m_serviceEndpoints[i]; if (serviceEndpoint.EndpointAddress == header.To) { if (serviceEndpoint.ServiceOperations[header.Action] != null) { // Don't block discovery processes. serviceEndpoint.BlockingCall = false; try { return(serviceEndpoint.ProcessRequest(message)); } catch (WsFaultException e) { return(WsFault.GenerateFaultResponse(e, request.Version)); } catch { // If a valid Action is not found, fault return(WsFault.GenerateFaultResponse(header, WsFaultType.WsaDestinationUnreachable, "To: " + header.To + " Action: " + header.Action, request.Version)); } } } } // Return null if service endpoint was not found System.Ext.Console.Write("Udp service endpoint was not found."); System.Ext.Console.Write(" Endpoint Address: " + header.To); System.Ext.Console.Write(" Action: " + header.Action); return(null); }
public byte[] OneWay(WsWsaHeader header, WsXmlDocument envelope) { WsXmlNode tempNode; WsFault fault = new WsFault(); if ((tempNode = envelope.SelectSingleNode("Body/OneWay/Param", false)) == null) { return(fault.RaiseFault(header, WsExceptionFaultType.XmlException, "Body/OneWay is missing.")); } int number = Convert.ToInt32(tempNode.Value); Debug.Print(""); Debug.Print("Integer = " + tempNode.Value); Debug.Print(""); byte[] response = new byte[0]; return(response); }
/// <summary> /// HttpServer Socket Listener /// </summary> public void Listen() { // Create listener and start listening while (m_isStarted) { try { _Bind.RequestContext context = m_replyChannel.ReceiveRequest(); // The context returned by m_httpListener.GetContext(); can be null in case the service was stopped. if (context != null) { WsHttpMessageProcessor processor = new WsHttpMessageProcessor(m_serviceEndpoints, context); if (m_threadManager.ThreadsAvailable == false) { WsWsaHeader header = new WsWsaHeader(); context.Reply(WsFault.GenerateFaultResponse(header, WsFaultType.WsaEndpointUnavailable, "Service Unavailable (busy)", context.Version)); System.Ext.Console.Write("Http max thread count exceeded. Request ignored."); } else { // Try to get a processing thread and process the request m_threadManager.StartNewThread(processor); } } } catch { if (!m_isStarted) { break; } } } }
private XmlReader ProcessResponse(byte[] response, String messageID, String action) { WsWsaHeader header = new WsWsaHeader(); XmlReader reader = WsSoapMessageParser.ParseSoapMessage(response, ref header, m_version); if (header.Action == m_version.AddressingNamespace + "/fault") { WsFault.ParseFaultResponseAndThrow(reader); } else if (header.Action != m_version.EventingNamespace + "/" + action) { throw new XmlException(); } // Make sure this response matches the request if (header.RelatesTo != messageID) { throw new XmlException(); } return(reader); }
private XmlReader ProcessResponse(byte[] response, String messageID, String action) { WsWsaHeader header; XmlReader reader; reader = WsSoapMessageParser.ParseSoapMessage(response, out header); try { if ( (header.Action == WsWellKnownUri.WsaNamespaceUri_2004_08 + "/fault") || (header.Action == WsWellKnownUri.WsaNamespaceUri_2005_08 + "/fault") ) { WsFault.ParseFaultResponseAndThrow(reader); } else if (header.Action != WsWellKnownUri.WseNamespaceUri + "/" + action) { throw new XmlException(); } // Make sure this response matches the request if (header.RelatesTo != messageID) { throw new XmlException("Invalid message ID in response. Id does not match request ID."); } return(reader); } catch { // if something's wrong, close the reader, and rethrow the exception reader.Close(); throw; } }
internal void ParseHeader(XmlReader reader, ProtocolVersion version) { RequiredHeaderElement headerElements = RequiredHeaderElement.None; ProtocolVersion altVer = version is ProtocolVersion10 ? (ProtocolVersion) new ProtocolVersion11() : (ProtocolVersion) new ProtocolVersion10(); bool isFault = false; try { reader.ReadStartElement("Header", WsWellKnownUri.SoapNamespaceUri); while (true) { if (reader.IsStartElement()) { if (reader.NamespaceURI == version.AddressingNamespace || reader.NamespaceURI == altVer.AddressingNamespace) { switch (reader.LocalName) { case "MessageID": if ((_messageId = reader.ReadElementString()) == String.Empty) { throw new XmlException("MessageID"); } headerElements |= RequiredHeaderElement.MessageID; break; case "RelatesTo": if ((_relatesTo = reader.ReadElementString()) == String.Empty) { throw new XmlException("RelatesTo"); } break; case "To": if ((_to = reader.ReadElementString()) == String.Empty) { throw new XmlException("To"); } // If this is a URI peal off the transport address if (To.IndexOf("http://") == 0) { int pathIndex = _to.Substring(7).IndexOf('/'); if (pathIndex != -1) { _to = _to.Substring(pathIndex + 8); } } headerElements |= RequiredHeaderElement.To; break; case "Action": if ((_action = reader.ReadElementString()) == String.Empty) { throw new XmlException("Action"); } if (_action == version.AddressingNamespace + "/fault") { isFault = true; } headerElements |= RequiredHeaderElement.Action; break; case "From": #if DEBUG int depth = reader.Depth; #endif _from = new WsWsaEndpointRef(reader, reader.NamespaceURI); #if DEBUG Debug.Assert(XmlReaderHelper.HasReadCompleteNode(depth, reader)); #endif break; case "ReplyTo": #if DEBUG depth = reader.Depth; #endif _replyTo = new WsWsaEndpointRef(reader, reader.NamespaceURI); #if DEBUG Debug.Assert(XmlReaderHelper.HasReadCompleteNode(depth, reader)); #endif break; case "FaultTo": #if DEBUG depth = reader.Depth; #endif _faultTo = new WsWsaEndpointRef(reader, reader.NamespaceURI); #if DEBUG Debug.Assert(XmlReaderHelper.HasReadCompleteNode(depth, reader)); #endif break; default: reader.Skip(); //unknown item from WSA namespace, should we store it? break; } } else { // unknown item, need to store it for future reference #if DEBUG int depth = reader.Depth; #endif _any.Add(new WsXmlNode(reader)); #if DEBUG Debug.Assert(XmlReaderHelper.HasReadCompleteNode(depth, reader)); #endif } } else { break; } } reader.ReadEndElement(); // Header } catch (XmlException e) { throw new WsFaultException(this, WsFaultType.WsaInvalidMessageInformationHeader, e.ToString()); } if (isFault) { WsFault.ThrowFaultException(reader, this); } // add more logic for determining required headers? it is not this simple //if (headerElements != RequiredHeaderElement.All) //{ // throw new WsFaultException(this, WsFaultType.WsaMessageInformationHeaderRequired); //} }
/// <summary> /// Parses a transport message and builds a header object and envelope document then calls processRequest /// on a service endpoint. /// </summary> /// <param name="soapRequest">WsRequestMessage object containing a raw soap message or mtom soap request.</param> /// <returns>WsResponseMessage object containing the soap response returned from a service endpoint.</returns> private WsMessage ProcessRequestMessage(WsMessage soapRequest) { // Parse and validate the soap message WsWsaHeader header; XmlReader reader; try { reader = WsSoapMessageParser.ParseSoapMessage(soapRequest.Message, out header); } catch (WsFaultException e) { return(WsFault.GenerateFaultResponse(e)); } try { // Now check for implementation specific service endpoints. IWsServiceEndpoint serviceEndpoint = null; string endpointAddress = null; // If this is Uri convert it if (header.To.IndexOf("urn") == 0 || header.To.IndexOf("http") == 0) { // Convert to address to Uri Uri toUri; try { toUri = new Uri(header.To); } catch { System.Ext.Console.Write("Unsupported Header.To Uri format: " + header.To); return(WsFault.GenerateFaultResponse(header, WsFaultType.ArgumentException, "Unsupported Header.To Uri format")); } // Convert the to address to a Urn:uuid if it is an Http endpoint if (toUri.Scheme == "urn") { endpointAddress = toUri.AbsoluteUri; } else if (toUri.Scheme == "http") { endpointAddress = "urn:uuid:" + toUri.AbsoluteUri.Substring(1); } else { endpointAddress = header.To; } } else { endpointAddress = "urn:uuid:" + header.To; } // Look for a service at the requested endpoint that contains an operation matching the Action // This hack is required because service spec writers determined that more than one service type // can live at a single endpoint address. Why you would want to break the object model and allow // this feature is unknown so for now we must hack. bool eventingReqFlag = true; for (int i = 0; i < m_serviceEndpoints.Count; ++i) { if (m_serviceEndpoints[i].EndpointAddress == endpointAddress) { if (m_serviceEndpoints[i].ServiceOperations[header.Action] != null) { serviceEndpoint = m_serviceEndpoints[i]; eventingReqFlag = false; break; } } } // Worst part of the hack: If no matching endpoint is found assume this is an event subscription // request and call the base eventing methods on any class. They had to be Global because of this feature. // Now the subscription manager must determine globally that a suitable web service is found. Yuch!! if (eventingReqFlag) { serviceEndpoint = m_serviceEndpoints[0]; } // If a matching service endpoint is found call operation if (serviceEndpoint != null) { // If this is mtom, copy the requests body parts to the hosted services body parts // prior to making the call if (soapRequest.MessageType == WsMessageType.Mtom) { serviceEndpoint.BodyParts = soapRequest.BodyParts; } // Process the request byte[] response; try { response = serviceEndpoint.ProcessRequest(header, reader); } catch (WsFaultException e) { return(WsFault.GenerateFaultResponse(e)); } catch (Exception e) { return(WsFault.GenerateFaultResponse(header, WsFaultType.Exception, e.ToString())); } // If the message response type is Soap return a SoapMessage type if (serviceEndpoint.MessageType == WsMessageType.Soap) { if (response == null) { return(null); } return(new WsMessage(response)); } // If the response is Mtom build an mtom response message else // if (serviceEndpoint.MessageType == WsMessageType.Mtom) { return(new WsMessage(serviceEndpoint.BodyParts)); } } // Unreachable endpoint requested. Generate fault response return(WsFault.GenerateFaultResponse(header, WsFaultType.WsaDestinationUnreachable, "Unknown service endpoint")); } finally { reader.Close(); } }
/// <summary> /// Parses a transport message and builds a header object and envelope document then calls processRequest /// on a service endpoint. /// </summary> /// <param name="soapRequest">WsRequestMessage object containing a raw soap message or mtom soap request.</param> /// <returns>WsResponseMessage object containing the soap response returned from a service endpoint.</returns> private WsMessage ProcessRequestMessage(WsMessage soapRequest) { // Now check for implementation specific service endpoints. IWsServiceEndpoint serviceEndpoint = null; string endpointAddress; WsWsaHeader header = soapRequest.Header; // If this is Uri convert it if (header.To.IndexOf("urn") == 0 || header.To.IndexOf("http") == 0) { // Convert to address to Uri Uri toUri; try { toUri = new Uri(header.To); } catch { System.Ext.Console.Write("Unsupported Header.To Uri format: " + header.To); return(WsFault.GenerateFaultResponse(header, WsFaultType.ArgumentException, "Unsupported Header.To Uri format", m_context.Version)); } // Convert the to address to a Urn:uuid if it is an Http endpoint if (toUri.Scheme == "urn") { endpointAddress = toUri.AbsoluteUri; } else if (toUri.Scheme == "http") { endpointAddress = "urn:uuid:" + toUri.AbsoluteUri.Substring(1); } else { endpointAddress = header.To; } } else { endpointAddress = "urn:uuid:" + header.To; } // Look for a service at the requested endpoint that contains an operation matching the Action IWsServiceEndpoint ep = m_serviceEndpoints[endpointAddress]; if (ep != null) { if (ep.ServiceOperations[header.Action] != null) { serviceEndpoint = ep; } else { ep = m_serviceEndpoints[0]; // mex endpoint if (ep.ServiceOperations[header.Action] != null) { serviceEndpoint = ep; } } } // If a matching service endpoint is found call operation if (serviceEndpoint != null) { // Process the request WsMessage response; try { response = serviceEndpoint.ProcessRequest(soapRequest); } catch (WsFaultException e) { return(WsFault.GenerateFaultResponse(e, m_context.Version)); } catch (Exception e) { return(WsFault.GenerateFaultResponse(header, WsFaultType.Exception, e.ToString(), m_context.Version)); } return(response); } // Unreachable endpoint requested. Generate fault response return(WsFault.GenerateFaultResponse(header, WsFaultType.WsaDestinationUnreachable, "Unknown service endpoint", m_context.Version)); }