001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027
028package org.apache.http.impl.conn;
029
030import java.nio.charset.Charset;
031import java.nio.charset.CharsetDecoder;
032import java.nio.charset.CharsetEncoder;
033import java.nio.charset.CodingErrorAction;
034import java.util.concurrent.atomic.AtomicLong;
035
036import org.apache.commons.logging.Log;
037import org.apache.commons.logging.LogFactory;
038import org.apache.http.HttpRequest;
039import org.apache.http.HttpResponse;
040import org.apache.http.annotation.Contract;
041import org.apache.http.annotation.ThreadingBehavior;
042import org.apache.http.config.ConnectionConfig;
043import org.apache.http.conn.HttpConnectionFactory;
044import org.apache.http.conn.ManagedHttpClientConnection;
045import org.apache.http.conn.routing.HttpRoute;
046import org.apache.http.entity.ContentLengthStrategy;
047import org.apache.http.impl.entity.LaxContentLengthStrategy;
048import org.apache.http.impl.entity.StrictContentLengthStrategy;
049import org.apache.http.impl.io.DefaultHttpRequestWriterFactory;
050import org.apache.http.io.HttpMessageParserFactory;
051import org.apache.http.io.HttpMessageWriterFactory;
052
053/**
054 * Factory for {@link ManagedHttpClientConnection} instances.
055 * @since 4.3
056 */
057@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
058public class ManagedHttpClientConnectionFactory
059        implements HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> {
060
061    private static final AtomicLong COUNTER = new AtomicLong();
062
063    public static final ManagedHttpClientConnectionFactory INSTANCE = new ManagedHttpClientConnectionFactory();
064
065    private final Log log = LogFactory.getLog(DefaultManagedHttpClientConnection.class);
066    private final Log headerlog = LogFactory.getLog("org.apache.http.headers");
067    private final Log wirelog = LogFactory.getLog("org.apache.http.wire");
068
069    private final HttpMessageWriterFactory<HttpRequest> requestWriterFactory;
070    private final HttpMessageParserFactory<HttpResponse> responseParserFactory;
071    private final ContentLengthStrategy incomingContentStrategy;
072    private final ContentLengthStrategy outgoingContentStrategy;
073
074    /**
075     * @since 4.4
076     */
077    public ManagedHttpClientConnectionFactory(
078            final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
079            final HttpMessageParserFactory<HttpResponse> responseParserFactory,
080            final ContentLengthStrategy incomingContentStrategy,
081            final ContentLengthStrategy outgoingContentStrategy) {
082        super();
083        this.requestWriterFactory = requestWriterFactory != null ? requestWriterFactory :
084                DefaultHttpRequestWriterFactory.INSTANCE;
085        this.responseParserFactory = responseParserFactory != null ? responseParserFactory :
086                DefaultHttpResponseParserFactory.INSTANCE;
087        this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
088                LaxContentLengthStrategy.INSTANCE;
089        this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
090                StrictContentLengthStrategy.INSTANCE;
091    }
092
093    public ManagedHttpClientConnectionFactory(
094            final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
095            final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
096        this(requestWriterFactory, responseParserFactory, null, null);
097    }
098
099    public ManagedHttpClientConnectionFactory(
100            final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
101        this(null, responseParserFactory);
102    }
103
104    public ManagedHttpClientConnectionFactory() {
105        this(null, null);
106    }
107
108    @Override
109    public ManagedHttpClientConnection create(final HttpRoute route, final ConnectionConfig config) {
110        final ConnectionConfig cconfig = config != null ? config : ConnectionConfig.DEFAULT;
111        CharsetDecoder chardecoder = null;
112        CharsetEncoder charencoder = null;
113        final Charset charset = cconfig.getCharset();
114        final CodingErrorAction malformedInputAction = cconfig.getMalformedInputAction() != null ?
115                cconfig.getMalformedInputAction() : CodingErrorAction.REPORT;
116        final CodingErrorAction unmappableInputAction = cconfig.getUnmappableInputAction() != null ?
117                cconfig.getUnmappableInputAction() : CodingErrorAction.REPORT;
118        if (charset != null) {
119            chardecoder = charset.newDecoder();
120            chardecoder.onMalformedInput(malformedInputAction);
121            chardecoder.onUnmappableCharacter(unmappableInputAction);
122            charencoder = charset.newEncoder();
123            charencoder.onMalformedInput(malformedInputAction);
124            charencoder.onUnmappableCharacter(unmappableInputAction);
125        }
126        final String id = "http-outgoing-" + Long.toString(COUNTER.getAndIncrement());
127        return new LoggingManagedHttpClientConnection(
128                id,
129                log,
130                headerlog,
131                wirelog,
132                cconfig.getBufferSize(),
133                cconfig.getFragmentSizeHint(),
134                chardecoder,
135                charencoder,
136                cconfig.getMessageConstraints(),
137                incomingContentStrategy,
138                outgoingContentStrategy,
139                requestWriterFactory,
140                responseParserFactory);
141    }
142
143}