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 */ 027package org.apache.http.impl.conn; 028 029import java.io.IOException; 030import java.net.InetAddress; 031import java.net.Socket; 032 033import javax.net.ssl.SSLSession; 034 035import org.apache.http.HttpClientConnection; 036import org.apache.http.HttpConnectionMetrics; 037import org.apache.http.HttpEntityEnclosingRequest; 038import org.apache.http.HttpException; 039import org.apache.http.HttpRequest; 040import org.apache.http.HttpResponse; 041import org.apache.http.conn.ManagedHttpClientConnection; 042import org.apache.http.protocol.HttpContext; 043 044/** 045 * @since 4.3 046 */ 047class CPoolProxy implements ManagedHttpClientConnection, HttpContext { 048 049 private volatile CPoolEntry poolEntry; 050 051 CPoolProxy(final CPoolEntry entry) { 052 super(); 053 this.poolEntry = entry; 054 } 055 056 CPoolEntry getPoolEntry() { 057 return this.poolEntry; 058 } 059 060 CPoolEntry detach() { 061 final CPoolEntry local = this.poolEntry; 062 this.poolEntry = null; 063 return local; 064 } 065 066 ManagedHttpClientConnection getConnection() { 067 final CPoolEntry local = this.poolEntry; 068 if (local == null) { 069 return null; 070 } 071 return local.getConnection(); 072 } 073 074 ManagedHttpClientConnection getValidConnection() { 075 final ManagedHttpClientConnection conn = getConnection(); 076 if (conn == null) { 077 throw new ConnectionShutdownException(); 078 } 079 return conn; 080 } 081 082 @Override 083 public void close() throws IOException { 084 final CPoolEntry local = this.poolEntry; 085 if (local != null) { 086 local.closeConnection(); 087 } 088 } 089 090 @Override 091 public void shutdown() throws IOException { 092 final CPoolEntry local = this.poolEntry; 093 if (local != null) { 094 local.shutdownConnection(); 095 } 096 } 097 098 @Override 099 public boolean isOpen() { 100 final CPoolEntry local = this.poolEntry; 101 if (local != null) { 102 return !local.isClosed(); 103 } else { 104 return false; 105 } 106 } 107 108 @Override 109 public boolean isStale() { 110 final HttpClientConnection conn = getConnection(); 111 if (conn != null) { 112 return conn.isStale(); 113 } else { 114 return true; 115 } 116 } 117 118 @Override 119 public void setSocketTimeout(final int timeout) { 120 getValidConnection().setSocketTimeout(timeout); 121 } 122 123 @Override 124 public int getSocketTimeout() { 125 return getValidConnection().getSocketTimeout(); 126 } 127 128 @Override 129 public String getId() { 130 return getValidConnection().getId(); 131 } 132 133 @Override 134 public void bind(final Socket socket) throws IOException { 135 getValidConnection().bind(socket); 136 } 137 138 @Override 139 public Socket getSocket() { 140 return getValidConnection().getSocket(); 141 } 142 143 @Override 144 public SSLSession getSSLSession() { 145 return getValidConnection().getSSLSession(); 146 } 147 148 @Override 149 public boolean isResponseAvailable(final int timeout) throws IOException { 150 return getValidConnection().isResponseAvailable(timeout); 151 } 152 153 @Override 154 public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException { 155 getValidConnection().sendRequestHeader(request); 156 } 157 158 @Override 159 public void sendRequestEntity(final HttpEntityEnclosingRequest request) throws HttpException, IOException { 160 getValidConnection().sendRequestEntity(request); 161 } 162 163 @Override 164 public HttpResponse receiveResponseHeader() throws HttpException, IOException { 165 return getValidConnection().receiveResponseHeader(); 166 } 167 168 @Override 169 public void receiveResponseEntity(final HttpResponse response) throws HttpException, IOException { 170 getValidConnection().receiveResponseEntity(response); 171 } 172 173 @Override 174 public void flush() throws IOException { 175 getValidConnection().flush(); 176 } 177 178 @Override 179 public HttpConnectionMetrics getMetrics() { 180 return getValidConnection().getMetrics(); 181 } 182 183 @Override 184 public InetAddress getLocalAddress() { 185 return getValidConnection().getLocalAddress(); 186 } 187 188 @Override 189 public int getLocalPort() { 190 return getValidConnection().getLocalPort(); 191 } 192 193 @Override 194 public InetAddress getRemoteAddress() { 195 return getValidConnection().getRemoteAddress(); 196 } 197 198 @Override 199 public int getRemotePort() { 200 return getValidConnection().getRemotePort(); 201 } 202 203 @Override 204 public Object getAttribute(final String id) { 205 final ManagedHttpClientConnection conn = getValidConnection(); 206 if (conn instanceof HttpContext) { 207 return ((HttpContext) conn).getAttribute(id); 208 } else { 209 return null; 210 } 211 } 212 213 @Override 214 public void setAttribute(final String id, final Object obj) { 215 final ManagedHttpClientConnection conn = getValidConnection(); 216 if (conn instanceof HttpContext) { 217 ((HttpContext) conn).setAttribute(id, obj); 218 } 219 } 220 221 @Override 222 public Object removeAttribute(final String id) { 223 final ManagedHttpClientConnection conn = getValidConnection(); 224 if (conn instanceof HttpContext) { 225 return ((HttpContext) conn).removeAttribute(id); 226 } else { 227 return null; 228 } 229 } 230 231 @Override 232 public String toString() { 233 final StringBuilder sb = new StringBuilder("CPoolProxy{"); 234 final ManagedHttpClientConnection conn = getConnection(); 235 if (conn != null) { 236 sb.append(conn); 237 } else { 238 sb.append("detached"); 239 } 240 sb.append('}'); 241 return sb.toString(); 242 } 243 244 public static HttpClientConnection newProxy(final CPoolEntry poolEntry) { 245 return new CPoolProxy(poolEntry); 246 } 247 248 private static CPoolProxy getProxy(final HttpClientConnection conn) { 249 if (!CPoolProxy.class.isInstance(conn)) { 250 throw new IllegalStateException("Unexpected connection proxy class: " + conn.getClass()); 251 } 252 return CPoolProxy.class.cast(conn); 253 } 254 255 public static CPoolEntry getPoolEntry(final HttpClientConnection proxy) { 256 final CPoolEntry entry = getProxy(proxy).getPoolEntry(); 257 if (entry == null) { 258 throw new ConnectionShutdownException(); 259 } 260 return entry; 261 } 262 263 public static CPoolEntry detach(final HttpClientConnection conn) { 264 return getProxy(conn).detach(); 265 } 266 267}