ROT 128 Stream Upgrade Sample, Part 5

Today is the last part of the stream upgrade sample. We've already looked at all the parts required to make the stream upgrade operate: stream, binding element, provider, initiator, and acceptor. All that's left today is to build a test harness for the code and run it. Here are the previous parts of this series for reference. It's taken a little longer than I expected to get this out due to some server difficulties.

  1. Stream class
  2. Binding element
  3. Provider
  4. Initiator and acceptor

I've created a simple service with one operation for demonstration purposes.

 using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

namespace Microsoft.ServiceModel.Samples
{
   [ServiceContract]
   interface ICalculator
   {
      [OperationContract]
      int Add(int x, int y);
   }

   class CalculatorService : ICalculator
   {
      public int Add(int x, int y)
      {
         return x + y;
      }
   }

   class service
   {
      static void Main(string[] args)
      {
         Binding binding = new CustomBinding(
            new ROT128StreamUpgradeBindingElement(),
            new TextMessageEncodingBindingElement(),
            new TcpTransportBindingElement()
         );
         ServiceHost host = new ServiceHost(typeof(CalculatorService), new Uri("net.tcp://localhost/"));
         host.AddServiceEndpoint(typeof(ICalculator), binding, "");
         ServiceMetadataBehavior mexBehavior = new ServiceMetadataBehavior();
         host.Description.Behaviors.Add(mexBehavior);
         Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
         host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");
         host.Open();
         Console.WriteLine("Press <ENTER> to quit.");
         Console.ReadLine();
         host.Close();
      }
   }
}

I've enabled metadata so you can generate the client proxy yourself using svcutil. The attachments to this post contain one such proxy. The client just connects to the service, makes one operation call, and then closes the connection.

 using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Microsoft.ServiceModel.Samples
{
   class client
   {
      static void Main(string[] args)
      {
         Binding binding = new CustomBinding(
            new ROT128StreamUpgradeBindingElement(),
            new TextMessageEncodingBindingElement(),
            new TcpTransportBindingElement()
         );
         CalculatorClient client = new CalculatorClient(binding, new EndpointAddress("net.tcp://localhost/"));
         client.Open();
         if (client.Add(1, 2) != 3)
         {
            throw new Exception("Operation call failed!");
         }
         client.Close();
      }
   }
}

Let's start by looking at what happens on the client side. Remember that the debug output is at the start of the Read or Write method of the stream. That means that when writing, we see the stream before rotation. When reading, we see the stream after one rotation. You can directly match up the reads and writes between the two sides.

 [WRITE] 1 bytes
 0C                                             .
[READ] 1 bytes
 8B                                             .
[WRITE] 512 bytes
 06 FD 03 3C 73 3A 45 6E 76 65 6C 6F 70 65 20   ...<s:Envelope 
 78 6D 6C 6E 73 3A 73 3D 22 68 74 74 70 3A 2F   xmlns:s="http:/
 2F 77 77 77 2E 77 33 2E 6F 72 67 2F 32 30 30   /www.w3.org/200
 33 2F 30 35 2F 73 6F 61 70 2D 65 6E 76 65 6C   3/05/soap-envel
 6F 70 65 22 20 78 6D 6C 6E 73 3A 61 3D 22 68   ope" xmlns:a="h
 74 74 70 3A 2F 2F 77 77 77 2E 77 33 2E 6F 72   ttp://www.w3.or
 67 2F 32 30 30 35 2F 30 38 2F 61 64 64 72 65   g/2005/08/addre
 73 73 69 6E 67 22 3E 3C 73 3A 48 65 61 64 65   ssing"><s:Heade
 72 3E 3C 61 3A 41 63 74 69 6F 6E 20 73 3A 6D   r><a:Action s:m
 75 73 74 55 6E 64 65 72 73 74 61 6E 64 3D 22   ustUnderstand="
 31 22 3E 68 74 74 70 3A 2F 2F 74 65 6D 70 75   1">https://tempu
 72 69 2E 6F 72 67 2F 49 43 61 6C 63 75 6C 61   ri.org/ICalcula
 74 6F 72 2F 41 64 64 3C 2F 61 3A 41 63 74 69   tor/Add</a:Acti
 6F 6E 3E 3C 61 3A 4D 65 73 73 61 67 65 49 44   on><a:MessageID
 3E 75 72 6E 3A 75 75 69 64 3A 35 39 66 63 39   >urn:uuid:59fc9
 66 63 39 2D 65 33 65 32 2D 34 62 63 31 2D 62   fc9-e3e2-4bc1-b
 36 33 32 2D 34 61 33 38 39 39 30 32 34 61 62   632-4a3899024ab
 39 3C 2F 61 3A 4D 65 73 73 61 67 65 49 44 3E   9</a:MessageID>
 3C 61 3A 52 65 70 6C 79 54 6F 3E 3C 61 3A 41   <a:ReplyTo><a:A
 64 64 72 65 73 73 3E 68 74 74 70 3A 2F 2F 77   ddress>https://w
 77 77 2E 77 33 2E 6F 72 67 2F 32 30 30 35 2F   ww.w3.org/2005/
 30 38 2F 61 64 64 72 65 73 73 69 6E 67 2F 61   08/addressing/a
 6E 6F 6E 79 6D 6F 75 73 3C 2F 61 3A 41 64 64   nonymous</a:Add
 72 65 73 73 3E 3C 2F 61 3A 52 65 70 6C 79 54   ress></a:ReplyT
 6F 3E 3C 61 3A 54 6F 20 73 3A 6D 75 73 74 55   o><a:To s:mustU
 6E 64 65 72 73 74 61 6E 64 3D 22 31 22 3E 6E   nderstand="1">n
 65 74 2E 74 63 70 3A 2F 2F 6C 6F 63 61 6C 68   et.tcp://localh
 6F 73 74 2F 3C 2F 61 3A 54 6F 3E 3C 2F 73 3A   ost/</a:To></s:
 48 65 61 64 65 72 3E 3C 73 3A 42 6F 64 79 3E   Header><s:Body>
 3C 41 64 64 20 78 6D 6C 6E 73 3D 22 68 74 74   <Add xmlns="htt
 70 3A 2F 2F 74 65 6D 70 75 72 69 2E 6F 72 67   p://tempuri.org
 2F 22 3E 3C 78 3E 31 3C 2F 78 3E 3C 79 3E 32   /"><x>1</x><y>2
 3C 2F 79 3E 3C 2F 41 64 64 3E 3C 2F 73 3A 42   </y></Add></s:B
 6F 64 79 3E 3C 2F 73 3A 45 6E 76 65 6C 6F 70   ody></s:Envelop
 65 3E                                          e>
[READ] 478 bytes
 86 5B 83 BC F3 BA C5 EE F6 E5 EC EF F0 E5 A0   .[.............
 F8 ED EC EE F3 BA F3 BD A2 E8 F4 F4 F0 BA AF   ...............
 AF F7 F7 F7 AE F7 B3 AE EF F2 E7 AF B2 B0 B0   ...............
 B3 AF B0 B5 AF F3 EF E1 F0 AD E5 EE F6 E5 EC   ...............
 EF F0 E5 A2 A0 F8 ED EC EE F3 BA E1 BD A2 E8   ...............
 F4 F4 F0 BA AF AF F7 F7 F7 AE F7 B3 AE EF F2   ...............
 E7 AF B2 B0 B0 B5 AF B0 B8 AF E1 E4 E4 F2 E5   ...............
 F3 F3 E9 EE E7 A2 BE BC F3 BA C8 E5 E1 E4 E5   ...............
 F2 BE BC E1 BA C1 E3 F4 E9 EF EE A0 F3 BA ED   ...............
 F5 F3 F4 D5 EE E4 E5 F2 F3 F4 E1 EE E4 BD A2   ...............
 B1 A2 BE E8 F4 F4 F0 BA AF AF F4 E5 ED F0 F5   ...............
 F2 E9 AE EF F2 E7 AF C9 C3 E1 EC E3 F5 EC E1   ...............
 F4 EF F2 AF C1 E4 E4 D2 E5 F3 F0 EF EE F3 E5   ...............
 BC AF E1 BA C1 E3 F4 E9 EF EE BE BC E1 BA D2   ...............
 E5 EC E1 F4 E5 F3 D4 EF BE F5 F2 EE BA F5 F5   ...............
 E9 E4 BA B5 B9 E6 E3 B9 E6 E3 B9 AD E5 B3 E5   ...............
 B2 AD B4 E2 E3 B1 AD E2 B6 B3 B2 AD B4 E1 B3   ...............
 B8 B9 B9 B0 B2 B4 E1 E2 B9 BC AF E1 BA D2 E5   ...............
 EC E1 F4 E5 F3 D4 EF BE BC E1 BA D4 EF A0 F3   ...............
 BA ED F5 F3 F4 D5 EE E4 E5 F2 F3 F4 E1 EE E4   ...............
 BD A2 B1 A2 BE E8 F4 F4 F0 BA AF AF F7 F7 F7   ...............
 AE F7 B3 AE EF F2 E7 AF B2 B0 B0 B5 AF B0 B8   ...............
 AF E1 E4 E4 F2 E5 F3 F3 E9 EE E7 AF E1 EE EF   ...............
 EE F9 ED EF F5 F3 BC AF E1 BA D4 EF BE BC AF   ...............
 F3 BA C8 E5 E1 E4 E5 F2 BE BC F3 BA C2 EF E4   ...............
 F9 BE BC C1 E4 E4 D2 E5 F3 F0 EF EE F3 E5 A0   ...............
 F8 ED EC EE F3 BD A2 E8 F4 F4 F0 BA AF AF F4   ...............
 E5 ED F0 F5 F2 E9 AE EF F2 E7 AF A2 BE BC C1   ...............
 E4 E4 D2 E5 F3 F5 EC F4 BE B3 BC AF C1 E4 E4   ...............
 D2 E5 F3 F5 EC F4 BE BC AF C1 E4 E4 D2 E5 F3   ...............
 F0 EF EE F3 E5 BE BC AF F3 BA C2 EF E4 F9 BE   ...............
 BC AF F3 BA C5 EE F6 E5 EC EF F0 E5 BE         .............
[WRITE] 1 bytes
 07                                             .
[READ] 1 bytes
 87                                             .

The start of each block is part of our framing format. You can clearly see the three sets of calls. The first set are single bytes for the end of connection establishment. The second set are the actual transfers for the service call. You can see the request on this side but the reply is obscured by the stream rotation as we have not yet undone the transformation. The third set are single bytes for connection termination.

Here's the same view showing what the server received and sent. Everything that was obscured on the client side is visible on the server side and vice versa.

 Press <ENTER> to quit.
[READ] 1 bytes
 8C                                             .
[WRITE] 1 bytes
 0B                                             .
[READ] 512 bytes
 86 7D 83 BC F3 BA C5 EE F6 E5 EC EF F0 E5 A0   .}.............
 F8 ED EC EE F3 BA F3 BD A2 E8 F4 F4 F0 BA AF   ...............
 AF F7 F7 F7 AE F7 B3 AE EF F2 E7 AF B2 B0 B0   ...............
 B3 AF B0 B5 AF F3 EF E1 F0 AD E5 EE F6 E5 EC   ...............
 EF F0 E5 A2 A0 F8 ED EC EE F3 BA E1 BD A2 E8   ...............
 F4 F4 F0 BA AF AF F7 F7 F7 AE F7 B3 AE EF F2   ...............
 E7 AF B2 B0 B0 B5 AF B0 B8 AF E1 E4 E4 F2 E5   ...............
 F3 F3 E9 EE E7 A2 BE BC F3 BA C8 E5 E1 E4 E5   ...............
 F2 BE BC E1 BA C1 E3 F4 E9 EF EE A0 F3 BA ED   ...............
 F5 F3 F4 D5 EE E4 E5 F2 F3 F4 E1 EE E4 BD A2   ...............
 B1 A2 BE E8 F4 F4 F0 BA AF AF F4 E5 ED F0 F5   ...............
 F2 E9 AE EF F2 E7 AF C9 C3 E1 EC E3 F5 EC E1   ...............
 F4 EF F2 AF C1 E4 E4 BC AF E1 BA C1 E3 F4 E9   ...............
 EF EE BE BC E1 BA CD E5 F3 F3 E1 E7 E5 C9 C4   ...............
 BE F5 F2 EE BA F5 F5 E9 E4 BA B5 B9 E6 E3 B9   ...............
 E6 E3 B9 AD E5 B3 E5 B2 AD B4 E2 E3 B1 AD E2   ...............
 B6 B3 B2 AD B4 E1 B3 B8 B9 B9 B0 B2 B4 E1 E2   ...............
 B9 BC AF E1 BA CD E5 F3 F3 E1 E7 E5 C9 C4 BE   ...............
 BC E1 BA D2 E5 F0 EC F9 D4 EF BE BC E1 BA C1   ...............
 E4 E4 F2 E5 F3 F3 BE E8 F4 F4 F0 BA AF AF F7   ...............
 F7 F7 AE F7 B3 AE EF F2 E7 AF B2 B0 B0 B5 AF   ...............
 B0 B8 AF E1 E4 E4 F2 E5 F3 F3 E9 EE E7 AF E1   ...............
 EE EF EE F9 ED EF F5 F3 BC AF E1 BA C1 E4 E4   ...............
 F2 E5 F3 F3 BE BC AF E1 BA D2 E5 F0 EC F9 D4   ...............
 EF BE BC E1 BA D4 EF A0 F3 BA ED F5 F3 F4 D5   ...............
 EE E4 E5 F2 F3 F4 E1 EE E4 BD A2 B1 A2 BE EE   ...............
 E5 F4 AE F4 E3 F0 BA AF AF EC EF E3 E1 EC E8   ...............
 EF F3 F4 AF BC AF E1 BA D4 EF BE BC AF F3 BA   ...............
 C8 E5 E1 E4 E5 F2 BE BC F3 BA C2 EF E4 F9 BE   ...............
 BC C1 E4 E4 A0 F8 ED EC EE F3 BD A2 E8 F4 F4   ...............
 F0 BA AF AF F4 E5 ED F0 F5 F2 E9 AE EF F2 E7   ...............
 AF A2 BE BC F8 BE B1 BC AF F8 BE BC F9 BE B2   ...............
 BC AF F9 BE BC AF C1 E4 E4 BE BC AF F3 BA C2   ...............
 EF E4 F9 BE BC AF F3 BA C5 EE F6 E5 EC EF F0   ...............
 E5 BE                                          ..
[WRITE] 478 bytes
 06 DB 03 3C 73 3A 45 6E 76 65 6C 6F 70 65 20   ...<s:Envelope 
 78 6D 6C 6E 73 3A 73 3D 22 68 74 74 70 3A 2F   xmlns:s="http:/
 2F 77 77 77 2E 77 33 2E 6F 72 67 2F 32 30 30   /www.w3.org/200
 33 2F 30 35 2F 73 6F 61 70 2D 65 6E 76 65 6C   3/05/soap-envel
 6F 70 65 22 20 78 6D 6C 6E 73 3A 61 3D 22 68   ope" xmlns:a="h
 74 74 70 3A 2F 2F 77 77 77 2E 77 33 2E 6F 72   ttp://www.w3.or
 67 2F 32 30 30 35 2F 30 38 2F 61 64 64 72 65   g/2005/08/addre
 73 73 69 6E 67 22 3E 3C 73 3A 48 65 61 64 65   ssing"><s:Heade
 72 3E 3C 61 3A 41 63 74 69 6F 6E 20 73 3A 6D   r><a:Action s:m
 75 73 74 55 6E 64 65 72 73 74 61 6E 64 3D 22   ustUnderstand="
 31 22 3E 68 74 74 70 3A 2F 2F 74 65 6D 70 75   1">https://tempu
 72 69 2E 6F 72 67 2F 49 43 61 6C 63 75 6C 61   ri.org/ICalcula
 74 6F 72 2F 41 64 64 52 65 73 70 6F 6E 73 65   tor/AddResponse
 3C 2F 61 3A 41 63 74 69 6F 6E 3E 3C 61 3A 52   </a:Action><a:R
 65 6C 61 74 65 73 54 6F 3E 75 72 6E 3A 75 75   elatesTo>urn:uu
 69 64 3A 35 39 66 63 39 66 63 39 2D 65 33 65   id:59fc9fc9-e3e
 32 2D 34 62 63 31 2D 62 36 33 32 2D 34 61 33   2-4bc1-b632-4a3
 38 39 39 30 32 34 61 62 39 3C 2F 61 3A 52 65   899024ab9</a:Re
 6C 61 74 65 73 54 6F 3E 3C 61 3A 54 6F 20 73   latesTo><a:To s
 3A 6D 75 73 74 55 6E 64 65 72 73 74 61 6E 64   :mustUnderstand
 3D 22 31 22 3E 68 74 74 70 3A 2F 2F 77 77 77   ="1">https://www
 2E 77 33 2E 6F 72 67 2F 32 30 30 35 2F 30 38   .w3.org/2005/08
 2F 61 64 64 72 65 73 73 69 6E 67 2F 61 6E 6F   /addressing/ano
 6E 79 6D 6F 75 73 3C 2F 61 3A 54 6F 3E 3C 2F   nymous</a:To></
 73 3A 48 65 61 64 65 72 3E 3C 73 3A 42 6F 64   s:Header><s:Bod
 79 3E 3C 41 64 64 52 65 73 70 6F 6E 73 65 20   y><AddResponse 
 78 6D 6C 6E 73 3D 22 68 74 74 70 3A 2F 2F 74   xmlns="https://t
 65 6D 70 75 72 69 2E 6F 72 67 2F 22 3E 3C 41   empuri.org/"><A
 64 64 52 65 73 75 6C 74 3E 33 3C 2F 41 64 64   ddResult>3</Add
 52 65 73 75 6C 74 3E 3C 2F 41 64 64 52 65 73   Result></AddRes
 70 6F 6E 73 65 3E 3C 2F 73 3A 42 6F 64 79 3E   ponse></s:Body>
 3C 2F 73 3A 45 6E 76 65 6C 6F 70 65 3E         </s:Envelope>
[READ] 1 bytes
 87                                             .
[WRITE] 1 bytes
 07                                             .

Next time: A Problem with Large Faults

CalculatorService.cs