Hello! (this time I hope the e-mail is complete ;-) Some time ago, I wrote about a possible alternative IIS AJP Connector implementation [1] that is written in C# and uses the new IIS 7/8 module pipeline, which allows to insert managed modules (.Net) in the request pipeline.
However, Mladen Turk pointed me to the SPDY protocol which could also be used for server-to-server communication as a possible replacement for AJP (which was also mentioned in the Thread "SPDY support" by Costin Manolache). Since I had some spare time again, I started to try an implementation of an SPDY Client / Redirector for IIS 7.x/8.x which is also written in C# (using .Net Framework 4.0), which is based on SPDY Protocol Draft 3 [2]. It is a 3-layered SPDY client with a very basic IIS module that uses the client to forward requests. You can find the source code at the SVN repo here: https://kinderbasar-luhe.de:8543/svn/PreisserNormaleProjekte/SpdyConnector/ Note that there is a Java part (Eclipse project, it is a workaround to use TLS NPN) and a .Net part (Microsoft Visual Studio 2010 project). Of course, it still needs a lot of work to be done (and probably has also a number of bugs ;-) ). If you like the connector, I would be happy to contribute it to the Apache Software Foundation (however there currently are some problems which prevent this - see below). The architecture of that SPDY client / IIS module is the following (each layer has only dependencies to the layer(s) above): 1. SPDY Connector (protocol) ------------------------------------ 2. SPDY Processor (multiplexer) ------------------------------------ 3. SPDY HTTP Processor (HTTP layer) ------------------------------------ 4. IIS Module (for forwarding requests) 1. "SPDY Connector" implements the SPDY protocol (without HTTP). This means e.g. it has methods to send specific frames, and it has events that are raised when other specific frames are received. It does not do any multiplexing. It is intended to be accessed by only 2 different threads (one for reading and one for writing). 2. "SPDY Processor" uses the SPDY connector and adds multiplexing to it. This means it can be accessed by several threads to get a SPDY stream and read from it / write to it. The SPDY Processor serializes these calls to the SPDY Connector. 3. "SPDY HTTP Processsor" adds an HTTP layer to the SPDY processor (e.g. it translates normal HTTP headers to SPDY ones). 4. "IIS Module" contains a class that implements System.Web.IHttpModule interface so that it can be inserted into IIS's request pipeline. It is responsible for redirecting HTTP requests using one or more SPDY HTTP Processors. This architecture also allows to use the SPDY client as a regular client (without IIS). I also noticed a "Websockets over SPDY" proposal which I think should not be hard to implement (IIS 8 supports WebSockets, but I haven't dealt with IIS 8 websockets yet). However, I got to some problems when I was implementing the SPDY client: 1. .Net has no support for the TLS NPN (next protocol negotiation) extension which is required by SPDY, and there seems to be no library for supporting it (at least I couldn't find one). Therefore I had to create a Java TLS tunnel which uses the NPN extension from Jetty [3]. This is similar to "stunnel" with the addition that it uses NPN to negotiate "spdy/3" as protocol. You can find it in https://kinderbasar-luhe.de:8543/svn/PreisserNormaleProjekte/SpdyConnector/Java/NpnSpdyTunnel/. 2. SPDY uses zlib for header compression. Although .Net has some support for compression in the System.IO.Compression namespace, it doesn't seem to have support for the operations required by SPDY (setting a Zlib Dictionary and using SYNC_FLUSH between header frames). (However I must admit that I don't have much knowledge about these compression technologies, so I might be wrong). Therefore I used "ZLIB.NET" [4] which is a managed .Net implementation of zlib. However it seems to be based on an older version, and I had to hack the code which checks if the correct dictionary is set (it seemed that the adler32() function computed a wrong value for the dictionary) for the compression to work. Also, I don't know if the library can be distributed with apache licences. Note that because of 1., the .Net SPDY client currently doesn't use any SSL/TLS, because it will connect to the Java NPN tunnel, which negotiates spdy/3 and does the encryption. I tested the SPDY client with Google servers which use "spdy/3" for some time now. However I couldn't test it with Tomcat, as it seems that it is currently implementing spdy/2, but not spdy/3 (please correct me if I'm saying something wrong). If you would like to test the SPDY client with IIS 7.x (Windows Server 2008 or Windows Server 2008 R2) or IIS 8.x (Windows Server 2012), you would need to do the following: 0. Ensure that the Microsoft .Net Framework 4.0 (Full) is installed. Also ensure that Role "Webserver (IIS)" with Role Service ".Net Extensibility" is enabled on the server, and that the IIS application pool which you would like to try the redirector with is using the Framework 4.0 and "Integrated" Managed Pipeline Mode. 1. Compile and run the Java NPN tunnel. When you run it, you need to set the Boot classpath to the Jetty NPN library, e.g. -Xbootclasspath/p:"npn-boot-8.1.2.v20120308.jar" 2. To use the SPDY IIS module, I recommend to compile it so that the compiled assembly can be used in IIS. To compile the project, run the following C# Compiler command if the current directory is the project directory (.../SpdyConnector/.Net/SPDY-Redirector/SPDY_Redirector): C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /out:SpdyRedirectorModule.dll /target:library /define:DEBUG /platform:anycpu /recurse:*.cs It will generate the assembly "SpdyRedirectorModule.dll" in the current directory. Note that because .Net is intended to be platform-independent (like Java), the assembly can be used both on 32 bit and 64 bit environments. 3. Create a "bin" folder in the IIS web application where you would like to use the SPDY client. E.g. on a default IIS installation, this would be "C:\inetpub\wwwroot". Copy the SpdyRedirectorModule.dll into that "bin" folder. 4. Open the IIS manager. Navigate to the web application / virtual host where you copied the file (e.g. "Default Web Site"). Then open the item "Modules". 5. Click on "Add managed module...". In the combobox, type "Preisser.Spdy.SpdyRedirector.IisModule.SpdyHttpIisModule" (without quotes), and enter a name for it. Make sure "Invoke only for requests to ASP.Net managed applications etc" is not selected. Then click OK, and when a message appears that the type could not be found in referenced libraries, click Yes. (Note that on IIS 8, the combobox should already contain the module, and such a warning should not appear when adding it.) 6. Open a URL like "http://localhost/mail/help/intl/de/tips.html". You should now see a Google Mail page appear. (It contains several images that are also loaded from localhost). 7. If you close the Java NPN SPDY tunnel and open the URL again, the following text should appear: HTTP 503 The request could not be served because the remote server was not available. (when starting the Java NPN Spdy tunnel again, the URL should also work again). Note that the current SPDY client / redirector supports only basic functionalities (e.g. it does not support POST requests). The most work probably would need to be done in the IIS module (to decide which request should be redirected, to also support other HTTP methods besides GET, etc.). Also, the SPDY client currently doesn't support streams which are initiated by server, and is not optimized for efficiency. The .Net SPDY client will connect to "localhost:8443" where it expects the Java NPN SPDY tunnel to listen. That will establish a connection to "mail.google.com" which supports spdy/3. Costin Manolache mentioned in the thread "SPDY support" [5] that for SPDY proxy mode to work, Tomcat would need to read and trust additional information from X- headers, like remote IP etc. Maybe Tomcat could use a "SPDY proxy mode", that in comparison to "real SPDY mode", allows to configure if header compression and TLS NPN should be used? (As it would be no real SPDY used by a Browser, it could be modified in such a way, if the other endpoint (e.g. the IIS Spdy redirector) also is implemented in that way). This would allow to not require NPN support so that the IIS SPDY redirector could be used without that Java NPN SPDY tunnel to directly connect to Tomcat (e.g. using TLS without NPN extension would be supported natively by .Net). One thing that also came to my mind while experimenting with the SPDY connector, is that the AJP protocol has a packet "GET_BODY_CHUNK". The server (Tomcat) sends this to the front-end (Httpd, IIS) so that they send the next request body chunk. If I understood correctly, this allows Tomcat to send an HTTP response immediately, before reading all the request data. However, the current SPDY redirector would first send the complete request body to Tomcat/SPDY server, before reading any response body to send to the client. I guess an additional thread per request would be needed for that behavior, so that one thread can transfer the request body to the SPDY server and the other thread can transfer the response body to IIS. I think when comparing AJP with SPDY as protocol for server-to-server-communication, a major advantage of SPDY is that only one TCP connection is used for several concurrent HTTP requests. In AJP, each connection can only serve one request at a time. Also, SPDY allows support for WebSockets which I don't know if it is possible with AJP. The SPDY client also supports flow control (which was added in SPDY/3) so that if a slow client connects to IIS, IIS does not have to buffer the complete request body received by Tomcat before it can send it to the client, while concurrently serving other HTTP requests over that SPDY connection (however I didn't test if flow-control correctly works when sending a POST request to the server). Note that C# (language) and .Net (Runtime, class libraries) are very similar to Java - so for anyone who knows Java, it should be easy to follow the C# code of that SPDY client. ;-) Please let me know what you think. Thanks! Regards, Konstantin Preißer [1] http://markmail.org/message/livcbkoa4b7bl7yq [2] http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3 [3] http://wiki.eclipse.org/Jetty/Feature/NPN [4] http://www.componentace.com/zlib_.NET.htm [5] http://markmail.org/message/c7pvtquoinzwapst --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org