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

Reply via email to