users@grizzly.java.net

Re: Tunnel implementation

From: Karsten Ohme <widerstand_at_t-online.de>
Date: Fri, 1 Jun 2007 18:20:51 +0200

On Fri, Jun 01, 2007 at 05:26:18PM +0200, Oleksiy Stashok wrote:
> Hello Karsten,
>
> let me try to help you.
> Let's start from the beginning and will not use cache for simplicity, we
> can always add it later...
> As I understood, you are not making http proxy, but some tunnel for
> socket connections. In other words nothing http specific?
>
> So I would advice you to start implementing something called... let's
> say ProxyProtocolFilter (as Jeanfrancois proposed) :)
> To see how you can implement the Filter - please find EchoFilter in
> Grizzly/framework test folder.
>
> As for proxy-to-tomcat connections - please use ConnectorHandlers (to
> get one use controller.aquireConnectorHandler(), and don't forget to
> release it).
> We're working on documentations, but you can take a look at unit tests
> we have to understand how you can use Grizzly both for client and server
> sides.
>
> If you'll have questions - please ask.

OK, I have a ProxyProtocolFilter and I also found out that the
WorkerThread contains the ByteBuffer. So I would do the following

Use the returned ByteBuffer from the WorkerThread aquire a
TCPConnectorHandler from the Controller in the Context

register a CallBackHandler with a reference to the SocketConnection for
the way from client to proxy and an implemented onConnect() method

write out the data with write(byteBuffer, true)

When do I release the TCPConnectorHandler? I store the TCPConnector with
the SocketChannel for the way client-proxy in a Map in the Context. So
the connection can be reused. What is better?

When the connection is done onConnect gets executed and I can get the
SocketChannel for the line proxy - Tomcat server
The pair of SocketConnections client-proxy and proxy-Tomcat server is
kept in a mapping in the context. This is important to remember who is
talking over the proxy to whom.

For the way server-proxy to proxy-client I have to write back the data.
Problem I see no way how I can use here an TCPConnectorHandler. The
TCPSelectorHandler offers no possibility to use an existing
SocketChannel. I would change this to simplify my life or how is it
intended?

Why are there two methods: register(CallbackHandler) and
setCallbackHandler(...)?

Thanks,
Karsten

>
> WBR,
> Alexey.
>
> Karsten Ohme wrote:
> >On Thu, May 31, 2007 at 02:43:43PM -0400, Jeanfrancois Arcand wrote:
> >
> >>Hi Karsten,
> >>
> >>don't stop the feedback!
> >>
> >>Karsten Ohme wrote:
> >>
> >>>Hi,
> >>>
> >>>I want to program a proxy (actually tunnel). All connections are made to
> >>>the proxy, the proxy makes some decisions and forwards them to the
> >>>server. For my situation many clients connect to the proxy on port 80,
> >>>the proxy forwards the requests to a Tomcat server on port 8080 and
> >>>writes the response back to the client.
> >>>
> >>Stupid question: can the client connect directly to Tomcat or does all
> >>connection must go to the proxy? I suspect all connections have to pass
> >>through the proxy, but in case not, the proxy can always send a redirect
> >>to the client (using the location: header).
> >>
> >>
> >>
> >>>How can I acieve this with Grizzly? I though I had to extend the
> >>>TCPSelectorHandler, overwrite the onAcceptInterest method, establish
> >>>there a new TCPConnectorHandler for the path client-proxy and one for
> >>>proxy-server and register CallbackHandlers wo propagate the read and
> >>>write operations.
> >>>
> >>I would not override the onAcceptInterest but instead let the default
> >>workflow happen. On of the reason is onAcceptInterest is executed on the
> >>same thread as the Selector.select(), which is a performance bottleneck.
> >>I would instead implement two ProtocolFilters that uses the newly added
> >>ConnectionPool/Cache. My recommendation is to do:
> >>
> >>1. Use the default ReadFilter to execute the first read to make sure the
> >>connection hasn't been closed between the accept() and the first read.
> >>2. Add a new ProxyProtocolFilter:
> >>
> >>+ When initializing, create a pool of connection your remote server
> >>(Tomcat). I recommend you take a look at the new ConnectionPool/Cache
> >>Alexey demonstrated yesterday at the Grizzly meeting.
> >>
> >
> >I don't know how to use it. What is a ConnectionPool? There is only a
> >class ConnectionCache. What is it useful for? From the name I suspect
> >that some sort of connections are cached and I have a method to get free
> >connections which I can use. I would expect a constructor with a given
> >number where this amount of connections are created. For me this would
> >be always the same type of connection from the proxy to the client, for
> >the way
> >from client to proxy I need for each client a single connection or not?
> >What are doing requestReceived(), requestProcessed() and responseSent( C
> >conn ). Which connection I have to pass in as parameter? What means
> >cached? In the sources it looks like i have to pass the connectiosn on
> >my own. From which class must the methods be called? How can I reuese
> >such a cached exception when it is idle? There is not get method.
> >
> >Regards,
> >Karsten
> >
> >
> >>+ When execute() is invoked, use a StreamAlgorithm implementation to
> >>make sure you can read the complete HTTP request (note: you gonna need
> >>to buffer the body as well). The module/http sub module have a
> >>StreamAlgorithm implementations called
> >>ContentLengthAlgorithm|StateMachineAlgoruithm that can be reused. Mainly
> >>those classes will make sure the entire headers + body are read.
> >>+ Once you have read all the bytes, get a connection from the connection
> >>pool and flush the bytes to Tomcat. Make the
> >>TCPConnectionHandler.write(bb,TRUE) so the temporary Selector trick can
> >>be reused.
> >>+ Then read back the response and flush it back to the client.
> >>
> >>Would that make sense? You might also want to create two ProtocolFilter,
> >>one for reading the request, and one for writing the response to the
> >>active connection to Tomcat.
> >>
> >>
> >>>But I don't know how the ProtocolFilter fits into the picture. How do I
> >>>use it? I also want to use TLS connections. How can I get the data which
> >>>is decoded?
> >>>
> >>>Is there any documentation or tutorial for the new Grizzly API?
> >>>
> >>Take a look at the following talks:
> >>
> >>https://grizzly.dev.java.net/presentations/FISL-2007.pdf
> >>http://weblogs.java.net/blog/jfarcand/archive/BOF-4989-Grizzly.pdf
> >>
> >>We don't have yet tutorials but I'm working on one right now.
> >>
> >>Hope that help.
> >>
> >>-- Jeanfrancois
> >>
> >>
> >>>Regards,
> >>>Karsten
> >>>
> >>>---------------------------------------------------------------------
> >>>To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> >>>For additional commands, e-mail: users-help_at_grizzly.dev.java.net
> >>>
> >>>
> >>---------------------------------------------------------------------
> >>To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> >>For additional commands, e-mail: users-help_at_grizzly.dev.java.net
> >>
> >>
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> >For additional commands, e-mail: users-help_at_grizzly.dev.java.net
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>