Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* .
*
*/
package org.apache.http.nio.protocol;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.ExceptionLogger;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseFactory;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.MethodNotSupportedException;
import org.apache.http.ProtocolException;
import org.apache.http.UnsupportedHttpVersionException;
import org.apache.http.annotation.Contract;
import org.apache.http.annotation.ThreadingBehavior;
import org.apache.http.concurrent.Cancellable;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.nio.ContentDecoder;
import org.apache.http.nio.ContentEncoder;
import org.apache.http.nio.NHttpConnection;
import org.apache.http.nio.NHttpServerConnection;
import org.apache.http.nio.NHttpServerEventHandler;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.nio.reactor.SessionBufferStatus;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.util.Args;
import org.apache.http.util.Asserts;
/**
* {@code HttpAsyncService} is a fully asynchronous HTTP server side protocol
* handler based on the non-blocking (NIO) I/O model.
* {@code HttpAsyncServerProtocolHandler} translates individual events fired
* through the {@link NHttpServerEventHandler} interface into logically related
* HTTP message exchanges.
*
* Upon receiving an incoming request {@code HttpAsyncService} verifies
* the message for compliance with the server expectations using
* {@link HttpAsyncExpectationVerifier}, if provided, and then
* {@link HttpAsyncRequestHandlerMapper} is used to map the request
* to a particular {@link HttpAsyncRequestHandler} intended to handle
* the request with the given URI. The protocol handler uses the selected
* {@link HttpAsyncRequestHandler} instance to process the incoming request
* and to generate an outgoing response.
*
* {@code HttpAsyncService} relies on {@link HttpProcessor} to generate
* mandatory protocol headers for all outgoing messages and apply common,
* cross-cutting message transformations to all incoming and outgoing messages,
* whereas individual {@link HttpAsyncRequestHandler}s are expected
* to implement application specific content generation and processing.
*
* Individual {@link HttpAsyncRequestHandler}s do not have to submit a response
* immediately. They can defer transmission of an HTTP response back to
* the client without blocking the I/O thread by delegating the process of
* request handling to another service or a worker thread. HTTP response can
* be submitted as a later a later point of time once response content becomes
* available.
*
* @since 4.2
*/
@SuppressWarnings("deprecation")
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
public class HttpAsyncService implements NHttpServerEventHandler {
static final String HTTP_EXCHANGE_STATE = "http.nio.http-exchange-state";
private final HttpProcessor httpProcessor;
private final ConnectionReuseStrategy connStrategy;
private final HttpResponseFactory responseFactory;
private final HttpAsyncRequestHandlerMapper handlerMapper;
private final HttpAsyncExpectationVerifier expectationVerifier;
private final ExceptionLogger exceptionLogger;
/**
* Creates new instance of {@code HttpAsyncServerProtocolHandler}.
*
* @param httpProcessor HTTP protocol processor (required).
* @param connStrategy Connection re-use strategy (required).
* @param responseFactory HTTP response factory (required).
* @param handlerResolver Request handler resolver.
* @param expectationVerifier Request expectation verifier (optional).
* @param params HTTP parameters (required).
*
* @deprecated (4.3) use {@link HttpAsyncService#HttpAsyncService(HttpProcessor,
* ConnectionReuseStrategy, HttpResponseFactory, HttpAsyncRequestHandlerMapper,
* HttpAsyncExpectationVerifier)}
*/
@Deprecated
public HttpAsyncService(
final HttpProcessor httpProcessor,
final ConnectionReuseStrategy connStrategy,
final HttpResponseFactory responseFactory,
final HttpAsyncRequestHandlerResolver handlerResolver,
final HttpAsyncExpectationVerifier expectationVerifier,
final HttpParams params) {
this(httpProcessor,
connStrategy,
responseFactory,
new HttpAsyncRequestHandlerResolverAdapter(handlerResolver),
expectationVerifier);
}
/**
* Creates new instance of {@code HttpAsyncServerProtocolHandler}.
*
* @param httpProcessor HTTP protocol processor (required).
* @param connStrategy Connection re-use strategy (required).
* @param handlerResolver Request handler resolver.
* @param params HTTP parameters (required).
*
* @deprecated (4.3) use {@link HttpAsyncService#HttpAsyncService(HttpProcessor,
* ConnectionReuseStrategy, HttpResponseFactory, HttpAsyncRequestHandlerMapper,
* HttpAsyncExpectationVerifier)}
*/
@Deprecated
public HttpAsyncService(
final HttpProcessor httpProcessor,
final ConnectionReuseStrategy connStrategy,
final HttpAsyncRequestHandlerResolver handlerResolver,
final HttpParams params) {
this(httpProcessor,
connStrategy,
DefaultHttpResponseFactory.INSTANCE,
new HttpAsyncRequestHandlerResolverAdapter(handlerResolver),
null);
}
/**
* Creates new instance of {@code HttpAsyncServerProtocolHandler}.
*
* @param httpProcessor HTTP protocol processor.
* @param connStrategy Connection re-use strategy. If {@code null}
* {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
* @param responseFactory HTTP response factory. If {@code null}
* {@link DefaultHttpResponseFactory#INSTANCE} will be used.
* @param handlerMapper Request handler mapper.
* @param expectationVerifier Request expectation verifier. May be {@code null}.
*
* @since 4.3
*/
public HttpAsyncService(
final HttpProcessor httpProcessor,
final ConnectionReuseStrategy connStrategy,
final HttpResponseFactory responseFactory,
final HttpAsyncRequestHandlerMapper handlerMapper,
final HttpAsyncExpectationVerifier expectationVerifier) {
this(httpProcessor, connStrategy, responseFactory, handlerMapper, expectationVerifier, null);
}
/**
* Creates new instance of {@code HttpAsyncServerProtocolHandler}.
*
* @param httpProcessor HTTP protocol processor.
* @param connStrategy Connection re-use strategy. If {@code null}
* {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
* @param responseFactory HTTP response factory. If {@code null}
* {@link DefaultHttpResponseFactory#INSTANCE} will be used.
* @param handlerMapper Request handler mapper.
* @param expectationVerifier Request expectation verifier. May be {@code null}.
* @param exceptionLogger Exception logger. If {@code null}
* {@link ExceptionLogger#NO_OP} will be used. Please note that the exception
* logger will be only used to log I/O exception thrown while closing
* {@link java.io.Closeable} objects (such as {@link org.apache.http.HttpConnection}).
*
* @since 4.4
*/
public HttpAsyncService(
final HttpProcessor httpProcessor,
final ConnectionReuseStrategy connStrategy,
final HttpResponseFactory responseFactory,
final HttpAsyncRequestHandlerMapper handlerMapper,
final HttpAsyncExpectationVerifier expectationVerifier,
final ExceptionLogger exceptionLogger) {
super();
this.httpProcessor = Args.notNull(httpProcessor, "HTTP processor");
this.connStrategy = connStrategy != null ? connStrategy :
DefaultConnectionReuseStrategy.INSTANCE;
this.responseFactory = responseFactory != null ? responseFactory :
DefaultHttpResponseFactory.INSTANCE;
this.handlerMapper = handlerMapper;
this.expectationVerifier = expectationVerifier;
this.exceptionLogger = exceptionLogger != null ? exceptionLogger : ExceptionLogger.NO_OP;
}
/**
* Creates new instance of {@code HttpAsyncServerProtocolHandler}.
*
* @param httpProcessor HTTP protocol processor.
* @param handlerMapper Request handler mapper.
*
* @since 4.3
*/
public HttpAsyncService(
final HttpProcessor httpProcessor,
final HttpAsyncRequestHandlerMapper handlerMapper) {
this(httpProcessor, null, null, handlerMapper, null);
}
/**
* Creates new instance of {@code HttpAsyncServerProtocolHandler}.
*
* @param httpProcessor HTTP protocol processor.
* @param handlerMapper Request handler mapper.
* @param exceptionLogger Exception logger. If {@code null}
* {@link ExceptionLogger#NO_OP} will be used. Please note that the exception
* logger will be only used to log I/O exception thrown while closing
* {@link java.io.Closeable} objects (such as {@link org.apache.http.HttpConnection}).
*
* @since 4.4
*/
public HttpAsyncService(
final HttpProcessor httpProcessor,
final HttpAsyncRequestHandlerMapper handlerMapper,
final ExceptionLogger exceptionLogger) {
this(httpProcessor, null, null, handlerMapper, null, exceptionLogger);
}
@Override
public void connected(final NHttpServerConnection conn) {
final State state = new State();
conn.getContext().setAttribute(HTTP_EXCHANGE_STATE, state);
}
@Override
public void closed(final NHttpServerConnection conn) {
final State state = (State) conn.getContext().removeAttribute(HTTP_EXCHANGE_STATE);
if (state != null) {
state.setTerminated();
closeHandlers(state);
final Cancellable cancellable = state.getCancellable();
if (cancellable != null) {
cancellable.cancel();
}
}
}
@Override
public void exception(
final NHttpServerConnection conn, final Exception cause) {
log(cause);
final State state = getState(conn);
if (state == null) {
shutdownConnection(conn);
return;
}
state.setTerminated();
closeHandlers(state, cause);
final Cancellable cancellable = state.getCancellable();
if (cancellable != null) {
cancellable.cancel();
}
final Queue pipeline = state.getPipeline();
if (!pipeline.isEmpty()
|| conn.isResponseSubmitted()
|| state.getResponseState().compareTo(MessageState.INIT) > 0) {
// There is not much that we can do if a response
// has already been submitted or pipelining is being used.
shutdownConnection(conn);
} else {
try {
final Incoming incoming = state.getIncoming();
final HttpRequest request = incoming != null ? incoming.getRequest() : null;
final HttpContext context = incoming != null ? incoming.getContext() : new BasicHttpContext();
final HttpAsyncResponseProducer responseProducer = handleException(cause, context);
final HttpResponse response = responseProducer.generateResponse();
final Outgoing outgoing = new Outgoing(request, response, responseProducer, context);
state.setResponseState(MessageState.INIT);
state.setOutgoing(outgoing);
commitFinalResponse(conn, state);
} catch (final Exception ex) {
shutdownConnection(conn);
closeHandlers(state);
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
} else {
log(ex);
}
}
}
}
@Override
public void requestReceived(
final NHttpServerConnection conn) throws IOException, HttpException {
final State state = getState(conn);
Asserts.notNull(state, "Connection state");
Asserts.check(state.getRequestState() == MessageState.READY,
"Unexpected request state %s", state.getRequestState());
final HttpRequest request = conn.getHttpRequest();
final HttpContext context = new BasicHttpContext();
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
this.httpProcessor.process(request, context);
final HttpAsyncRequestHandler