@Override
  public Connection newConnection(Connector connector, EndPoint endPoint) {
    ServerSessionListener listener = newSessionListener(connector, endPoint);

    Generator generator = new Generator(connector.getByteBufferPool(), getMaxHeaderTableSize());
    HTTP2ServerSession session =
        new HTTP2ServerSession(
            connector.getScheduler(),
            endPoint,
            generator,
            listener,
            new HTTP2FlowControl(getInitialStreamWindow()));
    session.setMaxLocalStreams(getMaxConcurrentStreams());
    session.setMaxRemoteStreams(getMaxConcurrentStreams());
    long idleTimeout = endPoint.getIdleTimeout();
    if (idleTimeout > 0) idleTimeout /= 2;
    session.setStreamIdleTimeout(idleTimeout);

    Parser parser = newServerParser(connector.getByteBufferPool(), session);
    HTTP2Connection connection =
        new HTTP2ServerConnection(
            connector.getByteBufferPool(),
            connector.getExecutor(),
            endPoint,
            parser,
            session,
            getInputBufferSize(),
            listener);

    return configure(connection, connector, endPoint);
  }
예제 #2
0
 /**
  * This method is invoked when the idle timeout triggers. We check the close state to act
  * appropriately:
  *
  * <p>* NOT_CLOSED: it's a real idle timeout, we just initiate a close, see {@link #close(int,
  * String, Callback)}.
  *
  * <p>* LOCALLY_CLOSED: we have sent a GO_AWAY and only shutdown the output, but the other peer
  * did not close the connection so we never received the TCP FIN, and therefore we terminate.
  *
  * <p>* REMOTELY_CLOSED: the other peer sent us a GO_AWAY, we should have queued a disconnect, but
  * for some reason it was not processed (for example, queue was stuck because of TCP congestion),
  * therefore we terminate. See {@link #onGoAway(GoAwayFrame)}.
  *
  * @return true if the session should be closed, false otherwise
  * @see #onGoAway(GoAwayFrame)
  * @see #close(int, String, Callback)
  * @see #onShutdown()
  */
 @Override
 public boolean onIdleTimeout() {
   switch (closed.get()) {
     case NOT_CLOSED:
       {
         long elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - idleTime);
         if (elapsed < endPoint.getIdleTimeout()) return false;
         return notifyIdleTimeout(this);
       }
     case LOCALLY_CLOSED:
     case REMOTELY_CLOSED:
       {
         abort(new TimeoutException("Idle timeout " + endPoint.getIdleTimeout() + " ms"));
         return false;
       }
     default:
       {
         return false;
       }
   }
 }
    @Override
    protected void send(HttpExchange exchange) {
      Request request = exchange.getRequest();
      normalizeRequest(request);

      // Save the old idle timeout to restore it
      EndPoint endPoint = getEndPoint();
      idleTimeout = endPoint.getIdleTimeout();
      endPoint.setIdleTimeout(request.getIdleTimeout());

      // One channel per connection, just delegate the send
      if (channel.associate(exchange)) channel.send();
      else channel.release();
    }
예제 #4
0
 public HTTP2Session(
     Scheduler scheduler,
     EndPoint endPoint,
     Generator generator,
     Session.Listener listener,
     FlowControlStrategy flowControl,
     int initialStreamId) {
   this.scheduler = scheduler;
   this.endPoint = endPoint;
   this.generator = generator;
   this.listener = listener;
   this.flowControl = flowControl;
   this.flusher = new HTTP2Flusher(this);
   this.maxLocalStreams = -1;
   this.maxRemoteStreams = -1;
   this.streamIds.set(initialStreamId);
   this.streamIdleTimeout = endPoint.getIdleTimeout();
   this.sendWindow.set(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
   this.recvWindow.set(FlowControlStrategy.DEFAULT_WINDOW_SIZE);
   this.pushEnabled = true; // SPEC: by default, push is enabled.
   this.idleTime = System.nanoTime();
 }