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.io.IOException;
031import java.io.InterruptedIOException;
032import java.net.Socket;
033import java.nio.charset.CharsetDecoder;
034import java.nio.charset.CharsetEncoder;
035import java.util.Map;
036import java.util.concurrent.ConcurrentHashMap;
037
038import javax.net.ssl.SSLSession;
039import javax.net.ssl.SSLSocket;
040
041import org.apache.http.HttpRequest;
042import org.apache.http.HttpResponse;
043import org.apache.http.config.MessageConstraints;
044import org.apache.http.conn.ManagedHttpClientConnection;
045import org.apache.http.entity.ContentLengthStrategy;
046import org.apache.http.impl.DefaultBHttpClientConnection;
047import org.apache.http.io.HttpMessageParserFactory;
048import org.apache.http.io.HttpMessageWriterFactory;
049import org.apache.http.protocol.HttpContext;
050
051/**
052 * Default {@link ManagedHttpClientConnection} implementation.
053 * @since 4.3
054 */
055public class DefaultManagedHttpClientConnection extends DefaultBHttpClientConnection
056                                 implements ManagedHttpClientConnection, HttpContext {
057
058    private final String id;
059    private final Map<String, Object> attributes;
060
061    private volatile boolean shutdown;
062
063    public DefaultManagedHttpClientConnection(
064            final String id,
065            final int buffersize,
066            final int fragmentSizeHint,
067            final CharsetDecoder chardecoder,
068            final CharsetEncoder charencoder,
069            final MessageConstraints constraints,
070            final ContentLengthStrategy incomingContentStrategy,
071            final ContentLengthStrategy outgoingContentStrategy,
072            final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
073            final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
074        super(buffersize, fragmentSizeHint, chardecoder, charencoder,
075                constraints, incomingContentStrategy, outgoingContentStrategy,
076                requestWriterFactory, responseParserFactory);
077        this.id = id;
078        this.attributes = new ConcurrentHashMap<String, Object>();
079    }
080
081    public DefaultManagedHttpClientConnection(
082            final String id,
083            final int buffersize) {
084        this(id, buffersize, buffersize, null, null, null, null, null, null, null);
085    }
086
087    @Override
088    public String getId() {
089        return this.id;
090    }
091
092    @Override
093    public void shutdown() throws IOException {
094        this.shutdown = true;
095        super.shutdown();
096    }
097
098    @Override
099    public Object getAttribute(final String id) {
100        return this.attributes.get(id);
101    }
102
103    @Override
104    public Object removeAttribute(final String id) {
105        return this.attributes.remove(id);
106    }
107
108    @Override
109    public void setAttribute(final String id, final Object obj) {
110        this.attributes.put(id, obj);
111    }
112
113    @Override
114    public void bind(final Socket socket) throws IOException {
115        if (this.shutdown) {
116            socket.close(); // allow this to throw...
117            // ...but if it doesn't, explicitly throw one ourselves.
118            throw new InterruptedIOException("Connection already shutdown");
119        }
120        super.bind(socket);
121    }
122
123    @Override
124    public Socket getSocket() {
125        return super.getSocket();
126    }
127
128    @Override
129    public SSLSession getSSLSession() {
130        final Socket socket = super.getSocket();
131        if (socket instanceof SSLSocket) {
132            return ((SSLSocket) socket).getSession();
133        } else {
134            return null;
135        }
136    }
137
138}