View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  
20  package org.eclipse.jetty.spdy;
21  
22  import java.io.IOException;
23  import java.nio.channels.SocketChannel;
24  import java.util.concurrent.Executor;
25  import java.util.concurrent.ScheduledExecutorService;
26  
27  import org.eclipse.jetty.io.AsyncEndPoint;
28  import org.eclipse.jetty.io.Connection;
29  import org.eclipse.jetty.io.nio.AsyncConnection;
30  import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
31  import org.eclipse.jetty.spdy.generator.Generator;
32  import org.eclipse.jetty.spdy.parser.Parser;
33  
34  public class ServerSPDYAsyncConnectionFactory implements AsyncConnectionFactory
35  {
36      private final ByteBufferPool bufferPool;
37      private final Executor threadPool;
38      private final ScheduledExecutorService scheduler;
39      private final short version;
40      private final ServerSessionFrameListener listener;
41  
42      public ServerSPDYAsyncConnectionFactory(short version, ByteBufferPool bufferPool, Executor threadPool, ScheduledExecutorService scheduler)
43      {
44          this(version, bufferPool, threadPool, scheduler, null);
45      }
46  
47      public ServerSPDYAsyncConnectionFactory(short version, ByteBufferPool bufferPool, Executor threadPool, ScheduledExecutorService scheduler, ServerSessionFrameListener listener)
48      {
49          this.version = version;
50          this.bufferPool = bufferPool;
51          this.threadPool = threadPool;
52          this.scheduler = scheduler;
53          this.listener = listener;
54      }
55  
56      public short getVersion()
57      {
58          return version;
59      }
60  
61      @Override
62      public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment)
63      {
64          CompressionFactory compressionFactory = new StandardCompressionFactory();
65          Parser parser = new Parser(compressionFactory.newDecompressor());
66          Generator generator = new Generator(bufferPool, compressionFactory.newCompressor());
67  
68          SPDYServerConnector connector = (SPDYServerConnector)attachment;
69  
70          ServerSessionFrameListener listener = provideServerSessionFrameListener(endPoint, attachment);
71          SPDYAsyncConnection connection = new ServerSPDYAsyncConnection(endPoint, bufferPool, parser, listener, connector);
72          endPoint.setConnection(connection);
73  
74          FlowControlStrategy flowControlStrategy = connector.newFlowControlStrategy(version);
75  
76          StandardSession session = new StandardSession(version, bufferPool, threadPool, scheduler, connection, connection, 2, listener, generator, flowControlStrategy);
77          session.setAttribute("org.eclipse.jetty.spdy.remoteAddress", endPoint.getRemoteAddr());
78          session.setWindowSize(connector.getInitialWindowSize());
79          parser.addListener(session);
80          connection.setSession(session);
81  
82          connector.sessionOpened(session);
83  
84          return connection;
85      }
86  
87      protected ServerSessionFrameListener provideServerSessionFrameListener(AsyncEndPoint endPoint, Object attachment)
88      {
89          return listener;
90      }
91  
92      private static class ServerSPDYAsyncConnection extends SPDYAsyncConnection
93      {
94          private final ServerSessionFrameListener listener;
95          private final SPDYServerConnector connector;
96          private volatile boolean connected;
97  
98          private ServerSPDYAsyncConnection(AsyncEndPoint endPoint, ByteBufferPool bufferPool, Parser parser, ServerSessionFrameListener listener, SPDYServerConnector connector)
99          {
100             super(endPoint, bufferPool, parser);
101             this.listener = listener;
102             this.connector = connector;
103         }
104 
105         @Override
106         public Connection handle() throws IOException
107         {
108             if (!connected)
109             {
110                 // NPE guard to support tests
111                 if (listener != null)
112                     listener.onConnect(getSession());
113                 connected = true;
114             }
115             return super.handle();
116         }
117 
118         @Override
119         public void onClose()
120         {
121             super.onClose();
122             connector.sessionClosed(getSession());
123         }
124     }
125 }