Search in sources :

Example 1 with ConnectionReuseStrategy

use of org.apache.hc.core5.http.ConnectionReuseStrategy in project httpcomponents-core by apache.

the class Http1IntegrationTest method testTruncatedChunk.

@Test
public void testTruncatedChunk() throws Exception {
    final InetSocketAddress serverEndpoint = server.start(new InternalServerHttp1EventHandlerFactory(HttpProcessors.server(), (request, context) -> new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {

        @Override
        protected void handle(final Message<HttpRequest, String> request, final AsyncServerRequestHandler.ResponseTrigger responseTrigger, final HttpContext context) throws IOException, HttpException {
            responseTrigger.submitResponse(new BasicResponseProducer(new StringAsyncEntityProducer("useful stuff")), context);
        }
    }, Http1Config.DEFAULT, CharCodingConfig.DEFAULT, DefaultConnectionReuseStrategy.INSTANCE, scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null) {

        @Override
        protected ServerHttp1StreamDuplexer createServerHttp1StreamDuplexer(final ProtocolIOSession ioSession, final HttpProcessor httpProcessor, final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory, final Http1Config http1Config, final CharCodingConfig connectionConfig, final ConnectionReuseStrategy connectionReuseStrategy, final NHttpMessageParser<HttpRequest> incomingMessageParser, final NHttpMessageWriter<HttpResponse> outgoingMessageWriter, final ContentLengthStrategy incomingContentStrategy, final ContentLengthStrategy outgoingContentStrategy, final Http1StreamListener streamListener) {
            return new ServerHttp1StreamDuplexer(ioSession, httpProcessor, exchangeHandlerFactory, scheme.id, http1Config, connectionConfig, connectionReuseStrategy, incomingMessageParser, outgoingMessageWriter, incomingContentStrategy, outgoingContentStrategy, streamListener) {

                @Override
                protected ContentEncoder createContentEncoder(final long len, final WritableByteChannel channel, final SessionOutputBuffer buffer, final BasicHttpTransportMetrics metrics) throws HttpException {
                    if (len == ContentLengthStrategy.CHUNKED) {
                        return new BrokenChunkEncoder(channel, buffer, metrics);
                    } else {
                        return super.createContentEncoder(len, channel, buffer, metrics);
                    }
                }
            };
        }
    });
    client.start();
    final Future<ClientSessionEndpoint> connectFuture = client.connect("localhost", serverEndpoint.getPort(), TIMEOUT);
    final ClientSessionEndpoint streamEndpoint = connectFuture.get();
    final AsyncRequestProducer requestProducer = new BasicRequestProducer(Method.GET, createRequestURI(serverEndpoint, "/hello"));
    final StringAsyncEntityConsumer entityConsumer = new StringAsyncEntityConsumer() {

        @Override
        public void releaseResources() {
        // Do not clear internal content buffer
        }
    };
    final BasicResponseConsumer<String> responseConsumer = new BasicResponseConsumer<>(entityConsumer);
    final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(requestProducer, responseConsumer, null);
    final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> future1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
    final Throwable cause = exception.getCause();
    Assertions.assertTrue(cause instanceof MalformedChunkCodingException);
    Assertions.assertEquals("garbage", entityConsumer.generateContent());
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) BasicResponseProducer(org.apache.hc.core5.http.nio.support.BasicResponseProducer) IOReactorConfig(org.apache.hc.core5.reactor.IOReactorConfig) CharCodingConfig(org.apache.hc.core5.http.config.CharCodingConfig) BasicAsyncServerExpectationDecorator(org.apache.hc.core5.http.nio.support.BasicAsyncServerExpectationDecorator) StringAsyncEntityConsumer(org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer) AbstractClassicEntityProducer(org.apache.hc.core5.http.nio.support.classic.AbstractClassicEntityProducer) HttpProcessor(org.apache.hc.core5.http.protocol.HttpProcessor) Future(java.util.concurrent.Future) Map(java.util.Map) DigestingEntityProducer(org.apache.hc.core5.http.nio.entity.DigestingEntityProducer) AbstractClassicServerExchangeHandler(org.apache.hc.core5.http.nio.support.classic.AbstractClassicServerExchangeHandler) RequestConnControl(org.apache.hc.core5.http.protocol.RequestConnControl) CancellationException(java.util.concurrent.CancellationException) DataStreamChannel(org.apache.hc.core5.http.nio.DataStreamChannel) HandlerFactory(org.apache.hc.core5.http.nio.HandlerFactory) ContentLengthStrategy(org.apache.hc.core5.http.ContentLengthStrategy) ConnectionReuseStrategy(org.apache.hc.core5.http.ConnectionReuseStrategy) Timeout(org.apache.hc.core5.util.Timeout) StandardCharsets(java.nio.charset.StandardCharsets) Executors(java.util.concurrent.Executors) MalformedChunkCodingException(org.apache.hc.core5.http.MalformedChunkCodingException) HeaderElements(org.apache.hc.core5.http.HeaderElements) CapacityChannel(org.apache.hc.core5.http.nio.CapacityChannel) HttpContext(org.apache.hc.core5.http.protocol.HttpContext) AsyncServerRequestHandler(org.apache.hc.core5.http.nio.AsyncServerRequestHandler) RunWith(org.junit.runner.RunWith) InterruptedIOException(java.io.InterruptedIOException) NHttpMessageParser(org.apache.hc.core5.http.nio.NHttpMessageParser) EntityDetails(org.apache.hc.core5.http.EntityDetails) HttpVersion(org.apache.hc.core5.http.HttpVersion) StringTokenizer(java.util.StringTokenizer) RequestTargetHost(org.apache.hc.core5.http.protocol.RequestTargetHost) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) NHttpMessageWriter(org.apache.hc.core5.http.nio.NHttpMessageWriter) SessionOutputBuffer(org.apache.hc.core5.http.nio.SessionOutputBuffer) AsyncResponseProducer(org.apache.hc.core5.http.nio.AsyncResponseProducer) BasicHttpRequest(org.apache.hc.core5.http.message.BasicHttpRequest) ImmediateResponseExchangeHandler(org.apache.hc.core5.http.nio.support.ImmediateResponseExchangeHandler) BufferedWriter(java.io.BufferedWriter) IOException(java.io.IOException) Test(org.junit.Test) InputStreamReader(java.io.InputStreamReader) URIScheme(org.apache.hc.core5.http.URIScheme) ExecutionException(java.util.concurrent.ExecutionException) BasicRequestProducer(org.apache.hc.core5.http.nio.support.BasicRequestProducer) HttpHeaders(org.apache.hc.core5.http.HttpHeaders) AfterEach(org.junit.jupiter.api.AfterEach) HttpHost(org.apache.hc.core5.http.HttpHost) HttpRequest(org.apache.hc.core5.http.HttpRequest) ContentType(org.apache.hc.core5.http.ContentType) WritableByteChannel(java.nio.channels.WritableByteChannel) AsyncRequestProducer(org.apache.hc.core5.http.nio.AsyncRequestProducer) BufferedReader(java.io.BufferedReader) HttpStatus(org.apache.hc.core5.http.HttpStatus) AsyncEntityProducers(org.apache.hc.core5.http.nio.entity.AsyncEntityProducers) CoreMatchers(org.hamcrest.CoreMatchers) AsyncRequestBuilder(org.apache.hc.core5.http.nio.support.AsyncRequestBuilder) RequestContent(org.apache.hc.core5.http.protocol.RequestContent) URISyntaxException(java.net.URISyntaxException) LoggerFactory(org.slf4j.LoggerFactory) Random(java.util.Random) BasicHttpTransportMetrics(org.apache.hc.core5.http.impl.BasicHttpTransportMetrics) ByteBuffer(java.nio.ByteBuffer) AbstractClassicEntityConsumer(org.apache.hc.core5.http.nio.support.classic.AbstractClassicEntityConsumer) HttpProcessors(org.apache.hc.core5.http.impl.HttpProcessors) URI(java.net.URI) Http1Config(org.apache.hc.core5.http.config.Http1Config) EnableRuleMigrationSupport(org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport) AsyncServerExchangeHandler(org.apache.hc.core5.http.nio.AsyncServerExchangeHandler) RequestValidateHost(org.apache.hc.core5.http.protocol.RequestValidateHost) Parameterized(org.junit.runners.Parameterized) Message(org.apache.hc.core5.http.Message) TimeValue(org.apache.hc.core5.util.TimeValue) Collection(java.util.Collection) BasicResponseConsumer(org.apache.hc.core5.http.nio.support.BasicResponseConsumer) InetSocketAddress(java.net.InetSocketAddress) StringAsyncEntityProducer(org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer) List(java.util.List) ContentEncoder(org.apache.hc.core5.http.nio.ContentEncoder) SSLTestContexts(org.apache.hc.core5.testing.SSLTestContexts) CharArrayBuffer(org.apache.hc.core5.util.CharArrayBuffer) ProtocolIOSession(org.apache.hc.core5.reactor.ProtocolIOSession) Queue(java.util.Queue) DefaultConnectionReuseStrategy(org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy) AbstractContentEncoder(org.apache.hc.core5.http.impl.nio.AbstractContentEncoder) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) ResponseChannel(org.apache.hc.core5.http.nio.ResponseChannel) TextUtils(org.apache.hc.core5.util.TextUtils) AsyncRequestConsumer(org.apache.hc.core5.http.nio.AsyncRequestConsumer) Charset(java.nio.charset.Charset) OutputStreamWriter(java.io.OutputStreamWriter) ServerHttp1StreamDuplexer(org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexer) HttpResponse(org.apache.hc.core5.http.HttpResponse) LinkedList(java.util.LinkedList) Http1StreamListener(org.apache.hc.core5.http.impl.Http1StreamListener) DefaultHttpProcessor(org.apache.hc.core5.http.protocol.DefaultHttpProcessor) OutputStream(java.io.OutputStream) HttpException(org.apache.hc.core5.http.HttpException) Logger(org.slf4j.Logger) Header(org.apache.hc.core5.http.Header) ProtocolException(org.apache.hc.core5.http.ProtocolException) BasicRequestConsumer(org.apache.hc.core5.http.nio.support.BasicRequestConsumer) AbstractServerExchangeHandler(org.apache.hc.core5.http.nio.support.AbstractServerExchangeHandler) DigestingEntityConsumer(org.apache.hc.core5.http.nio.entity.DigestingEntityConsumer) AsyncEntityProducer(org.apache.hc.core5.http.nio.AsyncEntityProducer) IOSession(org.apache.hc.core5.reactor.IOSession) Method(org.apache.hc.core5.http.Method) BasicHttpResponse(org.apache.hc.core5.http.message.BasicHttpResponse) Assertions(org.junit.jupiter.api.Assertions) InputStream(java.io.InputStream) CharCodingConfig(org.apache.hc.core5.http.config.CharCodingConfig) Message(org.apache.hc.core5.http.Message) InetSocketAddress(java.net.InetSocketAddress) ProtocolIOSession(org.apache.hc.core5.reactor.ProtocolIOSession) HttpProcessor(org.apache.hc.core5.http.protocol.HttpProcessor) DefaultHttpProcessor(org.apache.hc.core5.http.protocol.DefaultHttpProcessor) StringAsyncEntityProducer(org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer) Http1StreamListener(org.apache.hc.core5.http.impl.Http1StreamListener) AsyncRequestProducer(org.apache.hc.core5.http.nio.AsyncRequestProducer) SessionOutputBuffer(org.apache.hc.core5.http.nio.SessionOutputBuffer) BasicResponseConsumer(org.apache.hc.core5.http.nio.support.BasicResponseConsumer) HttpException(org.apache.hc.core5.http.HttpException) ExecutionException(java.util.concurrent.ExecutionException) AsyncServerExchangeHandler(org.apache.hc.core5.http.nio.AsyncServerExchangeHandler) StringAsyncEntityConsumer(org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer) BasicHttpRequest(org.apache.hc.core5.http.message.BasicHttpRequest) HttpRequest(org.apache.hc.core5.http.HttpRequest) MalformedChunkCodingException(org.apache.hc.core5.http.MalformedChunkCodingException) ServerHttp1StreamDuplexer(org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexer) ContentEncoder(org.apache.hc.core5.http.nio.ContentEncoder) AbstractContentEncoder(org.apache.hc.core5.http.impl.nio.AbstractContentEncoder) BasicRequestProducer(org.apache.hc.core5.http.nio.support.BasicRequestProducer) HttpContext(org.apache.hc.core5.http.protocol.HttpContext) WritableByteChannel(java.nio.channels.WritableByteChannel) HttpResponse(org.apache.hc.core5.http.HttpResponse) BasicHttpResponse(org.apache.hc.core5.http.message.BasicHttpResponse) ContentLengthStrategy(org.apache.hc.core5.http.ContentLengthStrategy) BasicHttpTransportMetrics(org.apache.hc.core5.http.impl.BasicHttpTransportMetrics) ConnectionReuseStrategy(org.apache.hc.core5.http.ConnectionReuseStrategy) DefaultConnectionReuseStrategy(org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy) BasicResponseProducer(org.apache.hc.core5.http.nio.support.BasicResponseProducer) Http1Config(org.apache.hc.core5.http.config.Http1Config) Test(org.junit.Test)

Example 2 with ConnectionReuseStrategy

use of org.apache.hc.core5.http.ConnectionReuseStrategy in project httpcomponents-core by apache.

the class ClientHttp1StreamDuplexer method execute.

@Override
void execute(final RequestExecutionCommand executionCommand) throws HttpException, IOException {
    final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
    final HttpCoreContext context = HttpCoreContext.adapt(executionCommand.getContext());
    context.setAttribute(HttpCoreContext.SSL_SESSION, getSSLSession());
    context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, getEndpointDetails());
    final ClientHttp1StreamHandler handler = new ClientHttp1StreamHandler(outputChannel, httpProcessor, http1Config, connectionReuseStrategy, exchangeHandler, context);
    pipeline.add(handler);
    outgoing = handler;
    if (handler.isOutputReady()) {
        handler.produceOutput();
    }
}
Also used : AsyncClientExchangeHandler(org.apache.hc.core5.http.nio.AsyncClientExchangeHandler) HttpCoreContext(org.apache.hc.core5.http.protocol.HttpCoreContext)

Example 3 with ConnectionReuseStrategy

use of org.apache.hc.core5.http.ConnectionReuseStrategy in project httpcomponents-core by apache.

the class DefaultConnectionReuseStrategy method keepAlive.

// see interface ConnectionReuseStrategy
@Override
public boolean keepAlive(final HttpRequest request, final HttpResponse response, final HttpContext context) {
    Args.notNull(response, "HTTP response");
    if (request != null) {
        final Iterator<String> ti = new BasicTokenIterator(request.headerIterator(HttpHeaders.CONNECTION));
        while (ti.hasNext()) {
            final String token = ti.next();
            if (HeaderElements.CLOSE.equalsIgnoreCase(token)) {
                return false;
            }
        }
    }
    // returns content as part of a HTTP 204 response.
    if (response.getCode() == HttpStatus.SC_NO_CONTENT) {
        final Header clh = response.getFirstHeader(HttpHeaders.CONTENT_LENGTH);
        if (clh != null) {
            try {
                final long contentLen = Long.parseLong(clh.getValue());
                if (contentLen > 0) {
                    return false;
                }
            } catch (final NumberFormatException ex) {
            // fall through
            }
        }
        if (response.containsHeader(HttpHeaders.TRANSFER_ENCODING)) {
            return false;
        }
    }
    // Check for a self-terminating entity. If the end of the entity will
    // be indicated by closing the connection, there is no keep-alive.
    final Header teh = response.getFirstHeader(HttpHeaders.TRANSFER_ENCODING);
    if (teh != null) {
        if (!HeaderElements.CHUNKED_ENCODING.equalsIgnoreCase(teh.getValue())) {
            return false;
        }
    } else {
        final String method = request != null ? request.getMethod() : null;
        if (MessageSupport.canResponseHaveBody(method, response) && response.countHeaders(HttpHeaders.CONTENT_LENGTH) != 1) {
            return false;
        }
    }
    // Check for the "Connection" header. If that is absent, check for
    // the "Proxy-Connection" header. The latter is an unspecified and
    // broken but unfortunately common extension of HTTP.
    Iterator<Header> headerIterator = response.headerIterator(HttpHeaders.CONNECTION);
    if (!headerIterator.hasNext()) {
        headerIterator = response.headerIterator("Proxy-Connection");
    }
    final ProtocolVersion ver = response.getVersion() != null ? response.getVersion() : context.getProtocolVersion();
    if (headerIterator.hasNext()) {
        if (ver.greaterEquals(HttpVersion.HTTP_1_1)) {
            final Iterator<String> it = new BasicTokenIterator(headerIterator);
            while (it.hasNext()) {
                final String token = it.next();
                if (HeaderElements.CLOSE.equalsIgnoreCase(token)) {
                    return false;
                }
            }
            return true;
        }
        final Iterator<String> it = new BasicTokenIterator(headerIterator);
        while (it.hasNext()) {
            final String token = it.next();
            if (HeaderElements.KEEP_ALIVE.equalsIgnoreCase(token)) {
                return true;
            }
        }
        return false;
    }
    return ver.greaterEquals(HttpVersion.HTTP_1_1);
}
Also used : Header(org.apache.hc.core5.http.Header) ProtocolVersion(org.apache.hc.core5.http.ProtocolVersion) BasicTokenIterator(org.apache.hc.core5.http.message.BasicTokenIterator)

Example 4 with ConnectionReuseStrategy

use of org.apache.hc.core5.http.ConnectionReuseStrategy in project commons-vfs by apache.

the class Http5FileProvider method createHttpClientBuilder.

/**
 * Create an {@link HttpClientBuilder} object. Invoked by {@link #createHttpClient(Http5FileSystemConfigBuilder, GenericFileName, FileSystemOptions)}.
 *
 * @param builder Configuration options builder for HTTP4 provider
 * @param rootName The root path
 * @param fileSystemOptions The FileSystem options
 * @return an {@link HttpClientBuilder} object
 * @throws FileSystemException if an error occurs
 */
protected HttpClientBuilder createHttpClientBuilder(final Http5FileSystemConfigBuilder builder, final GenericFileName rootName, final FileSystemOptions fileSystemOptions) throws FileSystemException {
    final List<Header> defaultHeaders = new ArrayList<>();
    defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, builder.getUserAgent(fileSystemOptions)));
    final ConnectionReuseStrategy connectionReuseStrategy = builder.isKeepAlive(fileSystemOptions) ? DefaultConnectionReuseStrategy.INSTANCE : (request, response, context) -> false;
    final HttpClientBuilder httpClientBuilder = HttpClients.custom().setRoutePlanner(createHttpRoutePlanner(builder, fileSystemOptions)).setConnectionManager(createConnectionManager(builder, fileSystemOptions)).setConnectionReuseStrategy(connectionReuseStrategy).setDefaultRequestConfig(createDefaultRequestConfig(builder, fileSystemOptions)).setDefaultHeaders(defaultHeaders).setDefaultCookieStore(createDefaultCookieStore(builder, fileSystemOptions));
    if (!builder.getFollowRedirect(fileSystemOptions)) {
        httpClientBuilder.disableRedirectHandling();
    }
    return httpClientBuilder;
}
Also used : BasicHeader(org.apache.hc.core5.http.message.BasicHeader) Header(org.apache.hc.core5.http.Header) ArrayList(java.util.ArrayList) HttpClientBuilder(org.apache.hc.client5.http.impl.classic.HttpClientBuilder) ConnectionReuseStrategy(org.apache.hc.core5.http.ConnectionReuseStrategy) DefaultConnectionReuseStrategy(org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy) BasicHeader(org.apache.hc.core5.http.message.BasicHeader)

Example 5 with ConnectionReuseStrategy

use of org.apache.hc.core5.http.ConnectionReuseStrategy in project httpcomponents-core by apache.

the class ServerHttp1StreamDuplexer method terminateExchange.

void terminateExchange(final HttpException ex) throws HttpException, IOException {
    suspendSessionInput();
    final ServerHttp1StreamHandler streamHandler;
    final HttpCoreContext context = HttpCoreContext.create();
    context.setAttribute(HttpCoreContext.SSL_SESSION, getSSLSession());
    context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, getEndpointDetails());
    if (outgoing == null) {
        streamHandler = new ServerHttp1StreamHandler(outputChannel, httpProcessor, connectionReuseStrategy, exchangeHandlerFactory, context);
        outgoing = streamHandler;
    } else {
        streamHandler = new ServerHttp1StreamHandler(new DelayedOutputChannel(outputChannel), httpProcessor, connectionReuseStrategy, exchangeHandlerFactory, context);
        pipeline.add(streamHandler);
    }
    streamHandler.terminateExchange(ex);
    incoming = null;
}
Also used : HttpCoreContext(org.apache.hc.core5.http.protocol.HttpCoreContext)

Aggregations

Header (org.apache.hc.core5.http.Header)3 ConnectionReuseStrategy (org.apache.hc.core5.http.ConnectionReuseStrategy)2 DefaultConnectionReuseStrategy (org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy)2 HttpCoreContext (org.apache.hc.core5.http.protocol.HttpCoreContext)2 BufferedReader (java.io.BufferedReader)1 BufferedWriter (java.io.BufferedWriter)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 InterruptedIOException (java.io.InterruptedIOException)1 OutputStream (java.io.OutputStream)1 OutputStreamWriter (java.io.OutputStreamWriter)1 InetSocketAddress (java.net.InetSocketAddress)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 ByteBuffer (java.nio.ByteBuffer)1 WritableByteChannel (java.nio.channels.WritableByteChannel)1 Charset (java.nio.charset.Charset)1 StandardCharsets (java.nio.charset.StandardCharsets)1 ArrayList (java.util.ArrayList)1