On Fri, May 25, 2012 at 9:08 AM, Konstantin Preißer < verlag.preis...@t-online.de> wrote:
> 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/ > . > For server-to-server ( i.e. IIS to tomcat ) you shouldn't need NPN or SSL. SSL may make sense. You would need to set the tomcat connector to accept non-NPN/SSL connections. > > 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. > Same, it should be possible to tweak tomcat connector to not require compression. > > 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). > Google servers (AFAIK) support both 2 and 3. I'm working on a 3 implementation for tomcat - the hard part is the flow control. The even harder part is finding time to work on it... IMHO this is the right thing to do - with SPDY you'll also be able to proxy to other servers (nodejs, jetty, etc). Disabling NPN/compression should be very easy - but there are some missing things in 'proxy mode' - in particular ability to pass the 'source IP', info about original certs, etc. Each is relatively simple ( define an X-header, cut&paste from ajp impl ) Costin > > > 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 > >