SoapExtension Problem

Discussion in 'ASP .Net Web Services' started by lissbpp, Apr 2, 2008.

  1. lissbpp

    lissbpp Guest

    I’ve got a problem with a custom SoapExtension that uses encryption. I am
    encrypting the <soap:Body> element using this library:
    http://www.obviex.com/samples/EncryptionWithSalt.aspx. The error that I am
    getting is intermittent for users (if a user tries the service again many
    times it will work). The webservice gets around 50K requests per day and I
    get around 100-200 of these errors, which is a fairly low occurrence but it’s
    driving me nuts trying to figure out the problem.
    This is a smart client application that shares an assembly both on the agent
    and server that deals with the SoapExtension. The SoapExtension is
    configured in app.config and web.config respectively.
    My problem:
    For some reason I am getting SoapMessages that do not have a closing
    </soap:Body> & </soap:Envelope> on both the client and server. Exception
    reads: “Unexpected end of file has occurred. The following elements are not
    closed: soap:Body, soap:Envelope.â€
    Example soap message:
    <?xml version="1.0" encoding="utf-8"?><soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header><EncryptionHeader
    xmlns="http://mystuff.com " /></soap:Header><soap:Body>Gv/RcjUTg8ctp…[END]
    The SoapExtension:
    using System;
    using System.Text;
    using System.Web.Services.Protocols;
    using System.IO;
    using System.Web.Services;
    using System.Net;
    using System.Xml;
    using System.Text.RegularExpressions;

    namespace MyStuff
    {
    public class SoapExtension : SoapExtension
    {
    Stream _wireStream;
    Stream _applicationStream;

    public override Stream ChainStream(Stream stream)
    {
    _wireStream = stream;
    _applicationStream = new MemoryStream();
    return _applicationStream;
    }

    public override object GetInitializer(LogicalMethodInfo methodInfo,
    SoapExtensionAttribute attribute)
    {
    return null;
    }

    public override object GetInitializer(Type WebServiceType)
    {
    return null;
    }

    public override void Initialize(object initializer)
    {
    return;
    }

    void Copy(Stream from, Stream to)
    {
    TextReader reader = new StreamReader(from);
    TextWriter writer = new StreamWriter(to);
    writer.WriteLine(reader.ReadToEnd());
    writer.Flush();
    }

    private void WriteInput()
    {
    string soapMessage = string.Empty;
    try
    {
    XmlDocument soapXML = new XmlDocument();

    string passPhrase = "XXX"; // can be any string
    string initVector = "XXX†// must be 16 bytes

    // Before encrypting data, we will append plain text to a
    random
    // salt value, which will be between 4 and 8 bytes long
    (implicitly
    // used defaults).
    Crypto crypto = new Crypto(passPhrase, initVector);

    TextReader streamReader = new StreamReader(_wireStream);
    TextWriter streamWriter = new
    StreamWriter(_applicationStream);

    soapMessage = streamReader.ReadToEnd();

    soapXML.LoadXml(soapMessage);

    XmlNamespaceManager xmlnsSoap = new
    XmlNamespaceManager(soapXML.NameTable);
    xmlnsSoap.AddNamespace("soap",
    "http://schemas.xmlsoap.org/soap/envelope/");

    //NOTE: If we have an encryption header lets decrypt the
    packet <soap:Body> only
    XmlNode soapHeader =
    soapXML.SelectSingleNode("soap:Envelope/soap:Header", xmlnsSoap);
    if (soapHeader != null)
    {
    if (soapHeader["EncryptionHeader"] != null)
    {
    XmlNode bodyNode =
    soapXML.SelectSingleNode("soap:Envelope/soap:Body", xmlnsSoap);

    bodyNode.InnerXml = crypto.Decrypt(bodyNode.InnerXml);
    }
    }

    streamWriter.Write(soapXML.OuterXml);
    streamWriter.Flush();

    Copy(_wireStream, _applicationStream);
    //NOTE: Rewind stream to the begining
    _applicationStream.Position = 0;
    }
    catch (Exception ex)
    {
    ex.Data.Add("SoapMessage", soapMessage);
    ExceptionProvider.HandleException(ex, "Client");
    }
    }

    private void WriteOutput()
    {
    string soapMessage = string.Empty;
    try
    {
    _applicationStream.Position = 0;

    XmlDocument soapXML = new XmlDocument();

    string passPhrase = "XXX"; // can be any string
    string initVector = "XXX"; // must be 16 bytes

    // Before encrypting data, we will append plain text to a
    random
    // salt value, which will be between 4 and 8 bytes long
    (implicitly
    // used defaults).
    Crypto crypto = new Crypto(passPhrase, initVector);

    TextReader streamReader = new
    StreamReader(_applicationStream);
    TextWriter streamWriter = new StreamWriter(_wireStream);

    soapMessage = streamReader.ReadToEnd();

    soapXML.LoadXml(soapMessage);

    XmlNamespaceManager xmlnsSoap = new
    XmlNamespaceManager(soapXML.NameTable);
    xmlnsSoap.AddNamespace("soap",
    "http://schemas.xmlsoap.org/soap/envelope/");

    //NOTE: If we have an encryption header lets encrypt the
    packet <soap:Body> only
    XmlNode soapHeader =
    soapXML.SelectSingleNode("soap:Envelope/soap:Header", xmlnsSoap);

    if (soapHeader != null)
    {
    if (soapHeader["EncryptionHeader"] != null)
    {
    bodyNode.InnerText =
    crypto.Encrypt(bodyNode.InnerXml);
    }
    }

    streamWriter.Write(soapXML.OuterXml);
    streamWriter.Flush();

    //NOTE: Rewind stream to the begining
    Copy(_applicationStream, _wireStream);
    }
    catch (Exception ex)
    {
    ex.Data.Add("SoapMessage", soapMessage);
    ExceptionProvider.HandleException(ex, "Client");
    }
    }



    public override void ProcessMessage(SoapMessage message)
    {
    switch (message.Stage)
    {
    case SoapMessageStage.BeforeDeserialize:
    WriteInput();
    break;
    case SoapMessageStage.AfterDeserialize:
    break;
    case SoapMessageStage.BeforeSerialize:
    break;
    case SoapMessageStage.AfterSerialize:
    WriteOutput();
    break;
    default:
    throw new Exception("invalid stage");
    }
    }
    }
    }

    Any help would be greatly appreciated.
     
    lissbpp, Apr 2, 2008
    #1
    1. Advertising

  2. "lissbpp" <> wrote in message
    news:...
    > I’ve got a problem with a custom SoapExtension that uses encryption. I
    > am
    > encrypting the <soap:Body> element using this library:
    > http://www.obviex.com/samples/EncryptionWithSalt.aspx. The error that I
    > am
    > getting is intermittent for users (if a user tries the service again many
    > times it will work). The webservice gets around 50K requests per day and
    > I
    > get around 100-200 of these errors, which is a fairly low occurrence but
    > it’s
    > driving me nuts trying to figure out the problem.


    ....

    I don't have time now to read all of your code. However, I note that you
    have a number of objects that implement IDisposable, but which you are not
    using inside of a using block. For instance, in WriteInput, I believe I
    would have:

    using (TextReader streamReader = new StreamReader(_wireStream))
    {
    using (TextWriter streamWriter = new StreamWriter(_applicationStream))
    {
    // ...
    }
    }
    --
    --------------------------------------------------------------------------------
    John Saunders | MVP – Windows Server System – Connected System Developer
     
    John Saunders [MVP], Apr 2, 2008
    #2
    1. Advertising

  3. lissbpp

    lissbpp Guest

    I'm getting a "Stream was not readable" exception when I wrap the streams up
    in using blocks. The exception is not coming from my SoapExtension but from
    deep within the framework:

    <stackTrace> at System.IO.StreamReader..ctor(Stream stream, Encoding
    encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
    at
    System.Web.Services.Protocols.SoapHttpClientProtocol.GetReaderForMessage(SoapClientMessage message, Int32 bufferSize)
    at
    System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
    at
    System.Web.Services.Protocols.SoapHttpClientProtocol.InvokeAsyncCallback(IAsyncResult result)</stackTrace>

    "John Saunders [MVP]" wrote:

    >
    >
    > "lissbpp" <> wrote in message
    > news:...
    > > I’ve got a problem with a custom SoapExtension that uses encryption. I
    > > am
    > > encrypting the <soap:Body> element using this library:
    > > http://www.obviex.com/samples/EncryptionWithSalt.aspx. The error that I
    > > am
    > > getting is intermittent for users (if a user tries the service again many
    > > times it will work). The webservice gets around 50K requests per day and
    > > I
    > > get around 100-200 of these errors, which is a fairly low occurrence but
    > > it’s
    > > driving me nuts trying to figure out the problem.

    >
    > ....
    >
    > I don't have time now to read all of your code. However, I note that you
    > have a number of objects that implement IDisposable, but which you are not
    > using inside of a using block. For instance, in WriteInput, I believe I
    > would have:
    >
    > using (TextReader streamReader = new StreamReader(_wireStream))
    > {
    > using (TextWriter streamWriter = new StreamWriter(_applicationStream))
    > {
    > // ...
    > }
    > }
    > --
    > --------------------------------------------------------------------------------
    > John Saunders | MVP – Windows Server System – Connected System Developer
    >
    >
    >
     
    lissbpp, Apr 3, 2008
    #3
  4. "lissbpp" <> wrote in message
    news:...
    > I'm getting a "Stream was not readable" exception when I wrap the streams
    > up
    > in using blocks. The exception is not coming from my SoapExtension but
    > from
    > deep within the framework:
    >
    > <stackTrace> at System.IO.StreamReader..ctor(Stream stream, Encoding
    > encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
    > at
    > System.Web.Services.Protocols.SoapHttpClientProtocol.GetReaderForMessage(SoapClientMessage
    > message, Int32 bufferSize)
    > at
    > System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage
    > message, WebResponse response, Stream responseStream, Boolean asyncCall)
    > at
    > System.Web.Services.Protocols.SoapHttpClientProtocol.InvokeAsyncCallback(IAsyncResult
    > result)</stackTrace>


    Did you get that error when wrapping the StreamReader/StreamWriter? I can
    imagine that StreamReader.Dispose might close the corresponding stream,
    which would be a problem for .NET.
    --
    --------------------------------------------------------------------------------
    John Saunders | MVP – Windows Server System – Connected System Developer
     
    John Saunders [MVP], Apr 3, 2008
    #4
  5. lissbpp

    lissbpp Guest

    Indeed that's what I did and that's probably why the runtime is blowing
    chunks when disposing the stream.

    "John Saunders [MVP]" wrote:

    >
    >
    > "lissbpp" <> wrote in message
    > news:...
    > > I'm getting a "Stream was not readable" exception when I wrap the streams
    > > up
    > > in using blocks. The exception is not coming from my SoapExtension but
    > > from
    > > deep within the framework:
    > >
    > > <stackTrace> at System.IO.StreamReader..ctor(Stream stream, Encoding
    > > encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
    > > at
    > > System.Web.Services.Protocols.SoapHttpClientProtocol.GetReaderForMessage(SoapClientMessage
    > > message, Int32 bufferSize)
    > > at
    > > System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage
    > > message, WebResponse response, Stream responseStream, Boolean asyncCall)
    > > at
    > > System.Web.Services.Protocols.SoapHttpClientProtocol.InvokeAsyncCallback(IAsyncResult
    > > result)</stackTrace>

    >
    > Did you get that error when wrapping the StreamReader/StreamWriter? I can
    > imagine that StreamReader.Dispose might close the corresponding stream,
    > which would be a problem for .NET.
    > --
    > --------------------------------------------------------------------------------
    > John Saunders | MVP – Windows Server System – Connected System Developer
    >
    >
    >
     
    lissbpp, Apr 3, 2008
    #5
  6. lissbpp

    lissbpp Guest

    Any other suggestions?

    "John Saunders [MVP]" wrote:

    >
    >
    > "lissbpp" <> wrote in message
    > news:...
    > > I'm getting a "Stream was not readable" exception when I wrap the streams
    > > up
    > > in using blocks. The exception is not coming from my SoapExtension but
    > > from
    > > deep within the framework:
    > >
    > > <stackTrace> at System.IO.StreamReader..ctor(Stream stream, Encoding
    > > encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
    > > at
    > > System.Web.Services.Protocols.SoapHttpClientProtocol.GetReaderForMessage(SoapClientMessage
    > > message, Int32 bufferSize)
    > > at
    > > System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage
    > > message, WebResponse response, Stream responseStream, Boolean asyncCall)
    > > at
    > > System.Web.Services.Protocols.SoapHttpClientProtocol.InvokeAsyncCallback(IAsyncResult
    > > result)</stackTrace>

    >
    > Did you get that error when wrapping the StreamReader/StreamWriter? I can
    > imagine that StreamReader.Dispose might close the corresponding stream,
    > which would be a problem for .NET.
    > --
    > --------------------------------------------------------------------------------
    > John Saunders | MVP – Windows Server System – Connected System Developer
    >
    >
    >
     
    lissbpp, Apr 4, 2008
    #6
  7. lissbpp

    Guest Guest

    "lissbpp" <> wrote in message
    news:...
    > Any other suggestions?


    I'm afraid I have no other suggestions beyond what we've discussed in the
    forums.
    --
    --------------------------------------------------------------------------------
    John Saunders | MVP – Windows Server System – Connected System Developer
     
    Guest, Apr 5, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. fred carter

    SoapExtension & Http headers

    fred carter, Apr 2, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    815
    fred carter
    Apr 2, 2004
  2. Ted A W
    Replies:
    0
    Views:
    381
    Ted A W
    Jan 12, 2006
  3. VSK
    Replies:
    0
    Views:
    268
  4. VSK
    Replies:
    0
    Views:
    109
  5. VSK
    Replies:
    0
    Views:
    132
Loading...

Share This Page