HTTP.SYS transport for WSE 3.0

Service Station, by Aaron Skonnard

Syndication

HTTP.SYS integration is one of the features I was expecting to find in WSE 3.0. Hosting ASMX in your own process just isn't easy enough with HttpListener (as you know if you read my article on the subject). Basically, I want the WCF-like ability to host HTTP endpoints in any process via SoapReceivers.Add:
 
SoapReceivers.Add("http://localhost:8080/math/",
   typeof(MathService));
 
I asked the WSE team about it when 3.0 was first becoming public but at that point it was too late; wasn't on the feature list. I didn't think about it when I wrote my wish list. Oh well.
 
So I thought through how it could be done through the WSE extensibility architecture, specifically as a custom transport, and decided to write it once I found some time. Many months passed and I finally found some time. You'll find links to download the code + samples below.
 
Here's a quick snapshot of how it works. Assume the following ASMX 2.0 code:
 
[WebServiceBinding(Name="MathServiceBinding",
    Namespace="http://example.org/math",
    ConformsTo = WsiProfiles.BasicProfile1_1,
    EmitConformanceClaims = true)]
public interface IMathService
{
    [WebMethod]
    double Add(double x, double y);
    [WebMethod]
    double Subtract(double x, double y);
    [WebMethod]
    double Multiply(double x, double y);
    [WebMethod]
    double Divide(double x, double y);
    [WebMethod]
    double Mod(double x, double y);
}
 
[WebService(Name="MathService",
    Namespace="http://example.org/math")]
public class MathService : IMathService
{
    #region IMathService Members
 
    public double Add(double x, double y)
    {
        return x + y;
    }
    ...
 
You can host this class in IIS/ASP.NET using the following .asmx file:
 
<%@ WebService Language="C#" Class="ServiceLibrary.MathService" %>
 
But with this custom HTTP.SYS transport, you can also write a console application, NT service, or a Windows app to host the same class using SoapRecievers. Here's a sample console app:
 
class Program
{
    static void Main(string[] args)
    {
        try
        {
            SoapReceivers.Add("http://localhost:8080/math/",
                typeof(MathService));
            Console.WriteLine("MathService is listening.");
            Console.WriteLine("Press [Enter] to terminate.");
            Console.ReadLine();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
}
 
All you have to do configuration-wise is tell WSE to use your custom HTTP transport instead of the built-in one for the "http" protocol scheme. You do this with the following configuration elements:
 
<configuration>
  ...
  <microsoft.web.services3>
    <messaging>
      <transports>
        <add scheme="http"
         type="Skonnard.Samples.HttpSys.HttpSysTransport,
Skonnard.Samples.HttpSys"/>
      </transports>
    </messaging>
  </microsoft.web.services3>
</configuration>
 
And you'll need a reference to Skonnard.Samples.HttpSys.dll in the hosting application so it can find it at runtime. Then, you're ready to go.
 
Clients don't need to use the adapter. They can simply use the built-in HTTP transport on the consuming side. Just update the proxy address before invoking methods as shown here:
 
MathServiceWse svc = new MathServiceWse();
svc.Destination = new EndpointReference(
   new Uri("http://localhost:8080/math/"));
 
The proxy class, MathServiceWse, was generated using wsdl.exe against the IIS/ASP.NET hosted endpoint.
 
Update: the following bits run on RTM, and they support HTTP GET requests for WSDL. Simply browse to the exact same address supplied in the call to SoapReceivers.Add. When supplying an ASMX class to SoapReceivers.Add, you must wrap the type in an instance of WsdlEnabledReceiver in order for the WSDL generation to work properly. See the sample code for an example.
 
Downloads
HttpSysTransport.zip (source code for HTTP.SYS transport)
HttpSysTransportTest.zip (sample test harness)
 

Posted Oct 14 2005, 02:54 PM by Aaron Skonnard
Filed under:

Comments

John Bristowe's Weblog wrote The WSE Wonk Strikes Again
on 10-14-2005 3:58 PM
After his port of Steve Maine's WSE 2.0 SMTP transport to the WSE 3.0 bits, Aaron Skonnard has done it...
Brain.Save() wrote WSE Transport Goodness
on 10-14-2005 11:40 PM
Omri wrote re: HTTP.SYS transport for WSE 3.0
on 10-15-2005 10:18 PM
awesome.. we were wondering who in the community would be first to build the http.sys transport, and the good money was on you :-)
mihailik wrote re: HTTP.SYS transport for WSE 3.0
on 10-17-2005 6:24 AM
Aaron, I caught you! You developed and ran this code as administrator :-)

There is a great problem with HTTP.sys — it require administrative privelege to run, or administrative pre-configuration on per-endpoint basis before run.

IMHO, it is really important note for thouse, who will download and try to run your code.
dominick wrote re: HTTP.SYS transport for WSE 3.0
on 10-17-2005 6:38 AM
I built a little helper program to simplify the pre-registration of URIs with httpcfg.exe

you can find it here:
http://www.leastprivilege.com/HttpCfgACLHelper.aspx
Christopher Steen wrote Link Listing - October 17, 2005
on 10-17-2005 11:34 AM
Aaron's HTTP.SYS transport running as LUA [Via: Keith Brown ]
An XML Guru's Guide to BizTalk Server...
Sam Gentile's Blog wrote New and Notable 81
on 10-21-2005 8:51 AM
Sam Gentile's Blog wrote New and Notable 81
on 10-21-2005 1:47 PM
Scott Hanselman wrote re: HTTP.SYS transport for WSE 3.0
on 11-04-2005 11:40 PM
You freaking rock.
<savas:blog /> wrote From the blogosphere
on 11-06-2005 2:34 AM
I don’t usually do a summary post like this one but as I try to go through my ~2000 unread blog posts, I am making a note of some interesting things I've found.It's nice to see that Steve's work is causing a reaction :-)Dennis Pilarinos' blog is one t...
Il Blog di Paolo Pialorsi wrote WSE 3.0 e hosting HTTP diretto tramite http.sys
on 11-06-2005 2:47 PM
Grazie ad Aaron Skonnard abbiamo in omaggio un trasporto HTTP diretto, via http.sys, per WSE3:
http://pluralsight.com/blogs/aaron/archive/2005/10/14/15571.asp...
Mike Taulty's Weblog wrote Hosting WSE 3.0 with HTTP.SYS
on 11-07-2005 2:00 AM
Service Station, by Aaron Skonnard wrote Learn how to write a custom transport for WSE 3.0
on 11-07-2005 3:49 PM
Andy Neilson wrote re: HTTP.SYS transport for WSE 3.0
on 11-14-2005 9:56 AM
In a server project I’m currently working on, we host the ASP.NET processing pipeline in our process (which is way more painful than it should be), and feed it using an HttpWorkerRequest-derived class that uses HttpListener. My solution feels like a bit of a Rube Goldberg device in comparison to the custom HTTP.SYS transport sample.

While this custom transport is certainly a neater solution, it doesn’t have some key capabilities that the ASP.NET solution does:

- MTOM
- Asynchronous WebMethod implementation.

I'm still trying to figure out how difficult it would be to add these capabilities.

As interesting a piece of work this is, it is still a way off from providing a complete HTTP.SYS transport solution. I’m not saying that it is your responsibility to provide one, but a complete out-of-the-box solution in WSE 3.0 would have been very welcome.
Dinis Cruz @ Owasp .Net Project wrote Http.Sys research
on 11-28-2005 3:19 AM


INF: Http.sys Registry Settings for IIS
Using Http.Sys to receive messages with WSE 2.0 , HTTP.SYS...
Irwin wrote re: HTTP.SYS transport for WSE 3.0
on 11-30-2005 3:03 AM
in response to mihailik:
This was stated in teh Messaging Manual for MS' hands on lab about creating your own transport.

Note: registering address with HTTP.SYS requires administrator privileges unless a namespace reservation has been made by an administrator beforehand that grants the user permission to do so. A namespace reservation is simply a record that sets an access control list (ACL) for an HTTP prefix (e.g. the URL you'd normally pass to HttpListener.Prefixes.Add). This allows the administrator to say which users are allowed to register that prefix with HTTP.SYS. The HTTPCFG.EXE utility can be used to create namespace registrations ahead of time. If you’re not running as Administrator, you’ll need to do before testing your HTTP.SYS transport. You can download HTTPCFG.EXE from here. You can read about how it works in the online documentation.
Irwin wrote re: HTTP.SYS transport for WSE 3.0
on 12-01-2005 5:54 AM
Hi,
I'm using this transport in my own application, but i need to use a SoapFilters to modify the message before it gets to the 'ultimate service'. I have noticed that even though the Filter is being called on my receiver class - which extends MM7Receiver - some methods that i have overridden from SoapReceiver are not being called in the subclass, do you have any idea why this might be?
Thanks
Irwin wrote re: HTTP.SYS transport for WSE 3.0
on 01-27-2006 10:46 AM
In answer to my own question above, i am not sure of all the reasons why, but when I'm using the WsdlEnabledReceiver - which allows us to see the WSDL contract via an HTTP GET - it doesnt allow the methods of the receiver object I invoked to be called.
So, when i don't use the WsdlEnabledReceiver in my SoapReceivers.Add() method call, the methods that i override are actually called.
Niels Flensted-Jensen wrote Performance of HTTP.SYS transport for WSE 3.0
on 02-17-2006 3:32 AM
I've run comparisons in performance between traditional IIS6/ASP.NET hosting and hosting in a console app using this HTTP.sys transport.

But no matter how I run it or set it up, I keep getting better performance from the IIS6 app pool scenario. And I would have expected the direct HTTP.sys transport to be faster as there is no ASP.NET pipeline involved?

Any views/explanations?
kayllama wrote re: HTTP.SYS transport for WSE 3.0
on 05-16-2006 9:10 AM
penis
Erikst wrote re: HTTP.SYS transport for WSE 3.0
on 05-17-2006 4:14 AM
Has anyone tried to implement custom HTTP tansport for OneWay (return void) service methods, because i'm having a problem there? The WSE 3.0 framework doesn’t close the response when a OneWay method is called, which means that the service never returns a 202 Accepted (or anything for that matter) that is needed for the proxy to continue. Has anyone encountered the same problem?
Schroeder wrote Kerberos Security with HTTP.SYS transport for WSE 3.0
on 08-03-2006 7:23 PM
How can I get kerberos security to work with this transport?

I've tried using the WSE3 Kerberos Policy, but I get an error in the HttpSysOutputChannel: "HttpListenerContext unavailable in HttpSysOutputChannel.Send".

I know that ASP.Net requires you to configure the ASPNet account to run as "System".
Mehdi Mousavi wrote re: HTTP.SYS transport for WSE 3.0
on 08-08-2006 7:10 AM
Hi,
Is there anyway to pass a given "object" to the SoapReceivers, so that we'd be able to receive it back in the MathService class? i.e., how am I supposed to implement IMathService within the Form class, where I call the following function:

SoapReceivers.Add("http://localhost:8080/math/", typeof(MathService));

Any help would be highly appreciated,
Rainer Schüler wrote re: HTTP.SYS transport for WSE 3.0
on 08-18-2006 7:00 AM
Hi,
can not get it to work. I'm allways getting an "Destination Unreachable" Exception on the client. The retrival of the WSDL document works fine. But the invocation of the mathservice fails. I tried to debug it, and the only thing I can see so far is that in the soap request from my client the Context.Addressing.To property is null. As a result of this the method call of DispatchMessage returns false.
Does anyone has a clue what is wrong?
Thanks, Rainer
Shaojun Ni wrote re: HTTP.SYS transport for WSE 3.0
on 09-26-2006 10:09 AM
I've tried using the WSE3.0 UsernameToken with WS Security 1.1, but i get an error in the HttpSysOutputChannel:Send(), HttpListenerContext is not available when i pass the wrong credential. Does anybody know how to fix it?
Jeff wrote re: HTTP.SYS transport for WSE 3.0 - HELP!!!!
on 11-28-2007 1:53 PM
I'm getting this error if I try to run the standalone ServiceHost.exe and the Client.exe...
-------------------------------
I think it's confused in the URI and the svc.URL... based on Aaron's code...

Thanks!
--------------------------------
System.Web.Services.Protocols.SoapHeaderException: Destination Unreachable
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClie
ntMessage message, WebResponse response, Stream responseStream, Boolean asyncCal
l)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodN
ame, Object[] parameters)
at Client.MathService.MathServiceWse.Add(Double x, Double y) in C:\NET\Websvc
\Aaron\test\HttpSysTransport\Client\Web References\MathService\Reference.cs:line
98
at Client.Program.Main(String[] args) in C:\NET\Websvc\Aaron\test\HttpSysTran
sport\Client\Program.cs:line 39


Radha Krishna Prasad wrote re: HTTP.SYS transport for WSE 3.0
on 01-02-2008 1:18 AM
Describe it with a Sql Native Xml Web Service example..
Wingman wrote re: HTTP.SYS transport for WSE 3.0
on 03-16-2010 4:42 AM

HttpTransport zip files can be found at:

msdn.microsoft.com/.../cc163879(en-us).aspx

Note that you don't have to use the configuration file to configure WSE. Another option is using this line in code (C#):

Microsoft.Web.Services3.Configuration.WebServicesConfiguration.MessagingConfiguration.AddTransport("http", typeof(HttpSysTransport));

and then add Your class using:

SoapReceivers.Add("localhost/.../",          typeof(MathService));

Also note that when IIS is installed AND running on your computer, you HAVE TO specify a port (in this example 8080), because IIS is using the default http port. Otherwise you get an http.sys-file-is-in-use-error

Add a Comment

(required)  
(optional)
(required)  
Remember Me?