mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 00:38:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
369
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/AbstractClientConnAdapter.java
vendored
Normal file
369
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/AbstractClientConnAdapter.java
vendored
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpConnectionMetrics;
|
||||
import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
* Abstract adapter from {@link OperatedClientConnection operated} to
|
||||
* {@link ManagedClientConnection managed} client connections.
|
||||
* Read and write methods are delegated to the wrapped connection.
|
||||
* Operations affecting the connection state have to be implemented
|
||||
* by derived classes. Operations for querying the connection state
|
||||
* are delegated to the wrapped connection if there is one, or
|
||||
* return a default value if there is none.
|
||||
* <p>
|
||||
* This adapter tracks the checkpoints for reusable communication states,
|
||||
* as indicated by {@link #markReusable markReusable} and queried by
|
||||
* {@link #isMarkedReusable isMarkedReusable}.
|
||||
* All send and receive operations will automatically clear the mark.
|
||||
* <p>
|
||||
* Connection release calls are delegated to the connection manager,
|
||||
* if there is one. {@link #abortConnection abortConnection} will
|
||||
* clear the reusability mark first. The connection manager is
|
||||
* expected to tolerate multiple calls to the release method.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) do not use
|
||||
*/
|
||||
@Deprecated
|
||||
@NotThreadSafe
|
||||
public abstract class AbstractClientConnAdapter implements ManagedClientConnection, HttpContext {
|
||||
|
||||
/**
|
||||
* The connection manager.
|
||||
*/
|
||||
private final ClientConnectionManager connManager;
|
||||
|
||||
/** The wrapped connection. */
|
||||
private volatile OperatedClientConnection wrappedConnection;
|
||||
|
||||
/** The reusability marker. */
|
||||
private volatile boolean markedReusable;
|
||||
|
||||
/** True if the connection has been shut down or released. */
|
||||
private volatile boolean released;
|
||||
|
||||
/** The duration this is valid for while idle (in ms). */
|
||||
private volatile long duration;
|
||||
|
||||
/**
|
||||
* Creates a new connection adapter.
|
||||
* The adapter is initially <i>not</i>
|
||||
* {@link #isMarkedReusable marked} as reusable.
|
||||
*
|
||||
* @param mgr the connection manager, or <code>null</code>
|
||||
* @param conn the connection to wrap, or <code>null</code>
|
||||
*/
|
||||
protected AbstractClientConnAdapter(final ClientConnectionManager mgr,
|
||||
final OperatedClientConnection conn) {
|
||||
super();
|
||||
connManager = mgr;
|
||||
wrappedConnection = conn;
|
||||
markedReusable = false;
|
||||
released = false;
|
||||
duration = Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches this adapter from the wrapped connection.
|
||||
* This adapter becomes useless.
|
||||
*/
|
||||
protected synchronized void detach() {
|
||||
wrappedConnection = null;
|
||||
duration = Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
protected OperatedClientConnection getWrappedConnection() {
|
||||
return wrappedConnection;
|
||||
}
|
||||
|
||||
protected ClientConnectionManager getManager() {
|
||||
return connManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated (4.1) use {@link #assertValid(OperatedClientConnection)}
|
||||
*/
|
||||
@Deprecated
|
||||
protected final void assertNotAborted() throws InterruptedIOException {
|
||||
if (isReleased()) {
|
||||
throw new InterruptedIOException("Connection has been shut down");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
* @return value of released flag
|
||||
*/
|
||||
protected boolean isReleased() {
|
||||
return released;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that there is a valid wrapped connection to delegate to.
|
||||
*
|
||||
* @throws ConnectionShutdownException if there is no wrapped connection
|
||||
* or connection has been aborted
|
||||
*/
|
||||
protected final void assertValid(
|
||||
final OperatedClientConnection wrappedConn) throws ConnectionShutdownException {
|
||||
if (isReleased() || wrappedConn == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
if (conn == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return conn.isOpen();
|
||||
}
|
||||
|
||||
public boolean isStale() {
|
||||
if (isReleased()) {
|
||||
return true;
|
||||
}
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
if (conn == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return conn.isStale();
|
||||
}
|
||||
|
||||
public void setSocketTimeout(final int timeout) {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
conn.setSocketTimeout(timeout);
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
return conn.getSocketTimeout();
|
||||
}
|
||||
|
||||
public HttpConnectionMetrics getMetrics() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
return conn.getMetrics();
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
conn.flush();
|
||||
}
|
||||
|
||||
public boolean isResponseAvailable(final int timeout) throws IOException {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
return conn.isResponseAvailable(timeout);
|
||||
}
|
||||
|
||||
public void receiveResponseEntity(final HttpResponse response)
|
||||
throws HttpException, IOException {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
unmarkReusable();
|
||||
conn.receiveResponseEntity(response);
|
||||
}
|
||||
|
||||
public HttpResponse receiveResponseHeader()
|
||||
throws HttpException, IOException {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
unmarkReusable();
|
||||
return conn.receiveResponseHeader();
|
||||
}
|
||||
|
||||
public void sendRequestEntity(final HttpEntityEnclosingRequest request)
|
||||
throws HttpException, IOException {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
unmarkReusable();
|
||||
conn.sendRequestEntity(request);
|
||||
}
|
||||
|
||||
public void sendRequestHeader(final HttpRequest request)
|
||||
throws HttpException, IOException {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
unmarkReusable();
|
||||
conn.sendRequestHeader(request);
|
||||
}
|
||||
|
||||
public InetAddress getLocalAddress() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
return conn.getLocalAddress();
|
||||
}
|
||||
|
||||
public int getLocalPort() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
return conn.getLocalPort();
|
||||
}
|
||||
|
||||
public InetAddress getRemoteAddress() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
return conn.getRemoteAddress();
|
||||
}
|
||||
|
||||
public int getRemotePort() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
return conn.getRemotePort();
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
return conn.isSecure();
|
||||
}
|
||||
|
||||
public void bind(final Socket socket) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Socket getSocket() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
if (!isOpen()) {
|
||||
return null;
|
||||
}
|
||||
return conn.getSocket();
|
||||
}
|
||||
|
||||
public SSLSession getSSLSession() {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
if (!isOpen()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SSLSession result = null;
|
||||
final Socket sock = conn.getSocket();
|
||||
if (sock instanceof SSLSocket) {
|
||||
result = ((SSLSocket)sock).getSession();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void markReusable() {
|
||||
markedReusable = true;
|
||||
}
|
||||
|
||||
public void unmarkReusable() {
|
||||
markedReusable = false;
|
||||
}
|
||||
|
||||
public boolean isMarkedReusable() {
|
||||
return markedReusable;
|
||||
}
|
||||
|
||||
public void setIdleDuration(final long duration, final TimeUnit unit) {
|
||||
if(duration > 0) {
|
||||
this.duration = unit.toMillis(duration);
|
||||
} else {
|
||||
this.duration = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void releaseConnection() {
|
||||
if (released) {
|
||||
return;
|
||||
}
|
||||
released = true;
|
||||
connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public synchronized void abortConnection() {
|
||||
if (released) {
|
||||
return;
|
||||
}
|
||||
released = true;
|
||||
unmarkReusable();
|
||||
try {
|
||||
shutdown();
|
||||
} catch (final IOException ignore) {
|
||||
}
|
||||
connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public Object getAttribute(final String id) {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
if (conn instanceof HttpContext) {
|
||||
return ((HttpContext) conn).getAttribute(id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object removeAttribute(final String id) {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
if (conn instanceof HttpContext) {
|
||||
return ((HttpContext) conn).removeAttribute(id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAttribute(final String id, final Object obj) {
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
assertValid(conn);
|
||||
if (conn instanceof HttpContext) {
|
||||
((HttpContext) conn).setAttribute(id, obj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
262
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/AbstractPoolEntry.java
vendored
Normal file
262
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/AbstractPoolEntry.java
vendored
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.RouteTracker;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* A pool entry for use by connection manager implementations.
|
||||
* Pool entries work in conjunction with an
|
||||
* {@link AbstractClientConnAdapter adapter}.
|
||||
* The adapter is handed out to applications that obtain a connection.
|
||||
* The pool entry stores the underlying connection and tracks the
|
||||
* {@link HttpRoute route} established.
|
||||
* The adapter delegates methods for establishing the route to
|
||||
* its pool entry.
|
||||
* <p>
|
||||
* If the managed connections is released or revoked, the adapter
|
||||
* gets disconnected, but the pool entry still contains the
|
||||
* underlying connection and the established route.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) do not use
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractPoolEntry {
|
||||
|
||||
/** The connection operator. */
|
||||
protected final ClientConnectionOperator connOperator;
|
||||
|
||||
/** The underlying connection being pooled or used. */
|
||||
protected final OperatedClientConnection connection;
|
||||
|
||||
/** The route for which this entry gets allocated. */
|
||||
//@@@ currently accessed from connection manager(s) as attribute
|
||||
//@@@ avoid that, derived classes should decide whether update is allowed
|
||||
//@@@ SCCM: yes, TSCCM: no
|
||||
protected volatile HttpRoute route;
|
||||
|
||||
/** Connection state object */
|
||||
protected volatile Object state;
|
||||
|
||||
/** The tracked route, or <code>null</code> before tracking starts. */
|
||||
protected volatile RouteTracker tracker;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new pool entry.
|
||||
*
|
||||
* @param connOperator the Connection Operator for this entry
|
||||
* @param route the planned route for the connection,
|
||||
* or <code>null</code>
|
||||
*/
|
||||
protected AbstractPoolEntry(final ClientConnectionOperator connOperator,
|
||||
final HttpRoute route) {
|
||||
super();
|
||||
Args.notNull(connOperator, "Connection operator");
|
||||
this.connOperator = connOperator;
|
||||
this.connection = connOperator.createConnection();
|
||||
this.route = route;
|
||||
this.tracker = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state object associated with this pool entry.
|
||||
*
|
||||
* @return The state object
|
||||
*/
|
||||
public Object getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a state object to this pool entry.
|
||||
*
|
||||
* @param state The state object
|
||||
*/
|
||||
public void setState(final Object state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the underlying connection.
|
||||
*
|
||||
* @param route the route along which to open the connection
|
||||
* @param context the context for opening the connection
|
||||
* @param params the parameters for opening the connection
|
||||
*
|
||||
* @throws IOException in case of a problem
|
||||
*/
|
||||
public void open(final HttpRoute route,
|
||||
final HttpContext context, final HttpParams params)
|
||||
throws IOException {
|
||||
|
||||
Args.notNull(route, "Route");
|
||||
Args.notNull(params, "HTTP parameters");
|
||||
if (this.tracker != null) {
|
||||
Asserts.check(!this.tracker.isConnected(), "Connection already open");
|
||||
}
|
||||
// - collect the arguments
|
||||
// - call the operator
|
||||
// - update the tracking data
|
||||
// In this order, we can be sure that only a successful
|
||||
// opening of the connection will be tracked.
|
||||
|
||||
this.tracker = new RouteTracker(route);
|
||||
final HttpHost proxy = route.getProxyHost();
|
||||
|
||||
connOperator.openConnection
|
||||
(this.connection,
|
||||
(proxy != null) ? proxy : route.getTargetHost(),
|
||||
route.getLocalAddress(),
|
||||
context, params);
|
||||
|
||||
final RouteTracker localTracker = tracker; // capture volatile
|
||||
|
||||
// If this tracker was reset while connecting,
|
||||
// fail early.
|
||||
if (localTracker == null) {
|
||||
throw new InterruptedIOException("Request aborted");
|
||||
}
|
||||
|
||||
if (proxy == null) {
|
||||
localTracker.connectTarget(this.connection.isSecure());
|
||||
} else {
|
||||
localTracker.connectProxy(proxy, this.connection.isSecure());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks tunnelling of the connection to the target.
|
||||
* The tunnel has to be established outside by sending a CONNECT
|
||||
* request to the (last) proxy.
|
||||
*
|
||||
* @param secure <code>true</code> if the tunnel should be
|
||||
* considered secure, <code>false</code> otherwise
|
||||
* @param params the parameters for tunnelling the connection
|
||||
*
|
||||
* @throws IOException in case of a problem
|
||||
*/
|
||||
public void tunnelTarget(final boolean secure, final HttpParams params)
|
||||
throws IOException {
|
||||
|
||||
Args.notNull(params, "HTTP parameters");
|
||||
Asserts.notNull(this.tracker, "Route tracker");
|
||||
Asserts.check(this.tracker.isConnected(), "Connection not open");
|
||||
Asserts.check(!this.tracker.isTunnelled(), "Connection is already tunnelled");
|
||||
|
||||
this.connection.update(null, tracker.getTargetHost(),
|
||||
secure, params);
|
||||
this.tracker.tunnelTarget(secure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks tunnelling of the connection to a chained proxy.
|
||||
* The tunnel has to be established outside by sending a CONNECT
|
||||
* request to the previous proxy.
|
||||
*
|
||||
* @param next the proxy to which the tunnel was established.
|
||||
* See {@link ch.boye.httpclientandroidlib.conn.ManagedClientConnection#tunnelProxy
|
||||
* ManagedClientConnection.tunnelProxy}
|
||||
* for details.
|
||||
* @param secure <code>true</code> if the tunnel should be
|
||||
* considered secure, <code>false</code> otherwise
|
||||
* @param params the parameters for tunnelling the connection
|
||||
*
|
||||
* @throws IOException in case of a problem
|
||||
*/
|
||||
public void tunnelProxy(final HttpHost next, final boolean secure, final HttpParams params)
|
||||
throws IOException {
|
||||
|
||||
Args.notNull(next, "Next proxy");
|
||||
Args.notNull(params, "Parameters");
|
||||
|
||||
Asserts.notNull(this.tracker, "Route tracker");
|
||||
Asserts.check(this.tracker.isConnected(), "Connection not open");
|
||||
|
||||
this.connection.update(null, next, secure, params);
|
||||
this.tracker.tunnelProxy(next, secure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Layers a protocol on top of an established tunnel.
|
||||
*
|
||||
* @param context the context for layering
|
||||
* @param params the parameters for layering
|
||||
*
|
||||
* @throws IOException in case of a problem
|
||||
*/
|
||||
public void layerProtocol(final HttpContext context, final HttpParams params)
|
||||
throws IOException {
|
||||
|
||||
//@@@ is context allowed to be null? depends on operator?
|
||||
Args.notNull(params, "HTTP parameters");
|
||||
Asserts.notNull(this.tracker, "Route tracker");
|
||||
Asserts.check(this.tracker.isConnected(), "Connection not open");
|
||||
Asserts.check(this.tracker.isTunnelled(), "Protocol layering without a tunnel not supported");
|
||||
Asserts.check(!this.tracker.isLayered(), "Multiple protocol layering not supported");
|
||||
// - collect the arguments
|
||||
// - call the operator
|
||||
// - update the tracking data
|
||||
// In this order, we can be sure that only a successful
|
||||
// layering on top of the connection will be tracked.
|
||||
|
||||
final HttpHost target = tracker.getTargetHost();
|
||||
|
||||
connOperator.updateSecureConnection(this.connection, target,
|
||||
context, params);
|
||||
|
||||
this.tracker.layerProtocol(this.connection.isSecure());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the entry.
|
||||
*
|
||||
* If {@link #open(HttpRoute, HttpContext, HttpParams)} is in progress,
|
||||
* this will cause that open to possibly throw an {@link IOException}.
|
||||
*/
|
||||
protected void shutdownEntry() {
|
||||
tracker = null;
|
||||
state = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
191
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/AbstractPooledConnAdapter.java
vendored
Normal file
191
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/AbstractPooledConnAdapter.java
vendored
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
* Abstract adapter from pool {@link AbstractPoolEntry entries} to
|
||||
* {@link ch.boye.httpclientandroidlib.conn.ManagedClientConnection managed}
|
||||
* client connections.
|
||||
* The connection in the pool entry is used to initialize the base class.
|
||||
* In addition, methods to establish a route are delegated to the
|
||||
* pool entry. {@link #shutdown shutdown} and {@link #close close}
|
||||
* will clear the tracked route in the pool entry and call the
|
||||
* respective method of the wrapped connection.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) do not use
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractPooledConnAdapter extends AbstractClientConnAdapter {
|
||||
|
||||
/** The wrapped pool entry. */
|
||||
protected volatile AbstractPoolEntry poolEntry;
|
||||
|
||||
/**
|
||||
* Creates a new connection adapter.
|
||||
*
|
||||
* @param manager the connection manager
|
||||
* @param entry the pool entry for the connection being wrapped
|
||||
*/
|
||||
protected AbstractPooledConnAdapter(final ClientConnectionManager manager,
|
||||
final AbstractPoolEntry entry) {
|
||||
super(manager, entry.connection);
|
||||
this.poolEntry = entry;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the pool entry.
|
||||
*
|
||||
* @return the pool entry, or <code>null</code> if detached
|
||||
*
|
||||
* @deprecated (4.0.1)
|
||||
*/
|
||||
@Deprecated
|
||||
protected AbstractPoolEntry getPoolEntry() {
|
||||
return this.poolEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that there is a valid pool entry.
|
||||
*
|
||||
* @throws ConnectionShutdownException if there is no pool entry
|
||||
* or connection has been aborted
|
||||
*
|
||||
* @see #assertValid(OperatedClientConnection)
|
||||
*/
|
||||
protected void assertValid(final AbstractPoolEntry entry) {
|
||||
if (isReleased() || entry == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated (4.1) use {@link #assertValid(AbstractPoolEntry)}
|
||||
*/
|
||||
@Deprecated
|
||||
protected final void assertAttached() {
|
||||
if (poolEntry == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches this adapter from the wrapped connection.
|
||||
* This adapter becomes useless.
|
||||
*/
|
||||
@Override
|
||||
protected synchronized void detach() {
|
||||
poolEntry = null;
|
||||
super.detach();
|
||||
}
|
||||
|
||||
public HttpRoute getRoute() {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
assertValid(entry);
|
||||
return (entry.tracker == null) ? null : entry.tracker.toRoute();
|
||||
}
|
||||
|
||||
public void open(final HttpRoute route,
|
||||
final HttpContext context, final HttpParams params)
|
||||
throws IOException {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
assertValid(entry);
|
||||
entry.open(route, context, params);
|
||||
}
|
||||
|
||||
public void tunnelTarget(final boolean secure, final HttpParams params)
|
||||
throws IOException {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
assertValid(entry);
|
||||
entry.tunnelTarget(secure, params);
|
||||
}
|
||||
|
||||
public void tunnelProxy(final HttpHost next, final boolean secure, final HttpParams params)
|
||||
throws IOException {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
assertValid(entry);
|
||||
entry.tunnelProxy(next, secure, params);
|
||||
}
|
||||
|
||||
public void layerProtocol(final HttpContext context, final HttpParams params)
|
||||
throws IOException {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
assertValid(entry);
|
||||
entry.layerProtocol(context, params);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
if (entry != null) {
|
||||
entry.shutdownEntry();
|
||||
}
|
||||
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
if (conn != null) {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() throws IOException {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
if (entry != null) {
|
||||
entry.shutdownEntry();
|
||||
}
|
||||
|
||||
final OperatedClientConnection conn = getWrappedConnection();
|
||||
if (conn != null) {
|
||||
conn.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public Object getState() {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
assertValid(entry);
|
||||
return entry.getState();
|
||||
}
|
||||
|
||||
public void setState(final Object state) {
|
||||
final AbstractPoolEntry entry = getPoolEntry();
|
||||
assertValid(entry);
|
||||
entry.setState(state);
|
||||
}
|
||||
|
||||
}
|
||||
276
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/BasicClientConnectionManager.java
vendored
Normal file
276
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/BasicClientConnectionManager.java
vendored
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.annotation.GuardedBy;
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionRequest;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* A connection manager for a single connection. This connection manager maintains only one active
|
||||
* connection. Even though this class is fully thread-safe it ought to be used by one execution
|
||||
* thread only, as only one thread a time can lease the connection at a time.
|
||||
* <p/>
|
||||
* This connection manager will make an effort to reuse the connection for subsequent requests
|
||||
* with the same {@link HttpRoute route}. It will, however, close the existing connection and
|
||||
* open it for the given route, if the route of the persistent connection does not match that
|
||||
* of the connection request. If the connection has been already been allocated
|
||||
* {@link IllegalStateException} is thrown.
|
||||
* <p/>
|
||||
* This connection manager implementation should be used inside an EJB container instead of
|
||||
* {@link PoolingClientConnectionManager}.
|
||||
*
|
||||
* @since 4.2
|
||||
*
|
||||
* @deprecated (4.3) use {@link BasicHttpClientConnectionManager}.
|
||||
*/
|
||||
@ThreadSafe
|
||||
@Deprecated
|
||||
public class BasicClientConnectionManager implements ClientConnectionManager {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
private static final AtomicLong COUNTER = new AtomicLong();
|
||||
|
||||
/** The message to be logged on multiple allocation. */
|
||||
public final static String MISUSE_MESSAGE =
|
||||
"Invalid use of BasicClientConnManager: connection still allocated.\n" +
|
||||
"Make sure to release the connection before allocating another one.";
|
||||
|
||||
/** The schemes supported by this connection manager. */
|
||||
private final SchemeRegistry schemeRegistry;
|
||||
|
||||
/** The operator for opening and updating connections. */
|
||||
private final ClientConnectionOperator connOperator;
|
||||
|
||||
/** The one and only entry in this pool. */
|
||||
@GuardedBy("this")
|
||||
private HttpPoolEntry poolEntry;
|
||||
|
||||
/** The currently issued managed connection, if any. */
|
||||
@GuardedBy("this")
|
||||
private ManagedClientConnectionImpl conn;
|
||||
|
||||
/** Indicates whether this connection manager is shut down. */
|
||||
@GuardedBy("this")
|
||||
private volatile boolean shutdown;
|
||||
|
||||
/**
|
||||
* Creates a new simple connection manager.
|
||||
*
|
||||
* @param schreg the scheme registry
|
||||
*/
|
||||
public BasicClientConnectionManager(final SchemeRegistry schreg) {
|
||||
Args.notNull(schreg, "Scheme registry");
|
||||
this.schemeRegistry = schreg;
|
||||
this.connOperator = createConnectionOperator(schreg);
|
||||
}
|
||||
|
||||
public BasicClientConnectionManager() {
|
||||
this(SchemeRegistryFactory.createDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
shutdown();
|
||||
} finally { // Make sure we call overridden method even if shutdown barfs
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
public SchemeRegistry getSchemeRegistry() {
|
||||
return this.schemeRegistry;
|
||||
}
|
||||
|
||||
protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry schreg) {
|
||||
return new DefaultClientConnectionOperator(schreg);
|
||||
}
|
||||
|
||||
public final ClientConnectionRequest requestConnection(
|
||||
final HttpRoute route,
|
||||
final Object state) {
|
||||
|
||||
return new ClientConnectionRequest() {
|
||||
|
||||
public void abortRequest() {
|
||||
// Nothing to abort, since requests are immediate.
|
||||
}
|
||||
|
||||
public ManagedClientConnection getConnection(
|
||||
final long timeout, final TimeUnit tunit) {
|
||||
return BasicClientConnectionManager.this.getConnection(
|
||||
route, state);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private void assertNotShutdown() {
|
||||
Asserts.check(!this.shutdown, "Connection manager has been shut down");
|
||||
}
|
||||
|
||||
ManagedClientConnection getConnection(final HttpRoute route, final Object state) {
|
||||
Args.notNull(route, "Route");
|
||||
synchronized (this) {
|
||||
assertNotShutdown();
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Get connection for route " + route);
|
||||
}
|
||||
Asserts.check(this.conn == null, MISUSE_MESSAGE);
|
||||
if (this.poolEntry != null && !this.poolEntry.getPlannedRoute().equals(route)) {
|
||||
this.poolEntry.close();
|
||||
this.poolEntry = null;
|
||||
}
|
||||
if (this.poolEntry == null) {
|
||||
final String id = Long.toString(COUNTER.getAndIncrement());
|
||||
final OperatedClientConnection conn = this.connOperator.createConnection();
|
||||
this.poolEntry = new HttpPoolEntry(this.log, id, route, conn, 0, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
final long now = System.currentTimeMillis();
|
||||
if (this.poolEntry.isExpired(now)) {
|
||||
this.poolEntry.close();
|
||||
this.poolEntry.getTracker().reset();
|
||||
}
|
||||
this.conn = new ManagedClientConnectionImpl(this, this.connOperator, this.poolEntry);
|
||||
return this.conn;
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdownConnection(final HttpClientConnection conn) {
|
||||
try {
|
||||
conn.shutdown();
|
||||
} catch (final IOException iox) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("I/O exception shutting down connection", iox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseConnection(final ManagedClientConnection conn, final long keepalive, final TimeUnit tunit) {
|
||||
Args.check(conn instanceof ManagedClientConnectionImpl, "Connection class mismatch, " +
|
||||
"connection not obtained from this manager");
|
||||
final ManagedClientConnectionImpl managedConn = (ManagedClientConnectionImpl) conn;
|
||||
synchronized (managedConn) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Releasing connection " + conn);
|
||||
}
|
||||
if (managedConn.getPoolEntry() == null) {
|
||||
return; // already released
|
||||
}
|
||||
final ClientConnectionManager manager = managedConn.getManager();
|
||||
Asserts.check(manager == this, "Connection not obtained from this manager");
|
||||
synchronized (this) {
|
||||
if (this.shutdown) {
|
||||
shutdownConnection(managedConn);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (managedConn.isOpen() && !managedConn.isMarkedReusable()) {
|
||||
shutdownConnection(managedConn);
|
||||
}
|
||||
if (managedConn.isMarkedReusable()) {
|
||||
this.poolEntry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS);
|
||||
if (this.log.isDebugEnabled()) {
|
||||
final String s;
|
||||
if (keepalive > 0) {
|
||||
s = "for " + keepalive + " " + tunit;
|
||||
} else {
|
||||
s = "indefinitely";
|
||||
}
|
||||
this.log.debug("Connection can be kept alive " + s);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
managedConn.detach();
|
||||
this.conn = null;
|
||||
if (this.poolEntry.isClosed()) {
|
||||
this.poolEntry = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeExpiredConnections() {
|
||||
synchronized (this) {
|
||||
assertNotShutdown();
|
||||
final long now = System.currentTimeMillis();
|
||||
if (this.poolEntry != null && this.poolEntry.isExpired(now)) {
|
||||
this.poolEntry.close();
|
||||
this.poolEntry.getTracker().reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeIdleConnections(final long idletime, final TimeUnit tunit) {
|
||||
Args.notNull(tunit, "Time unit");
|
||||
synchronized (this) {
|
||||
assertNotShutdown();
|
||||
long time = tunit.toMillis(idletime);
|
||||
if (time < 0) {
|
||||
time = 0;
|
||||
}
|
||||
final long deadline = System.currentTimeMillis() - time;
|
||||
if (this.poolEntry != null && this.poolEntry.getUpdated() <= deadline) {
|
||||
this.poolEntry.close();
|
||||
this.poolEntry.getTracker().reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
synchronized (this) {
|
||||
this.shutdown = true;
|
||||
try {
|
||||
if (this.poolEntry != null) {
|
||||
this.poolEntry.close();
|
||||
}
|
||||
} finally {
|
||||
this.poolEntry = null;
|
||||
this.conn = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.annotation.GuardedBy;
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.config.ConnectionConfig;
|
||||
import ch.boye.httpclientandroidlib.config.Lookup;
|
||||
import ch.boye.httpclientandroidlib.config.Registry;
|
||||
import ch.boye.httpclientandroidlib.config.RegistryBuilder;
|
||||
import ch.boye.httpclientandroidlib.config.SocketConfig;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectionRequest;
|
||||
import ch.boye.httpclientandroidlib.conn.DnsResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.HttpClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.HttpConnectionFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.SchemePortResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.socket.ConnectionSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.socket.PlainConnectionSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.ssl.SSLConnectionSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
import ch.boye.httpclientandroidlib.util.LangUtils;
|
||||
|
||||
/**
|
||||
* A connection manager for a single connection. This connection manager maintains only one active
|
||||
* connection. Even though this class is fully thread-safe it ought to be used by one execution
|
||||
* thread only, as only one thread a time can lease the connection at a time.
|
||||
* <p/>
|
||||
* This connection manager will make an effort to reuse the connection for subsequent requests
|
||||
* with the same {@link HttpRoute route}. It will, however, close the existing connection and
|
||||
* open it for the given route, if the route of the persistent connection does not match that
|
||||
* of the connection request. If the connection has been already been allocated
|
||||
* {@link IllegalStateException} is thrown.
|
||||
* <p/>
|
||||
* This connection manager implementation should be used inside an EJB container instead of
|
||||
* {@link PoolingHttpClientConnectionManager}.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class BasicHttpClientConnectionManager implements HttpClientConnectionManager, Closeable {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
private final HttpClientConnectionOperator connectionOperator;
|
||||
private final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory;
|
||||
|
||||
@GuardedBy("this")
|
||||
private ManagedHttpClientConnection conn;
|
||||
|
||||
@GuardedBy("this")
|
||||
private HttpRoute route;
|
||||
|
||||
@GuardedBy("this")
|
||||
private Object state;
|
||||
|
||||
@GuardedBy("this")
|
||||
private long updated;
|
||||
|
||||
@GuardedBy("this")
|
||||
private long expiry;
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean leased;
|
||||
|
||||
@GuardedBy("this")
|
||||
private SocketConfig socketConfig;
|
||||
|
||||
@GuardedBy("this")
|
||||
private ConnectionConfig connConfig;
|
||||
|
||||
private final AtomicBoolean isShutdown;
|
||||
|
||||
private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
|
||||
return RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
||||
.register("https", SSLConnectionSocketFactory.getSocketFactory())
|
||||
.build();
|
||||
}
|
||||
|
||||
public BasicHttpClientConnectionManager(
|
||||
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver) {
|
||||
super();
|
||||
this.connectionOperator = new HttpClientConnectionOperator(
|
||||
socketFactoryRegistry, schemePortResolver, dnsResolver);
|
||||
this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE;
|
||||
this.expiry = Long.MAX_VALUE;
|
||||
this.socketConfig = SocketConfig.DEFAULT;
|
||||
this.connConfig = ConnectionConfig.DEFAULT;
|
||||
this.isShutdown = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
public BasicHttpClientConnectionManager(
|
||||
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory) {
|
||||
this(socketFactoryRegistry, connFactory, null, null);
|
||||
}
|
||||
|
||||
public BasicHttpClientConnectionManager(
|
||||
final Lookup<ConnectionSocketFactory> socketFactoryRegistry) {
|
||||
this(socketFactoryRegistry, null, null, null);
|
||||
}
|
||||
|
||||
public BasicHttpClientConnectionManager() {
|
||||
this(getDefaultRegistry(), null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
shutdown();
|
||||
} finally { // Make sure we call overridden method even if shutdown barfs
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
HttpRoute getRoute() {
|
||||
return route;
|
||||
}
|
||||
|
||||
Object getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public synchronized SocketConfig getSocketConfig() {
|
||||
return socketConfig;
|
||||
}
|
||||
|
||||
public synchronized void setSocketConfig(final SocketConfig socketConfig) {
|
||||
this.socketConfig = socketConfig != null ? socketConfig : SocketConfig.DEFAULT;
|
||||
}
|
||||
|
||||
public synchronized ConnectionConfig getConnectionConfig() {
|
||||
return connConfig;
|
||||
}
|
||||
|
||||
public synchronized void setConnectionConfig(final ConnectionConfig connConfig) {
|
||||
this.connConfig = connConfig != null ? connConfig : ConnectionConfig.DEFAULT;
|
||||
}
|
||||
|
||||
public final ConnectionRequest requestConnection(
|
||||
final HttpRoute route,
|
||||
final Object state) {
|
||||
Args.notNull(route, "Route");
|
||||
return new ConnectionRequest() {
|
||||
|
||||
public boolean cancel() {
|
||||
// Nothing to abort, since requests are immediate.
|
||||
return false;
|
||||
}
|
||||
|
||||
public HttpClientConnection get(final long timeout, final TimeUnit tunit) {
|
||||
return BasicHttpClientConnectionManager.this.getConnection(
|
||||
route, state);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private void closeConnection() {
|
||||
if (this.conn != null) {
|
||||
this.log.debug("Closing connection");
|
||||
try {
|
||||
this.conn.close();
|
||||
} catch (final IOException iox) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("I/O exception closing connection", iox);
|
||||
}
|
||||
}
|
||||
this.conn = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdownConnection() {
|
||||
if (this.conn != null) {
|
||||
this.log.debug("Shutting down connection");
|
||||
try {
|
||||
this.conn.shutdown();
|
||||
} catch (final IOException iox) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("I/O exception shutting down connection", iox);
|
||||
}
|
||||
}
|
||||
this.conn = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkExpiry() {
|
||||
if (this.conn != null && System.currentTimeMillis() >= this.expiry) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection expired @ " + new Date(this.expiry));
|
||||
}
|
||||
closeConnection();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized HttpClientConnection getConnection(final HttpRoute route, final Object state) {
|
||||
Asserts.check(!this.isShutdown.get(), "Connection manager has been shut down");
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Get connection for route " + route);
|
||||
}
|
||||
Asserts.check(!this.leased, "Connection is still allocated");
|
||||
if (!LangUtils.equals(this.route, route) || !LangUtils.equals(this.state, state)) {
|
||||
closeConnection();
|
||||
}
|
||||
this.route = route;
|
||||
this.state = state;
|
||||
checkExpiry();
|
||||
if (this.conn == null) {
|
||||
this.conn = this.connFactory.create(route, this.connConfig);
|
||||
}
|
||||
this.leased = true;
|
||||
return this.conn;
|
||||
}
|
||||
|
||||
public synchronized void releaseConnection(
|
||||
final HttpClientConnection conn,
|
||||
final Object state,
|
||||
final long keepalive, final TimeUnit tunit) {
|
||||
Args.notNull(conn, "Connection");
|
||||
Asserts.check(conn == this.conn, "Connection not obtained from this manager");
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Releasing connection " + conn);
|
||||
}
|
||||
if (this.isShutdown.get()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.updated = System.currentTimeMillis();
|
||||
if (!this.conn.isOpen()) {
|
||||
this.conn = null;
|
||||
this.route = null;
|
||||
this.conn = null;
|
||||
this.expiry = Long.MAX_VALUE;
|
||||
} else {
|
||||
this.state = state;
|
||||
if (this.log.isDebugEnabled()) {
|
||||
final String s;
|
||||
if (keepalive > 0) {
|
||||
s = "for " + keepalive + " " + tunit;
|
||||
} else {
|
||||
s = "indefinitely";
|
||||
}
|
||||
this.log.debug("Connection can be kept alive " + s);
|
||||
}
|
||||
if (keepalive > 0) {
|
||||
this.expiry = this.updated + tunit.toMillis(keepalive);
|
||||
} else {
|
||||
this.expiry = Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.leased = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void connect(
|
||||
final HttpClientConnection conn,
|
||||
final HttpRoute route,
|
||||
final int connectTimeout,
|
||||
final HttpContext context) throws IOException {
|
||||
Args.notNull(conn, "Connection");
|
||||
Args.notNull(route, "HTTP route");
|
||||
Asserts.check(conn == this.conn, "Connection not obtained from this manager");
|
||||
final HttpHost host;
|
||||
if (route.getProxyHost() != null) {
|
||||
host = route.getProxyHost();
|
||||
} else {
|
||||
host = route.getTargetHost();
|
||||
}
|
||||
final InetSocketAddress localAddress = route.getLocalSocketAddress();
|
||||
this.connectionOperator.connect(this.conn, host, localAddress,
|
||||
connectTimeout, this.socketConfig, context);
|
||||
}
|
||||
|
||||
public void upgrade(
|
||||
final HttpClientConnection conn,
|
||||
final HttpRoute route,
|
||||
final HttpContext context) throws IOException {
|
||||
Args.notNull(conn, "Connection");
|
||||
Args.notNull(route, "HTTP route");
|
||||
Asserts.check(conn == this.conn, "Connection not obtained from this manager");
|
||||
this.connectionOperator.upgrade(this.conn, route.getTargetHost(), context);
|
||||
}
|
||||
|
||||
public void routeComplete(
|
||||
final HttpClientConnection conn,
|
||||
final HttpRoute route,
|
||||
final HttpContext context) throws IOException {
|
||||
}
|
||||
|
||||
public synchronized void closeExpiredConnections() {
|
||||
if (this.isShutdown.get()) {
|
||||
return;
|
||||
}
|
||||
if (!this.leased) {
|
||||
checkExpiry();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void closeIdleConnections(final long idletime, final TimeUnit tunit) {
|
||||
Args.notNull(tunit, "Time unit");
|
||||
if (this.isShutdown.get()) {
|
||||
return;
|
||||
}
|
||||
if (!this.leased) {
|
||||
long time = tunit.toMillis(idletime);
|
||||
if (time < 0) {
|
||||
time = 0;
|
||||
}
|
||||
final long deadline = System.currentTimeMillis() - time;
|
||||
if (this.updated <= deadline) {
|
||||
closeConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void shutdown() {
|
||||
if (this.isShutdown.compareAndSet(false, true)) {
|
||||
shutdownConnection();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
67
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/CPool.java
vendored
Normal file
67
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/CPool.java
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.pool.AbstractConnPool;
|
||||
import ch.boye.httpclientandroidlib.pool.ConnFactory;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
@ThreadSafe
|
||||
class CPool extends AbstractConnPool<HttpRoute, ManagedHttpClientConnection, CPoolEntry> {
|
||||
|
||||
private static final AtomicLong COUNTER = new AtomicLong();
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(CPool.class);
|
||||
private final long timeToLive;
|
||||
private final TimeUnit tunit;
|
||||
|
||||
public CPool(
|
||||
final ConnFactory<HttpRoute, ManagedHttpClientConnection> connFactory,
|
||||
final int defaultMaxPerRoute, final int maxTotal,
|
||||
final long timeToLive, final TimeUnit tunit) {
|
||||
super(connFactory, defaultMaxPerRoute, maxTotal);
|
||||
this.timeToLive = timeToLive;
|
||||
this.tunit = tunit;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CPoolEntry createEntry(final HttpRoute route, final ManagedHttpClientConnection conn) {
|
||||
final String id = Long.toString(COUNTER.getAndIncrement());
|
||||
return new CPoolEntry(this.log, id, route, conn, this.timeToLive, this.tunit);
|
||||
}
|
||||
|
||||
}
|
||||
101
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/CPoolEntry.java
vendored
Normal file
101
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/CPoolEntry.java
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
import ch.boye.httpclientandroidlib.HttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.pool.PoolEntry;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
@ThreadSafe
|
||||
class CPoolEntry extends PoolEntry<HttpRoute, ManagedHttpClientConnection> {
|
||||
|
||||
public HttpClientAndroidLog log;
|
||||
private volatile boolean routeComplete;
|
||||
|
||||
public CPoolEntry(
|
||||
final HttpClientAndroidLog log,
|
||||
final String id,
|
||||
final HttpRoute route,
|
||||
final ManagedHttpClientConnection conn,
|
||||
final long timeToLive, final TimeUnit tunit) {
|
||||
super(id, route, conn, timeToLive, tunit);
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public void markRouteComplete() {
|
||||
this.routeComplete = true;
|
||||
}
|
||||
|
||||
public boolean isRouteComplete() {
|
||||
return this.routeComplete;
|
||||
}
|
||||
|
||||
public void closeConnection() throws IOException {
|
||||
final HttpClientConnection conn = getConnection();
|
||||
conn.close();
|
||||
}
|
||||
|
||||
public void shutdownConnection() throws IOException {
|
||||
final HttpClientConnection conn = getConnection();
|
||||
conn.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired(final long now) {
|
||||
final boolean expired = super.isExpired(now);
|
||||
if (expired && this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection " + this + " expired @ " + new Date(getExpiry()));
|
||||
}
|
||||
return expired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
final HttpClientConnection conn = getConnection();
|
||||
return !conn.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
closeConnection();
|
||||
} catch (final IOException ex) {
|
||||
this.log.debug("I/O error closing connection", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
245
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/CPoolProxy.java
vendored
Normal file
245
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/CPoolProxy.java
vendored
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.HttpConnectionMetrics;
|
||||
import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
@NotThreadSafe
|
||||
class CPoolProxy implements ManagedHttpClientConnection, HttpContext {
|
||||
|
||||
private volatile CPoolEntry poolEntry;
|
||||
|
||||
CPoolProxy(final CPoolEntry entry) {
|
||||
super();
|
||||
this.poolEntry = entry;
|
||||
}
|
||||
|
||||
CPoolEntry getPoolEntry() {
|
||||
return this.poolEntry;
|
||||
}
|
||||
|
||||
CPoolEntry detach() {
|
||||
final CPoolEntry local = this.poolEntry;
|
||||
this.poolEntry = null;
|
||||
return local;
|
||||
}
|
||||
|
||||
ManagedHttpClientConnection getConnection() {
|
||||
final CPoolEntry local = this.poolEntry;
|
||||
if (local == null) {
|
||||
return null;
|
||||
}
|
||||
return local.getConnection();
|
||||
}
|
||||
|
||||
ManagedHttpClientConnection getValidConnection() {
|
||||
final ManagedHttpClientConnection conn = getConnection();
|
||||
if (conn == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
final CPoolEntry local = this.poolEntry;
|
||||
if (local != null) {
|
||||
local.closeConnection();
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() throws IOException {
|
||||
final CPoolEntry local = this.poolEntry;
|
||||
if (local != null) {
|
||||
local.shutdownConnection();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
final CPoolEntry local = this.poolEntry;
|
||||
if (local != null) {
|
||||
return !local.isClosed();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStale() {
|
||||
final HttpClientConnection conn = getConnection();
|
||||
if (conn != null) {
|
||||
return conn.isStale();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSocketTimeout(final int timeout) {
|
||||
getValidConnection().setSocketTimeout(timeout);
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
return getValidConnection().getSocketTimeout();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return getValidConnection().getId();
|
||||
}
|
||||
|
||||
public void bind(final Socket socket) throws IOException {
|
||||
getValidConnection().bind(socket);
|
||||
}
|
||||
|
||||
public Socket getSocket() {
|
||||
return getValidConnection().getSocket();
|
||||
}
|
||||
|
||||
public SSLSession getSSLSession() {
|
||||
return getValidConnection().getSSLSession();
|
||||
}
|
||||
|
||||
public boolean isResponseAvailable(final int timeout) throws IOException {
|
||||
return getValidConnection().isResponseAvailable(timeout);
|
||||
}
|
||||
|
||||
public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException {
|
||||
getValidConnection().sendRequestHeader(request);
|
||||
}
|
||||
|
||||
public void sendRequestEntity(final HttpEntityEnclosingRequest request) throws HttpException, IOException {
|
||||
getValidConnection().sendRequestEntity(request);
|
||||
}
|
||||
|
||||
public HttpResponse receiveResponseHeader() throws HttpException, IOException {
|
||||
return getValidConnection().receiveResponseHeader();
|
||||
}
|
||||
|
||||
public void receiveResponseEntity(final HttpResponse response) throws HttpException, IOException {
|
||||
getValidConnection().receiveResponseEntity(response);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
getValidConnection().flush();
|
||||
}
|
||||
|
||||
public HttpConnectionMetrics getMetrics() {
|
||||
return getValidConnection().getMetrics();
|
||||
}
|
||||
|
||||
public InetAddress getLocalAddress() {
|
||||
return getValidConnection().getLocalAddress();
|
||||
}
|
||||
|
||||
public int getLocalPort() {
|
||||
return getValidConnection().getLocalPort();
|
||||
}
|
||||
|
||||
public InetAddress getRemoteAddress() {
|
||||
return getValidConnection().getRemoteAddress();
|
||||
}
|
||||
|
||||
public int getRemotePort() {
|
||||
return getValidConnection().getRemotePort();
|
||||
}
|
||||
|
||||
public Object getAttribute(final String id) {
|
||||
final ManagedHttpClientConnection conn = getValidConnection();
|
||||
if (conn instanceof HttpContext) {
|
||||
return ((HttpContext) conn).getAttribute(id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAttribute(final String id, final Object obj) {
|
||||
final ManagedHttpClientConnection conn = getValidConnection();
|
||||
if (conn instanceof HttpContext) {
|
||||
((HttpContext) conn).setAttribute(id, obj);
|
||||
}
|
||||
}
|
||||
|
||||
public Object removeAttribute(final String id) {
|
||||
final ManagedHttpClientConnection conn = getValidConnection();
|
||||
if (conn instanceof HttpContext) {
|
||||
return ((HttpContext) conn).removeAttribute(id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("CPoolProxy{");
|
||||
final ManagedHttpClientConnection conn = getConnection();
|
||||
if (conn != null) {
|
||||
sb.append(conn);
|
||||
} else {
|
||||
sb.append("detached");
|
||||
}
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static HttpClientConnection newProxy(final CPoolEntry poolEntry) {
|
||||
return new CPoolProxy(poolEntry);
|
||||
}
|
||||
|
||||
private static CPoolProxy getProxy(final HttpClientConnection conn) {
|
||||
if (!CPoolProxy.class.isInstance(conn)) {
|
||||
throw new IllegalStateException("Unexpected connection proxy class: " + conn.getClass());
|
||||
}
|
||||
return CPoolProxy.class.cast(conn);
|
||||
}
|
||||
|
||||
public static CPoolEntry getPoolEntry(final HttpClientConnection proxy) {
|
||||
final CPoolEntry entry = getProxy(proxy).getPoolEntry();
|
||||
if (entry == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
public static CPoolEntry detach(final HttpClientConnection conn) {
|
||||
return getProxy(conn).detach();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
|
||||
/**
|
||||
* Signals that the connection has been shut down or released back to the
|
||||
* the connection pool
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
@Immutable
|
||||
public class ConnectionShutdownException extends IllegalStateException {
|
||||
|
||||
private static final long serialVersionUID = 5868657401162844497L;
|
||||
|
||||
/**
|
||||
* Creates a new ConnectionShutdownException with a <tt>null</tt> detail message.
|
||||
*/
|
||||
public ConnectionShutdownException() {
|
||||
super();
|
||||
}
|
||||
|
||||
}
|
||||
292
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultClientConnection.java
vendored
Normal file
292
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultClientConnection.java
vendored
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.Header;
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.HttpResponseFactory;
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.impl.SocketHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageParser;
|
||||
import ch.boye.httpclientandroidlib.io.SessionInputBuffer;
|
||||
import ch.boye.httpclientandroidlib.io.SessionOutputBuffer;
|
||||
import ch.boye.httpclientandroidlib.params.BasicHttpParams;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.params.HttpProtocolParams;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* Default implementation of an operated client connection.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.3) use {@link ManagedHttpClientConnectionFactory}.
|
||||
*/
|
||||
@NotThreadSafe // connSecure, targetHost
|
||||
@Deprecated
|
||||
public class DefaultClientConnection extends SocketHttpClientConnection
|
||||
implements OperatedClientConnection, ManagedHttpClientConnection, HttpContext {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
public HttpClientAndroidLog headerLog = new HttpClientAndroidLog("ch.boye.httpclientandroidlib.headers");
|
||||
public HttpClientAndroidLog wireLog = new HttpClientAndroidLog("ch.boye.httpclientandroidlib.wire");
|
||||
|
||||
/** The unconnected socket */
|
||||
private volatile Socket socket;
|
||||
|
||||
/** The target host of this connection. */
|
||||
private HttpHost targetHost;
|
||||
|
||||
/** Whether this connection is secure. */
|
||||
private boolean connSecure;
|
||||
|
||||
/** True if this connection was shutdown. */
|
||||
private volatile boolean shutdown;
|
||||
|
||||
/** connection specific attributes */
|
||||
private final Map<String, Object> attributes;
|
||||
|
||||
public DefaultClientConnection() {
|
||||
super();
|
||||
this.attributes = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final HttpHost getTargetHost() {
|
||||
return this.targetHost;
|
||||
}
|
||||
|
||||
public final boolean isSecure() {
|
||||
return this.connSecure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Socket getSocket() {
|
||||
return this.socket;
|
||||
}
|
||||
|
||||
public SSLSession getSSLSession() {
|
||||
if (this.socket instanceof SSLSocket) {
|
||||
return ((SSLSocket) this.socket).getSession();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void opening(final Socket sock, final HttpHost target) throws IOException {
|
||||
assertNotOpen();
|
||||
this.socket = sock;
|
||||
this.targetHost = target;
|
||||
|
||||
// Check for shutdown after assigning socket, so that
|
||||
if (this.shutdown) {
|
||||
sock.close(); // allow this to throw...
|
||||
// ...but if it doesn't, explicitly throw one ourselves.
|
||||
throw new InterruptedIOException("Connection already shutdown");
|
||||
}
|
||||
}
|
||||
|
||||
public void openCompleted(final boolean secure, final HttpParams params) throws IOException {
|
||||
Args.notNull(params, "Parameters");
|
||||
assertNotOpen();
|
||||
this.connSecure = secure;
|
||||
bind(this.socket, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force-closes this connection.
|
||||
* If the connection is still in the process of being open (the method
|
||||
* {@link #opening opening} was already called but
|
||||
* {@link #openCompleted openCompleted} was not), the associated
|
||||
* socket that is being connected to a remote address will be closed.
|
||||
* That will interrupt a thread that is blocked on connecting
|
||||
* the socket.
|
||||
* If the connection is not yet open, this will prevent the connection
|
||||
* from being opened.
|
||||
*
|
||||
* @throws IOException in case of a problem
|
||||
*/
|
||||
@Override
|
||||
public void shutdown() throws IOException {
|
||||
shutdown = true;
|
||||
try {
|
||||
super.shutdown();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Connection " + this + " shut down");
|
||||
}
|
||||
final Socket sock = this.socket; // copy volatile attribute
|
||||
if (sock != null) {
|
||||
sock.close();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
log.debug("I/O error shutting down connection", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
super.close();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Connection " + this + " closed");
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
log.debug("I/O error closing connection", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SessionInputBuffer createSessionInputBuffer(
|
||||
final Socket socket,
|
||||
final int buffersize,
|
||||
final HttpParams params) throws IOException {
|
||||
SessionInputBuffer inbuffer = super.createSessionInputBuffer(
|
||||
socket,
|
||||
buffersize > 0 ? buffersize : 8192,
|
||||
params);
|
||||
if (wireLog.isDebugEnabled()) {
|
||||
inbuffer = new LoggingSessionInputBuffer(
|
||||
inbuffer,
|
||||
new Wire(wireLog),
|
||||
HttpProtocolParams.getHttpElementCharset(params));
|
||||
}
|
||||
return inbuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SessionOutputBuffer createSessionOutputBuffer(
|
||||
final Socket socket,
|
||||
final int buffersize,
|
||||
final HttpParams params) throws IOException {
|
||||
SessionOutputBuffer outbuffer = super.createSessionOutputBuffer(
|
||||
socket,
|
||||
buffersize > 0 ? buffersize : 8192,
|
||||
params);
|
||||
if (wireLog.isDebugEnabled()) {
|
||||
outbuffer = new LoggingSessionOutputBuffer(
|
||||
outbuffer,
|
||||
new Wire(wireLog),
|
||||
HttpProtocolParams.getHttpElementCharset(params));
|
||||
}
|
||||
return outbuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpMessageParser<HttpResponse> createResponseParser(
|
||||
final SessionInputBuffer buffer,
|
||||
final HttpResponseFactory responseFactory,
|
||||
final HttpParams params) {
|
||||
// override in derived class to specify a line parser
|
||||
return new DefaultHttpResponseParser
|
||||
(buffer, null, responseFactory, params);
|
||||
}
|
||||
|
||||
public void bind(final Socket socket) throws IOException {
|
||||
bind(socket, new BasicHttpParams());
|
||||
}
|
||||
|
||||
public void update(final Socket sock, final HttpHost target,
|
||||
final boolean secure, final HttpParams params)
|
||||
throws IOException {
|
||||
|
||||
assertOpen();
|
||||
Args.notNull(target, "Target host");
|
||||
Args.notNull(params, "Parameters");
|
||||
|
||||
if (sock != null) {
|
||||
this.socket = sock;
|
||||
bind(sock, params);
|
||||
}
|
||||
targetHost = target;
|
||||
connSecure = secure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse receiveResponseHeader() throws HttpException, IOException {
|
||||
final HttpResponse response = super.receiveResponseHeader();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Receiving response: " + response.getStatusLine());
|
||||
}
|
||||
if (headerLog.isDebugEnabled()) {
|
||||
headerLog.debug("<< " + response.getStatusLine().toString());
|
||||
final Header[] headers = response.getAllHeaders();
|
||||
for (final Header header : headers) {
|
||||
headerLog.debug("<< " + header.toString());
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Sending request: " + request.getRequestLine());
|
||||
}
|
||||
super.sendRequestHeader(request);
|
||||
if (headerLog.isDebugEnabled()) {
|
||||
headerLog.debug(">> " + request.getRequestLine().toString());
|
||||
final Header[] headers = request.getAllHeaders();
|
||||
for (final Header header : headers) {
|
||||
headerLog.debug(">> " + header.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object getAttribute(final String id) {
|
||||
return this.attributes.get(id);
|
||||
}
|
||||
|
||||
public Object removeAttribute(final String id) {
|
||||
return this.attributes.remove(id);
|
||||
}
|
||||
|
||||
public void setAttribute(final String id, final Object obj) {
|
||||
this.attributes.put(id, obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.client.protocol.ClientContext;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectTimeoutException;
|
||||
import ch.boye.httpclientandroidlib.conn.DnsResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.HttpInetSocketAddress;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.Scheme;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeLayeredSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.params.HttpConnectionParams;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link ClientConnectionOperator}. It uses a {@link SchemeRegistry}
|
||||
* to look up {@link SchemeSocketFactory} objects.
|
||||
* <p>
|
||||
* This connection operator is multihome network aware and will attempt to retry failed connects
|
||||
* against all known IP addresses sequentially until the connect is successful or all known
|
||||
* addresses fail to respond. Please note the same
|
||||
* {@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#CONNECTION_TIMEOUT} value will be used
|
||||
* for each connection attempt, so in the worst case the total elapsed time before timeout
|
||||
* can be <code>CONNECTION_TIMEOUT * n</code> where <code>n</code> is the number of IP addresses
|
||||
* of the given host. One can disable multihome support by overriding
|
||||
* the {@link #resolveHostname(String)} method and returning only one IP address for the given
|
||||
* host name.
|
||||
* <p>
|
||||
* The following parameters can be used to customize the behavior of this
|
||||
* class:
|
||||
* <ul>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#SO_TIMEOUT}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#SO_LINGER}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#SO_REUSEADDR}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#TCP_NODELAY}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#CONNECTION_TIMEOUT}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.3) use {@link PoolingHttpClientConnectionManager}.
|
||||
*/
|
||||
@Deprecated
|
||||
@ThreadSafe
|
||||
public class DefaultClientConnectionOperator implements ClientConnectionOperator {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
/** The scheme registry for looking up socket factories. */
|
||||
protected final SchemeRegistry schemeRegistry; // @ThreadSafe
|
||||
|
||||
/** the custom-configured DNS lookup mechanism. */
|
||||
protected final DnsResolver dnsResolver;
|
||||
|
||||
/**
|
||||
* Creates a new client connection operator for the given scheme registry.
|
||||
*
|
||||
* @param schemes the scheme registry
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public DefaultClientConnectionOperator(final SchemeRegistry schemes) {
|
||||
Args.notNull(schemes, "Scheme registry");
|
||||
this.schemeRegistry = schemes;
|
||||
this.dnsResolver = new SystemDefaultDnsResolver();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new client connection operator for the given scheme registry
|
||||
* and the given custom DNS lookup mechanism.
|
||||
*
|
||||
* @param schemes
|
||||
* the scheme registry
|
||||
* @param dnsResolver
|
||||
* the custom DNS lookup mechanism
|
||||
*/
|
||||
public DefaultClientConnectionOperator(final SchemeRegistry schemes,final DnsResolver dnsResolver) {
|
||||
Args.notNull(schemes, "Scheme registry");
|
||||
|
||||
Args.notNull(dnsResolver, "DNS resolver");
|
||||
|
||||
this.schemeRegistry = schemes;
|
||||
this.dnsResolver = dnsResolver;
|
||||
}
|
||||
|
||||
public OperatedClientConnection createConnection() {
|
||||
return new DefaultClientConnection();
|
||||
}
|
||||
|
||||
private SchemeRegistry getSchemeRegistry(final HttpContext context) {
|
||||
SchemeRegistry reg = (SchemeRegistry) context.getAttribute(
|
||||
ClientContext.SCHEME_REGISTRY);
|
||||
if (reg == null) {
|
||||
reg = this.schemeRegistry;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
public void openConnection(
|
||||
final OperatedClientConnection conn,
|
||||
final HttpHost target,
|
||||
final InetAddress local,
|
||||
final HttpContext context,
|
||||
final HttpParams params) throws IOException {
|
||||
Args.notNull(conn, "Connection");
|
||||
Args.notNull(target, "Target host");
|
||||
Args.notNull(params, "HTTP parameters");
|
||||
Asserts.check(!conn.isOpen(), "Connection must not be open");
|
||||
|
||||
final SchemeRegistry registry = getSchemeRegistry(context);
|
||||
final Scheme schm = registry.getScheme(target.getSchemeName());
|
||||
final SchemeSocketFactory sf = schm.getSchemeSocketFactory();
|
||||
|
||||
final InetAddress[] addresses = resolveHostname(target.getHostName());
|
||||
final int port = schm.resolvePort(target.getPort());
|
||||
for (int i = 0; i < addresses.length; i++) {
|
||||
final InetAddress address = addresses[i];
|
||||
final boolean last = i == addresses.length - 1;
|
||||
|
||||
Socket sock = sf.createSocket(params);
|
||||
conn.opening(sock, target);
|
||||
|
||||
final InetSocketAddress remoteAddress = new HttpInetSocketAddress(target, address, port);
|
||||
InetSocketAddress localAddress = null;
|
||||
if (local != null) {
|
||||
localAddress = new InetSocketAddress(local, 0);
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connecting to " + remoteAddress);
|
||||
}
|
||||
try {
|
||||
final Socket connsock = sf.connectSocket(sock, remoteAddress, localAddress, params);
|
||||
if (sock != connsock) {
|
||||
sock = connsock;
|
||||
conn.opening(sock, target);
|
||||
}
|
||||
prepareSocket(sock, context, params);
|
||||
conn.openCompleted(sf.isSecure(sock), params);
|
||||
return;
|
||||
} catch (final ConnectException ex) {
|
||||
if (last) {
|
||||
throw ex;
|
||||
}
|
||||
} catch (final ConnectTimeoutException ex) {
|
||||
if (last) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connect to " + remoteAddress + " timed out. " +
|
||||
"Connection will be retried using another IP address");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSecureConnection(
|
||||
final OperatedClientConnection conn,
|
||||
final HttpHost target,
|
||||
final HttpContext context,
|
||||
final HttpParams params) throws IOException {
|
||||
Args.notNull(conn, "Connection");
|
||||
Args.notNull(target, "Target host");
|
||||
Args.notNull(params, "Parameters");
|
||||
Asserts.check(conn.isOpen(), "Connection must be open");
|
||||
|
||||
final SchemeRegistry registry = getSchemeRegistry(context);
|
||||
final Scheme schm = registry.getScheme(target.getSchemeName());
|
||||
Asserts.check(schm.getSchemeSocketFactory() instanceof SchemeLayeredSocketFactory,
|
||||
"Socket factory must implement SchemeLayeredSocketFactory");
|
||||
final SchemeLayeredSocketFactory lsf = (SchemeLayeredSocketFactory) schm.getSchemeSocketFactory();
|
||||
final Socket sock = lsf.createLayeredSocket(
|
||||
conn.getSocket(), target.getHostName(), schm.resolvePort(target.getPort()), params);
|
||||
prepareSocket(sock, context, params);
|
||||
conn.update(sock, target, lsf.isSecure(sock), params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs standard initializations on a newly created socket.
|
||||
*
|
||||
* @param sock the socket to prepare
|
||||
* @param context the context for the connection
|
||||
* @param params the parameters from which to prepare the socket
|
||||
*
|
||||
* @throws IOException in case of an IO problem
|
||||
*/
|
||||
protected void prepareSocket(
|
||||
final Socket sock,
|
||||
final HttpContext context,
|
||||
final HttpParams params) throws IOException {
|
||||
sock.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params));
|
||||
sock.setSoTimeout(HttpConnectionParams.getSoTimeout(params));
|
||||
|
||||
final int linger = HttpConnectionParams.getLinger(params);
|
||||
if (linger >= 0) {
|
||||
sock.setSoLinger(linger > 0, linger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given host name to an array of corresponding IP addresses, based on the
|
||||
* configured name service on the provided DNS resolver. If one wasn't provided, the system
|
||||
* configuration is used.
|
||||
*
|
||||
* @param host host name to resolve
|
||||
* @return array of IP addresses
|
||||
* @exception UnknownHostException if no IP address for the host could be determined.
|
||||
*
|
||||
* @see DnsResolver
|
||||
* @see SystemDefaultDnsResolver
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
protected InetAddress[] resolveHostname(final String host) throws UnknownHostException {
|
||||
return dnsResolver.resolve(host);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
168
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultHttpResponseParser.java
vendored
Normal file
168
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultHttpResponseParser.java
vendored
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.HttpResponseFactory;
|
||||
import ch.boye.httpclientandroidlib.NoHttpResponseException;
|
||||
import ch.boye.httpclientandroidlib.ProtocolException;
|
||||
import ch.boye.httpclientandroidlib.StatusLine;
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.config.MessageConstraints;
|
||||
import ch.boye.httpclientandroidlib.impl.DefaultHttpResponseFactory;
|
||||
import ch.boye.httpclientandroidlib.impl.io.AbstractMessageParser;
|
||||
import ch.boye.httpclientandroidlib.io.SessionInputBuffer;
|
||||
import ch.boye.httpclientandroidlib.message.LineParser;
|
||||
import ch.boye.httpclientandroidlib.message.ParserCursor;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
|
||||
|
||||
/**
|
||||
* Lenient HTTP response parser implementation that can skip malformed data until
|
||||
* a valid HTTP response message head is encountered.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@NotThreadSafe
|
||||
public class DefaultHttpResponseParser extends AbstractMessageParser<HttpResponse> {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
private final HttpResponseFactory responseFactory;
|
||||
private final CharArrayBuffer lineBuf;
|
||||
|
||||
/**
|
||||
* @deprecated (4.3) use {@link DefaultHttpResponseParser#DefaultHttpResponseParser(
|
||||
* SessionInputBuffer, LineParser, HttpResponseFactory, MessageConstraints)}
|
||||
*/
|
||||
@Deprecated
|
||||
public DefaultHttpResponseParser(
|
||||
final SessionInputBuffer buffer,
|
||||
final LineParser parser,
|
||||
final HttpResponseFactory responseFactory,
|
||||
final HttpParams params) {
|
||||
super(buffer, parser, params);
|
||||
Args.notNull(responseFactory, "Response factory");
|
||||
this.responseFactory = responseFactory;
|
||||
this.lineBuf = new CharArrayBuffer(128);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new instance of DefaultHttpResponseParser.
|
||||
*
|
||||
* @param buffer the session input buffer.
|
||||
* @param lineParser the line parser. If <code>null</code>
|
||||
* {@link ch.boye.httpclientandroidlib.message.BasicLineParser#INSTANCE} will be used.
|
||||
* @param responseFactory HTTP response factory. If <code>null</code>
|
||||
* {@link DefaultHttpResponseFactory#INSTANCE} will be used.
|
||||
* @param constraints the message constraints. If <code>null</code>
|
||||
* {@link MessageConstraints#DEFAULT} will be used.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public DefaultHttpResponseParser(
|
||||
final SessionInputBuffer buffer,
|
||||
final LineParser lineParser,
|
||||
final HttpResponseFactory responseFactory,
|
||||
final MessageConstraints constraints) {
|
||||
super(buffer, lineParser, constraints);
|
||||
this.responseFactory = responseFactory != null ? responseFactory :
|
||||
DefaultHttpResponseFactory.INSTANCE;
|
||||
this.lineBuf = new CharArrayBuffer(128);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new instance of DefaultHttpResponseParser.
|
||||
*
|
||||
* @param buffer the session input buffer.
|
||||
* @param constraints the message constraints. If <code>null</code>
|
||||
* {@link MessageConstraints#DEFAULT} will be used.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public DefaultHttpResponseParser(
|
||||
final SessionInputBuffer buffer, final MessageConstraints constraints) {
|
||||
this(buffer, null, null, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new instance of DefaultHttpResponseParser.
|
||||
*
|
||||
* @param buffer the session input buffer.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public DefaultHttpResponseParser(final SessionInputBuffer buffer) {
|
||||
this(buffer, null, null, MessageConstraints.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpResponse parseHead(
|
||||
final SessionInputBuffer sessionBuffer) throws IOException, HttpException {
|
||||
//read out the HTTP status string
|
||||
int count = 0;
|
||||
ParserCursor cursor = null;
|
||||
do {
|
||||
// clear the buffer
|
||||
this.lineBuf.clear();
|
||||
final int i = sessionBuffer.readLine(this.lineBuf);
|
||||
if (i == -1 && count == 0) {
|
||||
// The server just dropped connection on us
|
||||
throw new NoHttpResponseException("The target server failed to respond");
|
||||
}
|
||||
cursor = new ParserCursor(0, this.lineBuf.length());
|
||||
if (lineParser.hasProtocolVersion(this.lineBuf, cursor)) {
|
||||
// Got one
|
||||
break;
|
||||
} else if (i == -1 || reject(this.lineBuf, count)) {
|
||||
// Giving up
|
||||
throw new ProtocolException("The server failed to respond with a " +
|
||||
"valid HTTP response");
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Garbage in response: " + this.lineBuf.toString());
|
||||
}
|
||||
count++;
|
||||
} while(true);
|
||||
//create the status line from the status string
|
||||
final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
|
||||
return this.responseFactory.newHttpResponse(statusline, null);
|
||||
}
|
||||
|
||||
protected boolean reject(final CharArrayBuffer line, final int count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.HttpResponseFactory;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.config.MessageConstraints;
|
||||
import ch.boye.httpclientandroidlib.impl.DefaultHttpResponseFactory;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageParser;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageParserFactory;
|
||||
import ch.boye.httpclientandroidlib.io.SessionInputBuffer;
|
||||
import ch.boye.httpclientandroidlib.message.BasicLineParser;
|
||||
import ch.boye.httpclientandroidlib.message.LineParser;
|
||||
|
||||
/**
|
||||
* Default factory for response message parsers.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@Immutable
|
||||
public class DefaultHttpResponseParserFactory implements HttpMessageParserFactory<HttpResponse> {
|
||||
|
||||
public static final DefaultHttpResponseParserFactory INSTANCE = new DefaultHttpResponseParserFactory();
|
||||
|
||||
private final LineParser lineParser;
|
||||
private final HttpResponseFactory responseFactory;
|
||||
|
||||
public DefaultHttpResponseParserFactory(
|
||||
final LineParser lineParser,
|
||||
final HttpResponseFactory responseFactory) {
|
||||
super();
|
||||
this.lineParser = lineParser != null ? lineParser : BasicLineParser.INSTANCE;
|
||||
this.responseFactory = responseFactory != null ? responseFactory
|
||||
: DefaultHttpResponseFactory.INSTANCE;
|
||||
}
|
||||
|
||||
public DefaultHttpResponseParserFactory(
|
||||
final HttpResponseFactory responseFactory) {
|
||||
this(null, responseFactory);
|
||||
}
|
||||
|
||||
public DefaultHttpResponseParserFactory() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public HttpMessageParser<HttpResponse> create(final SessionInputBuffer buffer,
|
||||
final MessageConstraints constraints) {
|
||||
return new DefaultHttpResponseParser(buffer, lineParser, responseFactory, constraints);
|
||||
}
|
||||
|
||||
}
|
||||
123
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultHttpRoutePlanner.java
vendored
Normal file
123
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultHttpRoutePlanner.java
vendored
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.params.ConnRouteParams;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoutePlanner;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.Scheme;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* Default implementation of an {@link HttpRoutePlanner}. This implementation
|
||||
* is based on {@link ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames parameters}.
|
||||
* It will not make use of any Java system properties, nor of system or
|
||||
* browser proxy settings.
|
||||
* <p>
|
||||
* The following parameters can be used to customize the behavior of this
|
||||
* class:
|
||||
* <ul>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames#DEFAULT_PROXY}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames#LOCAL_ADDRESS}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames#FORCED_ROUTE}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.3) use {@link DefaultRoutePlanner}
|
||||
*/
|
||||
@ThreadSafe
|
||||
@Deprecated
|
||||
public class DefaultHttpRoutePlanner implements HttpRoutePlanner {
|
||||
|
||||
/** The scheme registry. */
|
||||
protected final SchemeRegistry schemeRegistry; // class is @ThreadSafe
|
||||
|
||||
/**
|
||||
* Creates a new default route planner.
|
||||
*
|
||||
* @param schreg the scheme registry
|
||||
*/
|
||||
public DefaultHttpRoutePlanner(final SchemeRegistry schreg) {
|
||||
Args.notNull(schreg, "Scheme registry");
|
||||
schemeRegistry = schreg;
|
||||
}
|
||||
|
||||
public HttpRoute determineRoute(final HttpHost target,
|
||||
final HttpRequest request,
|
||||
final HttpContext context)
|
||||
throws HttpException {
|
||||
|
||||
Args.notNull(request, "HTTP request");
|
||||
|
||||
// If we have a forced route, we can do without a target.
|
||||
HttpRoute route =
|
||||
ConnRouteParams.getForcedRoute(request.getParams());
|
||||
if (route != null) {
|
||||
return route;
|
||||
}
|
||||
|
||||
// If we get here, there is no forced route.
|
||||
// So we need a target to compute a route.
|
||||
|
||||
Asserts.notNull(target, "Target host");
|
||||
|
||||
final InetAddress local =
|
||||
ConnRouteParams.getLocalAddress(request.getParams());
|
||||
final HttpHost proxy =
|
||||
ConnRouteParams.getDefaultProxy(request.getParams());
|
||||
|
||||
final Scheme schm;
|
||||
try {
|
||||
schm = this.schemeRegistry.getScheme(target.getSchemeName());
|
||||
} catch (final IllegalStateException ex) {
|
||||
throw new HttpException(ex.getMessage());
|
||||
}
|
||||
// as it is typically used for TLS/SSL, we assume that
|
||||
// a layered scheme implies a secure connection
|
||||
final boolean secure = schm.isLayered();
|
||||
|
||||
if (proxy == null) {
|
||||
route = new HttpRoute(target, local, secure);
|
||||
} else {
|
||||
route = new HttpRoute(target, local, proxy, secure);
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.config.MessageConstraints;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy;
|
||||
import ch.boye.httpclientandroidlib.impl.DefaultBHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageParserFactory;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageWriterFactory;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
* Default {@link ManagedHttpClientConnection} implementation.
|
||||
* @since 4.3
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public class DefaultManagedHttpClientConnection extends DefaultBHttpClientConnection
|
||||
implements ManagedHttpClientConnection, HttpContext {
|
||||
|
||||
private final String id;
|
||||
private final Map<String, Object> attributes;
|
||||
|
||||
private volatile boolean shutdown;
|
||||
|
||||
public DefaultManagedHttpClientConnection(
|
||||
final String id,
|
||||
final int buffersize,
|
||||
final int fragmentSizeHint,
|
||||
final CharsetDecoder chardecoder,
|
||||
final CharsetEncoder charencoder,
|
||||
final MessageConstraints constraints,
|
||||
final ContentLengthStrategy incomingContentStrategy,
|
||||
final ContentLengthStrategy outgoingContentStrategy,
|
||||
final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
|
||||
final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
|
||||
super(buffersize, fragmentSizeHint, chardecoder, charencoder,
|
||||
constraints, incomingContentStrategy, outgoingContentStrategy,
|
||||
requestWriterFactory, responseParserFactory);
|
||||
this.id = id;
|
||||
this.attributes = new ConcurrentHashMap<String, Object>();
|
||||
}
|
||||
|
||||
public DefaultManagedHttpClientConnection(
|
||||
final String id,
|
||||
final int buffersize) {
|
||||
this(id, buffersize, buffersize, null, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws IOException {
|
||||
this.shutdown = true;
|
||||
super.shutdown();
|
||||
}
|
||||
|
||||
public Object getAttribute(final String id) {
|
||||
return this.attributes.get(id);
|
||||
}
|
||||
|
||||
public Object removeAttribute(final String id) {
|
||||
return this.attributes.remove(id);
|
||||
}
|
||||
|
||||
public void setAttribute(final String id, final Object obj) {
|
||||
this.attributes.put(id, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(final Socket socket) throws IOException {
|
||||
if (this.shutdown) {
|
||||
socket.close(); // allow this to throw...
|
||||
// ...but if it doesn't, explicitly throw one ourselves.
|
||||
throw new InterruptedIOException("Connection already shutdown");
|
||||
}
|
||||
super.bind(socket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket getSocket() {
|
||||
return super.getSocket();
|
||||
}
|
||||
|
||||
public SSLSession getSSLSession() {
|
||||
final Socket socket = super.getSocket();
|
||||
if (socket instanceof SSLSocket) {
|
||||
return ((SSLSocket) socket).getSession();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
66
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultProxyRoutePlanner.java
vendored
Normal file
66
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultProxyRoutePlanner.java
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.conn.SchemePortResolver;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* Implementation of an {@link ch.boye.httpclientandroidlib.conn.routing.HttpRoutePlanner}
|
||||
* that routes requests through a default proxy.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@Immutable
|
||||
public class DefaultProxyRoutePlanner extends DefaultRoutePlanner {
|
||||
|
||||
private final HttpHost proxy;
|
||||
|
||||
public DefaultProxyRoutePlanner(final HttpHost proxy, final SchemePortResolver schemePortResolver) {
|
||||
super(schemePortResolver);
|
||||
this.proxy = Args.notNull(proxy, "Proxy host");
|
||||
}
|
||||
|
||||
public DefaultProxyRoutePlanner(final HttpHost proxy) {
|
||||
this(proxy, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpHost determineProxy(
|
||||
final HttpHost target,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws HttpException {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
}
|
||||
125
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultResponseParser.java
vendored
Normal file
125
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultResponseParser.java
vendored
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpMessage;
|
||||
import ch.boye.httpclientandroidlib.HttpResponseFactory;
|
||||
import ch.boye.httpclientandroidlib.NoHttpResponseException;
|
||||
import ch.boye.httpclientandroidlib.ProtocolException;
|
||||
import ch.boye.httpclientandroidlib.StatusLine;
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.impl.io.AbstractMessageParser;
|
||||
import ch.boye.httpclientandroidlib.io.SessionInputBuffer;
|
||||
import ch.boye.httpclientandroidlib.message.LineParser;
|
||||
import ch.boye.httpclientandroidlib.message.ParserCursor;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
|
||||
|
||||
/**
|
||||
* Default HTTP response parser implementation.
|
||||
* <p>
|
||||
* The following parameters can be used to customize the behavior of this
|
||||
* class:
|
||||
* <ul>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#MAX_HEADER_COUNT}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#MAX_LINE_LENGTH}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.conn.params.ConnConnectionPNames#MAX_STATUS_LINE_GARBAGE}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) use {@link DefaultHttpResponseParser}
|
||||
*/
|
||||
@Deprecated
|
||||
@ThreadSafe // no public methods
|
||||
public class DefaultResponseParser extends AbstractMessageParser<HttpMessage> {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
private final HttpResponseFactory responseFactory;
|
||||
private final CharArrayBuffer lineBuf;
|
||||
private final int maxGarbageLines;
|
||||
|
||||
public DefaultResponseParser(
|
||||
final SessionInputBuffer buffer,
|
||||
final LineParser parser,
|
||||
final HttpResponseFactory responseFactory,
|
||||
final HttpParams params) {
|
||||
super(buffer, parser, params);
|
||||
Args.notNull(responseFactory, "Response factory");
|
||||
this.responseFactory = responseFactory;
|
||||
this.lineBuf = new CharArrayBuffer(128);
|
||||
this.maxGarbageLines = getMaxGarbageLines(params);
|
||||
}
|
||||
|
||||
protected int getMaxGarbageLines(final HttpParams params) {
|
||||
return params.getIntParameter(
|
||||
ch.boye.httpclientandroidlib.conn.params.ConnConnectionPNames.MAX_STATUS_LINE_GARBAGE,
|
||||
Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpMessage parseHead(
|
||||
final SessionInputBuffer sessionBuffer) throws IOException, HttpException {
|
||||
//read out the HTTP status string
|
||||
int count = 0;
|
||||
ParserCursor cursor = null;
|
||||
do {
|
||||
// clear the buffer
|
||||
this.lineBuf.clear();
|
||||
final int i = sessionBuffer.readLine(this.lineBuf);
|
||||
if (i == -1 && count == 0) {
|
||||
// The server just dropped connection on us
|
||||
throw new NoHttpResponseException("The target server failed to respond");
|
||||
}
|
||||
cursor = new ParserCursor(0, this.lineBuf.length());
|
||||
if (lineParser.hasProtocolVersion(this.lineBuf, cursor)) {
|
||||
// Got one
|
||||
break;
|
||||
} else if (i == -1 || count >= this.maxGarbageLines) {
|
||||
// Giving up
|
||||
throw new ProtocolException("The server failed to respond with a " +
|
||||
"valid HTTP response");
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Garbage in response: " + this.lineBuf.toString());
|
||||
}
|
||||
count++;
|
||||
} while(true);
|
||||
//create the status line from the status string
|
||||
final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor);
|
||||
return this.responseFactory.newHttpResponse(statusline, null);
|
||||
}
|
||||
|
||||
}
|
||||
107
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultRoutePlanner.java
vendored
Normal file
107
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultRoutePlanner.java
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.ProtocolException;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.client.config.RequestConfig;
|
||||
import ch.boye.httpclientandroidlib.client.protocol.HttpClientContext;
|
||||
import ch.boye.httpclientandroidlib.conn.SchemePortResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.UnsupportedSchemeException;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoutePlanner;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* Default implementation of an {@link HttpRoutePlanner}. It will not make use of
|
||||
* any Java system properties, nor of system or browser proxy settings.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@Immutable
|
||||
public class DefaultRoutePlanner implements HttpRoutePlanner {
|
||||
|
||||
private final SchemePortResolver schemePortResolver;
|
||||
|
||||
public DefaultRoutePlanner(final SchemePortResolver schemePortResolver) {
|
||||
super();
|
||||
this.schemePortResolver = schemePortResolver != null ? schemePortResolver :
|
||||
DefaultSchemePortResolver.INSTANCE;
|
||||
}
|
||||
|
||||
public HttpRoute determineRoute(
|
||||
final HttpHost host,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws HttpException {
|
||||
Args.notNull(request, "Request");
|
||||
if (host == null) {
|
||||
throw new ProtocolException("Target host is not specified");
|
||||
}
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
final RequestConfig config = clientContext.getRequestConfig();
|
||||
final InetAddress local = config.getLocalAddress();
|
||||
HttpHost proxy = config.getProxy();
|
||||
if (proxy == null) {
|
||||
proxy = determineProxy(host, request, context);
|
||||
}
|
||||
|
||||
final HttpHost target;
|
||||
if (host.getPort() <= 0) {
|
||||
try {
|
||||
target = new HttpHost(
|
||||
host.getHostName(),
|
||||
this.schemePortResolver.resolve(host),
|
||||
host.getSchemeName());
|
||||
} catch (final UnsupportedSchemeException ex) {
|
||||
throw new HttpException(ex.getMessage());
|
||||
}
|
||||
} else {
|
||||
target = host;
|
||||
}
|
||||
final boolean secure = target.getSchemeName().equalsIgnoreCase("https");
|
||||
if (proxy == null) {
|
||||
return new HttpRoute(target, local, secure);
|
||||
} else {
|
||||
return new HttpRoute(target, local, proxy, secure);
|
||||
}
|
||||
}
|
||||
|
||||
protected HttpHost determineProxy(
|
||||
final HttpHost target,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws HttpException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
61
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultSchemePortResolver.java
vendored
Normal file
61
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/DefaultSchemePortResolver.java
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.conn.SchemePortResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.UnsupportedSchemeException;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* Default {@link SchemePortResolver}.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@Immutable
|
||||
public class DefaultSchemePortResolver implements SchemePortResolver {
|
||||
|
||||
public static final DefaultSchemePortResolver INSTANCE = new DefaultSchemePortResolver();
|
||||
|
||||
public int resolve(final HttpHost host) throws UnsupportedSchemeException {
|
||||
Args.notNull(host, "HTTP host");
|
||||
final int port = host.getPort();
|
||||
if (port > 0) {
|
||||
return port;
|
||||
}
|
||||
final String name = host.getSchemeName();
|
||||
if (name.equalsIgnoreCase("http")) {
|
||||
return 80;
|
||||
} else if (name.equalsIgnoreCase("https")) {
|
||||
return 443;
|
||||
} else {
|
||||
throw new UnsupportedSchemeException(name + " protocol is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
173
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/HttpClientConnectionOperator.java
vendored
Normal file
173
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/HttpClientConnectionOperator.java
vendored
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.client.protocol.HttpClientContext;
|
||||
import ch.boye.httpclientandroidlib.config.Lookup;
|
||||
import ch.boye.httpclientandroidlib.config.SocketConfig;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectTimeoutException;
|
||||
import ch.boye.httpclientandroidlib.conn.DnsResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.HttpHostConnectException;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.SchemePortResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.UnsupportedSchemeException;
|
||||
import ch.boye.httpclientandroidlib.conn.socket.ConnectionSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.socket.LayeredConnectionSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
@Immutable
|
||||
class HttpClientConnectionOperator {
|
||||
|
||||
static final String SOCKET_FACTORY_REGISTRY = "http.socket-factory-registry";
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
private final Lookup<ConnectionSocketFactory> socketFactoryRegistry;
|
||||
private final SchemePortResolver schemePortResolver;
|
||||
private final DnsResolver dnsResolver;
|
||||
|
||||
HttpClientConnectionOperator(
|
||||
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver) {
|
||||
super();
|
||||
Args.notNull(socketFactoryRegistry, "Socket factory registry");
|
||||
this.socketFactoryRegistry = socketFactoryRegistry;
|
||||
this.schemePortResolver = schemePortResolver != null ? schemePortResolver :
|
||||
DefaultSchemePortResolver.INSTANCE;
|
||||
this.dnsResolver = dnsResolver != null ? dnsResolver :
|
||||
SystemDefaultDnsResolver.INSTANCE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Lookup<ConnectionSocketFactory> getSocketFactoryRegistry(final HttpContext context) {
|
||||
Lookup<ConnectionSocketFactory> reg = (Lookup<ConnectionSocketFactory>) context.getAttribute(
|
||||
SOCKET_FACTORY_REGISTRY);
|
||||
if (reg == null) {
|
||||
reg = this.socketFactoryRegistry;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
public void connect(
|
||||
final ManagedHttpClientConnection conn,
|
||||
final HttpHost host,
|
||||
final InetSocketAddress localAddress,
|
||||
final int connectTimeout,
|
||||
final SocketConfig socketConfig,
|
||||
final HttpContext context) throws IOException {
|
||||
final Lookup<ConnectionSocketFactory> registry = getSocketFactoryRegistry(context);
|
||||
final ConnectionSocketFactory sf = registry.lookup(host.getSchemeName());
|
||||
if (sf == null) {
|
||||
throw new UnsupportedSchemeException(host.getSchemeName() +
|
||||
" protocol is not supported");
|
||||
}
|
||||
final InetAddress[] addresses = this.dnsResolver.resolve(host.getHostName());
|
||||
final int port = this.schemePortResolver.resolve(host);
|
||||
for (int i = 0; i < addresses.length; i++) {
|
||||
final InetAddress address = addresses[i];
|
||||
final boolean last = i == addresses.length - 1;
|
||||
|
||||
Socket sock = sf.createSocket(context);
|
||||
sock.setSoTimeout(socketConfig.getSoTimeout());
|
||||
sock.setReuseAddress(socketConfig.isSoReuseAddress());
|
||||
sock.setTcpNoDelay(socketConfig.isTcpNoDelay());
|
||||
sock.setKeepAlive(socketConfig.isSoKeepAlive());
|
||||
final int linger = socketConfig.getSoLinger();
|
||||
if (linger >= 0) {
|
||||
sock.setSoLinger(linger > 0, linger);
|
||||
}
|
||||
conn.bind(sock);
|
||||
|
||||
final InetSocketAddress remoteAddress = new InetSocketAddress(address, port);
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connecting to " + remoteAddress);
|
||||
}
|
||||
try {
|
||||
sock = sf.connectSocket(
|
||||
connectTimeout, sock, host, remoteAddress, localAddress, context);
|
||||
conn.bind(sock);
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection established " + conn);
|
||||
}
|
||||
return;
|
||||
} catch (final SocketTimeoutException ex) {
|
||||
if (last) {
|
||||
throw new ConnectTimeoutException(ex, host, addresses);
|
||||
}
|
||||
} catch (final ConnectException ex) {
|
||||
if (last) {
|
||||
final String msg = ex.getMessage();
|
||||
if ("Connection timed out".equals(msg)) {
|
||||
throw new ConnectTimeoutException(ex, host, addresses);
|
||||
} else {
|
||||
throw new HttpHostConnectException(ex, host, addresses);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connect to " + remoteAddress + " timed out. " +
|
||||
"Connection will be retried using another IP address");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void upgrade(
|
||||
final ManagedHttpClientConnection conn,
|
||||
final HttpHost host,
|
||||
final HttpContext context) throws IOException {
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
final Lookup<ConnectionSocketFactory> registry = getSocketFactoryRegistry(clientContext);
|
||||
final ConnectionSocketFactory sf = registry.lookup(host.getSchemeName());
|
||||
if (sf == null) {
|
||||
throw new UnsupportedSchemeException(host.getSchemeName() +
|
||||
" protocol is not supported");
|
||||
}
|
||||
if (!(sf instanceof LayeredConnectionSocketFactory)) {
|
||||
throw new UnsupportedSchemeException(host.getSchemeName() +
|
||||
" protocol does not support connection upgrade");
|
||||
}
|
||||
final LayeredConnectionSocketFactory lsf = (LayeredConnectionSocketFactory) sf;
|
||||
Socket sock = conn.getSocket();
|
||||
final int port = this.schemePortResolver.resolve(host);
|
||||
sock = lsf.createLayeredSocket(sock, host.getHostName(), port, context);
|
||||
conn.bind(sock);
|
||||
}
|
||||
|
||||
}
|
||||
84
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/HttpConnPool.java
vendored
Normal file
84
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/HttpConnPool.java
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.pool.AbstractConnPool;
|
||||
import ch.boye.httpclientandroidlib.pool.ConnFactory;
|
||||
|
||||
/**
|
||||
* @since 4.2
|
||||
*
|
||||
* @deprecated (4.3) no longer used.
|
||||
*/
|
||||
@Deprecated
|
||||
class HttpConnPool extends AbstractConnPool<HttpRoute, OperatedClientConnection, HttpPoolEntry> {
|
||||
|
||||
private static final AtomicLong COUNTER = new AtomicLong();
|
||||
|
||||
public HttpClientAndroidLog log;
|
||||
private final long timeToLive;
|
||||
private final TimeUnit tunit;
|
||||
|
||||
public HttpConnPool(final HttpClientAndroidLog log,
|
||||
final ClientConnectionOperator connOperator,
|
||||
final int defaultMaxPerRoute, final int maxTotal,
|
||||
final long timeToLive, final TimeUnit tunit) {
|
||||
super(new InternalConnFactory(connOperator), defaultMaxPerRoute, maxTotal);
|
||||
this.log = log;
|
||||
this.timeToLive = timeToLive;
|
||||
this.tunit = tunit;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpPoolEntry createEntry(final HttpRoute route, final OperatedClientConnection conn) {
|
||||
final String id = Long.toString(COUNTER.getAndIncrement());
|
||||
return new HttpPoolEntry(this.log, id, route, conn, this.timeToLive, this.tunit);
|
||||
}
|
||||
|
||||
static class InternalConnFactory implements ConnFactory<HttpRoute, OperatedClientConnection> {
|
||||
|
||||
private final ClientConnectionOperator connOperator;
|
||||
|
||||
InternalConnFactory(final ClientConnectionOperator connOperator) {
|
||||
this.connOperator = connOperator;
|
||||
}
|
||||
|
||||
public OperatedClientConnection create(final HttpRoute route) throws IOException {
|
||||
return connOperator.createConnection();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
98
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/HttpPoolEntry.java
vendored
Normal file
98
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/HttpPoolEntry.java
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.RouteTracker;
|
||||
import ch.boye.httpclientandroidlib.pool.PoolEntry;
|
||||
|
||||
/**
|
||||
* @since 4.2
|
||||
*
|
||||
* @deprecated (4.3) no longer used.
|
||||
*/
|
||||
@Deprecated
|
||||
class HttpPoolEntry extends PoolEntry<HttpRoute, OperatedClientConnection> {
|
||||
|
||||
public HttpClientAndroidLog log;
|
||||
private final RouteTracker tracker;
|
||||
|
||||
public HttpPoolEntry(
|
||||
final HttpClientAndroidLog log,
|
||||
final String id,
|
||||
final HttpRoute route,
|
||||
final OperatedClientConnection conn,
|
||||
final long timeToLive, final TimeUnit tunit) {
|
||||
super(id, route, conn, timeToLive, tunit);
|
||||
this.log = log;
|
||||
this.tracker = new RouteTracker(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired(final long now) {
|
||||
final boolean expired = super.isExpired(now);
|
||||
if (expired && this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection " + this + " expired @ " + new Date(getExpiry()));
|
||||
}
|
||||
return expired;
|
||||
}
|
||||
|
||||
RouteTracker getTracker() {
|
||||
return this.tracker;
|
||||
}
|
||||
|
||||
HttpRoute getPlannedRoute() {
|
||||
return getRoute();
|
||||
}
|
||||
|
||||
HttpRoute getEffectiveRoute() {
|
||||
return this.tracker.toRoute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
final OperatedClientConnection conn = getConnection();
|
||||
return !conn.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
final OperatedClientConnection conn = getConnection();
|
||||
try {
|
||||
conn.close();
|
||||
} catch (final IOException ex) {
|
||||
this.log.debug("I/O error closing connection", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
181
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/IdleConnectionHandler.java
vendored
Normal file
181
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/IdleConnectionHandler.java
vendored
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpConnection;
|
||||
|
||||
// Currently only used by AbstractConnPool
|
||||
/**
|
||||
* A helper class for connection managers to track idle connections.
|
||||
*
|
||||
* <p>This class is not synchronized.</p>
|
||||
*
|
||||
* @see ch.boye.httpclientandroidlib.conn.ClientConnectionManager#closeIdleConnections
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.1) no longer used
|
||||
*/
|
||||
@Deprecated
|
||||
public class IdleConnectionHandler {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
/** Holds connections and the time they were added. */
|
||||
private final Map<HttpConnection,TimeValues> connectionToTimes;
|
||||
|
||||
|
||||
public IdleConnectionHandler() {
|
||||
super();
|
||||
connectionToTimes = new HashMap<HttpConnection,TimeValues>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given connection with this handler. The connection will be held until
|
||||
* {@link #remove} or {@link #closeIdleConnections} is called.
|
||||
*
|
||||
* @param connection the connection to add
|
||||
*
|
||||
* @see #remove
|
||||
*/
|
||||
public void add(final HttpConnection connection, final long validDuration, final TimeUnit unit) {
|
||||
|
||||
final long timeAdded = System.currentTimeMillis();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Adding connection at: " + timeAdded);
|
||||
}
|
||||
|
||||
connectionToTimes.put(connection, new TimeValues(timeAdded, validDuration, unit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given connection from the list of connections to be closed when idle.
|
||||
* This will return true if the connection is still valid, and false
|
||||
* if the connection should be considered expired and not used.
|
||||
*
|
||||
* @param connection
|
||||
* @return True if the connection is still valid.
|
||||
*/
|
||||
public boolean remove(final HttpConnection connection) {
|
||||
final TimeValues times = connectionToTimes.remove(connection);
|
||||
if(times == null) {
|
||||
log.warn("Removing a connection that never existed!");
|
||||
return true;
|
||||
} else {
|
||||
return System.currentTimeMillis() <= times.timeExpires;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all connections referenced by this handler.
|
||||
*/
|
||||
public void removeAll() {
|
||||
this.connectionToTimes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes connections that have been idle for at least the given amount of time.
|
||||
*
|
||||
* @param idleTime the minimum idle time, in milliseconds, for connections to be closed
|
||||
*/
|
||||
public void closeIdleConnections(final long idleTime) {
|
||||
|
||||
// the latest time for which connections will be closed
|
||||
final long idleTimeout = System.currentTimeMillis() - idleTime;
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Checking for connections, idle timeout: " + idleTimeout);
|
||||
}
|
||||
|
||||
for (final Entry<HttpConnection, TimeValues> entry : connectionToTimes.entrySet()) {
|
||||
final HttpConnection conn = entry.getKey();
|
||||
final TimeValues times = entry.getValue();
|
||||
final long connectionTime = times.timeAdded;
|
||||
if (connectionTime <= idleTimeout) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing idle connection, connection time: " + connectionTime);
|
||||
}
|
||||
try {
|
||||
conn.close();
|
||||
} catch (final IOException ex) {
|
||||
log.debug("I/O error closing connection", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void closeExpiredConnections() {
|
||||
final long now = System.currentTimeMillis();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Checking for expired connections, now: " + now);
|
||||
}
|
||||
|
||||
for (final Entry<HttpConnection, TimeValues> entry : connectionToTimes.entrySet()) {
|
||||
final HttpConnection conn = entry.getKey();
|
||||
final TimeValues times = entry.getValue();
|
||||
if(times.timeExpires <= now) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing connection, expired @: " + times.timeExpires);
|
||||
}
|
||||
try {
|
||||
conn.close();
|
||||
} catch (final IOException ex) {
|
||||
log.debug("I/O error closing connection", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class TimeValues {
|
||||
private final long timeAdded;
|
||||
private final long timeExpires;
|
||||
|
||||
/**
|
||||
* @param now The current time in milliseconds
|
||||
* @param validDuration The duration this connection is valid for
|
||||
* @param validUnit The unit of time the duration is specified in.
|
||||
*/
|
||||
TimeValues(final long now, final long validDuration, final TimeUnit validUnit) {
|
||||
this.timeAdded = now;
|
||||
if(validDuration > 0) {
|
||||
this.timeExpires = now + validUnit.toMillis(validDuration);
|
||||
} else {
|
||||
this.timeExpires = Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/InMemoryDnsResolver.java
vendored
Normal file
94
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/InMemoryDnsResolver.java
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.conn.DnsResolver;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* In-memory {@link DnsResolver} implementation.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public class InMemoryDnsResolver implements DnsResolver {
|
||||
|
||||
/** Logger associated to this class. */
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(InMemoryDnsResolver.class);
|
||||
|
||||
/**
|
||||
* In-memory collection that will hold the associations between a host name
|
||||
* and an array of InetAddress instances.
|
||||
*/
|
||||
private final Map<String, InetAddress[]> dnsMap;
|
||||
|
||||
/**
|
||||
* Builds a DNS resolver that will resolve the host names against a
|
||||
* collection held in-memory.
|
||||
*/
|
||||
public InMemoryDnsResolver() {
|
||||
dnsMap = new ConcurrentHashMap<String, InetAddress[]>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the given array of IP addresses to the given host in this DNS overrider.
|
||||
* The IP addresses are assumed to be already resolved.
|
||||
*
|
||||
* @param host
|
||||
* The host name to be associated with the given IP.
|
||||
* @param ips
|
||||
* array of IP addresses to be resolved by this DNS overrider to the given
|
||||
* host name.
|
||||
*/
|
||||
public void add(final String host, final InetAddress... ips) {
|
||||
Args.notNull(host, "Host name");
|
||||
Args.notNull(ips, "Array of IP addresses");
|
||||
dnsMap.put(host, ips);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public InetAddress[] resolve(final String host) throws UnknownHostException {
|
||||
final InetAddress[] resolvedAddresses = dnsMap.get(host);
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Resolving " + host + " to " + Arrays.deepToString(resolvedAddresses));
|
||||
}
|
||||
if(resolvedAddresses == null){
|
||||
throw new UnknownHostException(host + " cannot be resolved");
|
||||
}
|
||||
return resolvedAddresses;
|
||||
}
|
||||
|
||||
}
|
||||
145
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/LoggingInputStream.java
vendored
Normal file
145
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/LoggingInputStream.java
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Internal class.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@NotThreadSafe
|
||||
class LoggingInputStream extends InputStream {
|
||||
|
||||
private final InputStream in;
|
||||
private final Wire wire;
|
||||
|
||||
public LoggingInputStream(final InputStream in, final Wire wire) {
|
||||
super();
|
||||
this.in = in;
|
||||
this.wire = wire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
try {
|
||||
final int b = in.read();
|
||||
if (b == -1) {
|
||||
wire.input("end of stream");
|
||||
} else {
|
||||
wire.input(b);
|
||||
}
|
||||
return b;
|
||||
} catch (IOException ex) {
|
||||
wire.input("[read] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(final byte[] b) throws IOException {
|
||||
try {
|
||||
final int bytesRead = in.read(b);
|
||||
if (bytesRead == -1) {
|
||||
wire.input("end of stream");
|
||||
} else if (bytesRead > 0) {
|
||||
wire.input(b, 0, bytesRead);
|
||||
}
|
||||
return bytesRead;
|
||||
} catch (IOException ex) {
|
||||
wire.input("[read] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(final byte[] b, final int off, final int len) throws IOException {
|
||||
try {
|
||||
final int bytesRead = in.read(b, off, len);
|
||||
if (bytesRead == -1) {
|
||||
wire.input("end of stream");
|
||||
} else if (bytesRead > 0) {
|
||||
wire.input(b, off, bytesRead);
|
||||
}
|
||||
return bytesRead;
|
||||
} catch (IOException ex) {
|
||||
wire.input("[read] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(final long n) throws IOException {
|
||||
try {
|
||||
return super.skip(n);
|
||||
} catch (IOException ex) {
|
||||
wire.input("[skip] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
try {
|
||||
return in.available();
|
||||
} catch (IOException ex) {
|
||||
wire.input("[available] I/O error : " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(final int readlimit) {
|
||||
super.mark(readlimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
super.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
wire.input("[close] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
import ch.boye.httpclientandroidlib.Header;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.config.MessageConstraints;
|
||||
import ch.boye.httpclientandroidlib.entity.ContentLengthStrategy;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageParserFactory;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageWriterFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
|
||||
@NotThreadSafe
|
||||
class LoggingManagedHttpClientConnection extends DefaultManagedHttpClientConnection {
|
||||
|
||||
public HttpClientAndroidLog log;
|
||||
private final HttpClientAndroidLog headerlog;
|
||||
private final Wire wire;
|
||||
|
||||
public LoggingManagedHttpClientConnection(
|
||||
final String id,
|
||||
final HttpClientAndroidLog log,
|
||||
final HttpClientAndroidLog headerlog,
|
||||
final HttpClientAndroidLog wirelog,
|
||||
final int buffersize,
|
||||
final int fragmentSizeHint,
|
||||
final CharsetDecoder chardecoder,
|
||||
final CharsetEncoder charencoder,
|
||||
final MessageConstraints constraints,
|
||||
final ContentLengthStrategy incomingContentStrategy,
|
||||
final ContentLengthStrategy outgoingContentStrategy,
|
||||
final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
|
||||
final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
|
||||
super(id, buffersize, fragmentSizeHint, chardecoder, charencoder,
|
||||
constraints, incomingContentStrategy, outgoingContentStrategy,
|
||||
requestWriterFactory, responseParserFactory);
|
||||
this.log = log;
|
||||
this.headerlog = headerlog;
|
||||
this.wire = new Wire(wirelog, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug(getId() + ": Close connection");
|
||||
}
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() throws IOException {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug(getId() + ": Shutdown connection");
|
||||
}
|
||||
super.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getSocketInputStream(final Socket socket) throws IOException {
|
||||
InputStream in = super.getSocketInputStream(socket);
|
||||
if (this.wire.enabled()) {
|
||||
in = new LoggingInputStream(in, this.wire);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OutputStream getSocketOutputStream(final Socket socket) throws IOException {
|
||||
OutputStream out = super.getSocketOutputStream(socket);
|
||||
if (this.wire.enabled()) {
|
||||
out = new LoggingOutputStream(out, this.wire);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResponseReceived(final HttpResponse response) {
|
||||
if (response != null && this.headerlog.isDebugEnabled()) {
|
||||
this.headerlog.debug(getId() + " << " + response.getStatusLine().toString());
|
||||
final Header[] headers = response.getAllHeaders();
|
||||
for (final Header header : headers) {
|
||||
this.headerlog.debug(getId() + " << " + header.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRequestSubmitted(final HttpRequest request) {
|
||||
if (request != null && this.headerlog.isDebugEnabled()) {
|
||||
this.headerlog.debug(getId() + " >> " + request.getRequestLine().toString());
|
||||
final Header[] headers = request.getAllHeaders();
|
||||
for (final Header header : headers) {
|
||||
this.headerlog.debug(getId() + " >> " + header.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
104
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/LoggingOutputStream.java
vendored
Normal file
104
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/LoggingOutputStream.java
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Internal class.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@NotThreadSafe
|
||||
class LoggingOutputStream extends OutputStream {
|
||||
|
||||
private final OutputStream out;
|
||||
private final Wire wire;
|
||||
|
||||
public LoggingOutputStream(final OutputStream out, final Wire wire) {
|
||||
super();
|
||||
this.out = out;
|
||||
this.wire = wire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final int b) throws IOException {
|
||||
try {
|
||||
wire.output(b);
|
||||
} catch (IOException ex) {
|
||||
wire.output("[write] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final byte[] b) throws IOException {
|
||||
try {
|
||||
wire.output(b);
|
||||
out.write(b);
|
||||
} catch (IOException ex) {
|
||||
wire.output("[write] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final byte[] b, final int off, final int len) throws IOException {
|
||||
try {
|
||||
wire.output(b, off, len);
|
||||
out.write(b, off, len);
|
||||
} catch (IOException ex) {
|
||||
wire.output("[write] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
try {
|
||||
out.flush();
|
||||
} catch (IOException ex) {
|
||||
wire.output("[flush] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
wire.output("[close] I/O error: " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
138
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/LoggingSessionInputBuffer.java
vendored
Normal file
138
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/LoggingSessionInputBuffer.java
vendored
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.Consts;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.io.EofSensor;
|
||||
import ch.boye.httpclientandroidlib.io.HttpTransportMetrics;
|
||||
import ch.boye.httpclientandroidlib.io.SessionInputBuffer;
|
||||
import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
|
||||
|
||||
/**
|
||||
* Logs all data read to the wire LOG.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.3) no longer used.
|
||||
*/
|
||||
@Immutable
|
||||
@Deprecated
|
||||
public class LoggingSessionInputBuffer implements SessionInputBuffer, EofSensor {
|
||||
|
||||
/** Original session input buffer. */
|
||||
private final SessionInputBuffer in;
|
||||
|
||||
private final EofSensor eofSensor;
|
||||
|
||||
/** The wire log to use for writing. */
|
||||
private final Wire wire;
|
||||
|
||||
private final String charset;
|
||||
|
||||
/**
|
||||
* Create an instance that wraps the specified session input buffer.
|
||||
* @param in The session input buffer.
|
||||
* @param wire The wire log to use.
|
||||
* @param charset protocol charset, <code>ASCII</code> if <code>null</code>
|
||||
*/
|
||||
public LoggingSessionInputBuffer(
|
||||
final SessionInputBuffer in, final Wire wire, final String charset) {
|
||||
super();
|
||||
this.in = in;
|
||||
this.eofSensor = in instanceof EofSensor ? (EofSensor) in : null;
|
||||
this.wire = wire;
|
||||
this.charset = charset != null ? charset : Consts.ASCII.name();
|
||||
}
|
||||
|
||||
public LoggingSessionInputBuffer(final SessionInputBuffer in, final Wire wire) {
|
||||
this(in, wire, null);
|
||||
}
|
||||
|
||||
public boolean isDataAvailable(final int timeout) throws IOException {
|
||||
return this.in.isDataAvailable(timeout);
|
||||
}
|
||||
|
||||
public int read(final byte[] b, final int off, final int len) throws IOException {
|
||||
final int l = this.in.read(b, off, len);
|
||||
if (this.wire.enabled() && l > 0) {
|
||||
this.wire.input(b, off, l);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
final int l = this.in.read();
|
||||
if (this.wire.enabled() && l != -1) {
|
||||
this.wire.input(l);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public int read(final byte[] b) throws IOException {
|
||||
final int l = this.in.read(b);
|
||||
if (this.wire.enabled() && l > 0) {
|
||||
this.wire.input(b, 0, l);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public String readLine() throws IOException {
|
||||
final String s = this.in.readLine();
|
||||
if (this.wire.enabled() && s != null) {
|
||||
final String tmp = s + "\r\n";
|
||||
this.wire.input(tmp.getBytes(this.charset));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public int readLine(final CharArrayBuffer buffer) throws IOException {
|
||||
final int l = this.in.readLine(buffer);
|
||||
if (this.wire.enabled() && l >= 0) {
|
||||
final int pos = buffer.length() - l;
|
||||
final String s = new String(buffer.buffer(), pos, l);
|
||||
final String tmp = s + "\r\n";
|
||||
this.wire.input(tmp.getBytes(this.charset));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public HttpTransportMetrics getMetrics() {
|
||||
return this.in.getMetrics();
|
||||
}
|
||||
|
||||
public boolean isEof() {
|
||||
if (this.eofSensor != null) {
|
||||
return this.eofSensor.isEof();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
118
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/LoggingSessionOutputBuffer.java
vendored
Normal file
118
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/LoggingSessionOutputBuffer.java
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.Consts;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.io.HttpTransportMetrics;
|
||||
import ch.boye.httpclientandroidlib.io.SessionOutputBuffer;
|
||||
import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
|
||||
|
||||
/**
|
||||
* Logs all data written to the wire LOG.
|
||||
* @since 4.0
|
||||
* @deprecated (4.3) no longer used.
|
||||
*/
|
||||
@Immutable
|
||||
@Deprecated
|
||||
public class LoggingSessionOutputBuffer implements SessionOutputBuffer {
|
||||
|
||||
/** Original data transmitter. */
|
||||
private final SessionOutputBuffer out;
|
||||
|
||||
/** The wire log to use. */
|
||||
private final Wire wire;
|
||||
|
||||
private final String charset;
|
||||
|
||||
/**
|
||||
* Create an instance that wraps the specified session output buffer.
|
||||
* @param out The session output buffer.
|
||||
* @param wire The Wire log to use.
|
||||
* @param charset protocol charset, <code>ASCII</code> if <code>null</code>
|
||||
*/
|
||||
public LoggingSessionOutputBuffer(
|
||||
final SessionOutputBuffer out, final Wire wire, final String charset) {
|
||||
super();
|
||||
this.out = out;
|
||||
this.wire = wire;
|
||||
this.charset = charset != null ? charset : Consts.ASCII.name();
|
||||
}
|
||||
|
||||
public LoggingSessionOutputBuffer(final SessionOutputBuffer out, final Wire wire) {
|
||||
this(out, wire, null);
|
||||
}
|
||||
|
||||
public void write(final byte[] b, final int off, final int len) throws IOException {
|
||||
this.out.write(b, off, len);
|
||||
if (this.wire.enabled()) {
|
||||
this.wire.output(b, off, len);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(final int b) throws IOException {
|
||||
this.out.write(b);
|
||||
if (this.wire.enabled()) {
|
||||
this.wire.output(b);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(final byte[] b) throws IOException {
|
||||
this.out.write(b);
|
||||
if (this.wire.enabled()) {
|
||||
this.wire.output(b);
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
this.out.flush();
|
||||
}
|
||||
|
||||
public void writeLine(final CharArrayBuffer buffer) throws IOException {
|
||||
this.out.writeLine(buffer);
|
||||
if (this.wire.enabled()) {
|
||||
final String s = new String(buffer.buffer(), 0, buffer.length());
|
||||
final String tmp = s + "\r\n";
|
||||
this.wire.output(tmp.getBytes(this.charset));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeLine(final String s) throws IOException {
|
||||
this.out.writeLine(s);
|
||||
if (this.wire.enabled()) {
|
||||
final String tmp = s + "\r\n";
|
||||
this.wire.output(tmp.getBytes(this.charset));
|
||||
}
|
||||
}
|
||||
|
||||
public HttpTransportMetrics getMetrics() {
|
||||
return this.out.getMetrics();
|
||||
}
|
||||
|
||||
}
|
||||
461
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/ManagedClientConnectionImpl.java
vendored
Normal file
461
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/ManagedClientConnectionImpl.java
vendored
Normal file
|
|
@ -0,0 +1,461 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpConnectionMetrics;
|
||||
import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.RouteTracker;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* @since 4.2
|
||||
*
|
||||
* @deprecated (4.3) use {@link ManagedHttpClientConnectionFactory}.
|
||||
*/
|
||||
@Deprecated
|
||||
@NotThreadSafe
|
||||
class ManagedClientConnectionImpl implements ManagedClientConnection {
|
||||
|
||||
private final ClientConnectionManager manager;
|
||||
private final ClientConnectionOperator operator;
|
||||
private volatile HttpPoolEntry poolEntry;
|
||||
private volatile boolean reusable;
|
||||
private volatile long duration;
|
||||
|
||||
ManagedClientConnectionImpl(
|
||||
final ClientConnectionManager manager,
|
||||
final ClientConnectionOperator operator,
|
||||
final HttpPoolEntry entry) {
|
||||
super();
|
||||
Args.notNull(manager, "Connection manager");
|
||||
Args.notNull(operator, "Connection operator");
|
||||
Args.notNull(entry, "HTTP pool entry");
|
||||
this.manager = manager;
|
||||
this.operator = operator;
|
||||
this.poolEntry = entry;
|
||||
this.reusable = false;
|
||||
this.duration = Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
HttpPoolEntry getPoolEntry() {
|
||||
return this.poolEntry;
|
||||
}
|
||||
|
||||
HttpPoolEntry detach() {
|
||||
final HttpPoolEntry local = this.poolEntry;
|
||||
this.poolEntry = null;
|
||||
return local;
|
||||
}
|
||||
|
||||
public ClientConnectionManager getManager() {
|
||||
return this.manager;
|
||||
}
|
||||
|
||||
private OperatedClientConnection getConnection() {
|
||||
final HttpPoolEntry local = this.poolEntry;
|
||||
if (local == null) {
|
||||
return null;
|
||||
}
|
||||
return local.getConnection();
|
||||
}
|
||||
|
||||
private OperatedClientConnection ensureConnection() {
|
||||
final HttpPoolEntry local = this.poolEntry;
|
||||
if (local == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
return local.getConnection();
|
||||
}
|
||||
|
||||
private HttpPoolEntry ensurePoolEntry() {
|
||||
final HttpPoolEntry local = this.poolEntry;
|
||||
if (local == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
return local;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
final HttpPoolEntry local = this.poolEntry;
|
||||
if (local != null) {
|
||||
final OperatedClientConnection conn = local.getConnection();
|
||||
local.getTracker().reset();
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() throws IOException {
|
||||
final HttpPoolEntry local = this.poolEntry;
|
||||
if (local != null) {
|
||||
final OperatedClientConnection conn = local.getConnection();
|
||||
local.getTracker().reset();
|
||||
conn.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
final OperatedClientConnection conn = getConnection();
|
||||
if (conn != null) {
|
||||
return conn.isOpen();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStale() {
|
||||
final OperatedClientConnection conn = getConnection();
|
||||
if (conn != null) {
|
||||
return conn.isStale();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSocketTimeout(final int timeout) {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
conn.setSocketTimeout(timeout);
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.getSocketTimeout();
|
||||
}
|
||||
|
||||
public HttpConnectionMetrics getMetrics() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.getMetrics();
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
conn.flush();
|
||||
}
|
||||
|
||||
public boolean isResponseAvailable(final int timeout) throws IOException {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.isResponseAvailable(timeout);
|
||||
}
|
||||
|
||||
public void receiveResponseEntity(
|
||||
final HttpResponse response) throws HttpException, IOException {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
conn.receiveResponseEntity(response);
|
||||
}
|
||||
|
||||
public HttpResponse receiveResponseHeader() throws HttpException, IOException {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.receiveResponseHeader();
|
||||
}
|
||||
|
||||
public void sendRequestEntity(
|
||||
final HttpEntityEnclosingRequest request) throws HttpException, IOException {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
conn.sendRequestEntity(request);
|
||||
}
|
||||
|
||||
public void sendRequestHeader(
|
||||
final HttpRequest request) throws HttpException, IOException {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
conn.sendRequestHeader(request);
|
||||
}
|
||||
|
||||
public InetAddress getLocalAddress() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.getLocalAddress();
|
||||
}
|
||||
|
||||
public int getLocalPort() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.getLocalPort();
|
||||
}
|
||||
|
||||
public InetAddress getRemoteAddress() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.getRemoteAddress();
|
||||
}
|
||||
|
||||
public int getRemotePort() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.getRemotePort();
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.isSecure();
|
||||
}
|
||||
|
||||
public void bind(final Socket socket) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Socket getSocket() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
return conn.getSocket();
|
||||
}
|
||||
|
||||
public SSLSession getSSLSession() {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
SSLSession result = null;
|
||||
final Socket sock = conn.getSocket();
|
||||
if (sock instanceof SSLSocket) {
|
||||
result = ((SSLSocket)sock).getSession();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object getAttribute(final String id) {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
if (conn instanceof HttpContext) {
|
||||
return ((HttpContext) conn).getAttribute(id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object removeAttribute(final String id) {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
if (conn instanceof HttpContext) {
|
||||
return ((HttpContext) conn).removeAttribute(id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAttribute(final String id, final Object obj) {
|
||||
final OperatedClientConnection conn = ensureConnection();
|
||||
if (conn instanceof HttpContext) {
|
||||
((HttpContext) conn).setAttribute(id, obj);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpRoute getRoute() {
|
||||
final HttpPoolEntry local = ensurePoolEntry();
|
||||
return local.getEffectiveRoute();
|
||||
}
|
||||
|
||||
public void open(
|
||||
final HttpRoute route,
|
||||
final HttpContext context,
|
||||
final HttpParams params) throws IOException {
|
||||
Args.notNull(route, "Route");
|
||||
Args.notNull(params, "HTTP parameters");
|
||||
final OperatedClientConnection conn;
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
final RouteTracker tracker = this.poolEntry.getTracker();
|
||||
Asserts.notNull(tracker, "Route tracker");
|
||||
Asserts.check(!tracker.isConnected(), "Connection already open");
|
||||
conn = this.poolEntry.getConnection();
|
||||
}
|
||||
|
||||
final HttpHost proxy = route.getProxyHost();
|
||||
this.operator.openConnection(
|
||||
conn,
|
||||
(proxy != null) ? proxy : route.getTargetHost(),
|
||||
route.getLocalAddress(),
|
||||
context, params);
|
||||
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
final RouteTracker tracker = this.poolEntry.getTracker();
|
||||
if (proxy == null) {
|
||||
tracker.connectTarget(conn.isSecure());
|
||||
} else {
|
||||
tracker.connectProxy(proxy, conn.isSecure());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void tunnelTarget(
|
||||
final boolean secure, final HttpParams params) throws IOException {
|
||||
Args.notNull(params, "HTTP parameters");
|
||||
final HttpHost target;
|
||||
final OperatedClientConnection conn;
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
final RouteTracker tracker = this.poolEntry.getTracker();
|
||||
Asserts.notNull(tracker, "Route tracker");
|
||||
Asserts.check(tracker.isConnected(), "Connection not open");
|
||||
Asserts.check(!tracker.isTunnelled(), "Connection is already tunnelled");
|
||||
target = tracker.getTargetHost();
|
||||
conn = this.poolEntry.getConnection();
|
||||
}
|
||||
|
||||
conn.update(null, target, secure, params);
|
||||
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
final RouteTracker tracker = this.poolEntry.getTracker();
|
||||
tracker.tunnelTarget(secure);
|
||||
}
|
||||
}
|
||||
|
||||
public void tunnelProxy(
|
||||
final HttpHost next, final boolean secure, final HttpParams params) throws IOException {
|
||||
Args.notNull(next, "Next proxy");
|
||||
Args.notNull(params, "HTTP parameters");
|
||||
final OperatedClientConnection conn;
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
final RouteTracker tracker = this.poolEntry.getTracker();
|
||||
Asserts.notNull(tracker, "Route tracker");
|
||||
Asserts.check(tracker.isConnected(), "Connection not open");
|
||||
conn = this.poolEntry.getConnection();
|
||||
}
|
||||
|
||||
conn.update(null, next, secure, params);
|
||||
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
final RouteTracker tracker = this.poolEntry.getTracker();
|
||||
tracker.tunnelProxy(next, secure);
|
||||
}
|
||||
}
|
||||
|
||||
public void layerProtocol(
|
||||
final HttpContext context, final HttpParams params) throws IOException {
|
||||
Args.notNull(params, "HTTP parameters");
|
||||
final HttpHost target;
|
||||
final OperatedClientConnection conn;
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
throw new ConnectionShutdownException();
|
||||
}
|
||||
final RouteTracker tracker = this.poolEntry.getTracker();
|
||||
Asserts.notNull(tracker, "Route tracker");
|
||||
Asserts.check(tracker.isConnected(), "Connection not open");
|
||||
Asserts.check(tracker.isTunnelled(), "Protocol layering without a tunnel not supported");
|
||||
Asserts.check(!tracker.isLayered(), "Multiple protocol layering not supported");
|
||||
target = tracker.getTargetHost();
|
||||
conn = this.poolEntry.getConnection();
|
||||
}
|
||||
this.operator.updateSecureConnection(conn, target, context, params);
|
||||
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
throw new InterruptedIOException();
|
||||
}
|
||||
final RouteTracker tracker = this.poolEntry.getTracker();
|
||||
tracker.layerProtocol(conn.isSecure());
|
||||
}
|
||||
}
|
||||
|
||||
public Object getState() {
|
||||
final HttpPoolEntry local = ensurePoolEntry();
|
||||
return local.getState();
|
||||
}
|
||||
|
||||
public void setState(final Object state) {
|
||||
final HttpPoolEntry local = ensurePoolEntry();
|
||||
local.setState(state);
|
||||
}
|
||||
|
||||
public void markReusable() {
|
||||
this.reusable = true;
|
||||
}
|
||||
|
||||
public void unmarkReusable() {
|
||||
this.reusable = false;
|
||||
}
|
||||
|
||||
public boolean isMarkedReusable() {
|
||||
return this.reusable;
|
||||
}
|
||||
|
||||
public void setIdleDuration(final long duration, final TimeUnit unit) {
|
||||
if(duration > 0) {
|
||||
this.duration = unit.toMillis(duration);
|
||||
} else {
|
||||
this.duration = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseConnection() {
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
return;
|
||||
}
|
||||
this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
|
||||
this.poolEntry = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void abortConnection() {
|
||||
synchronized (this) {
|
||||
if (this.poolEntry == null) {
|
||||
return;
|
||||
}
|
||||
this.reusable = false;
|
||||
final OperatedClientConnection conn = this.poolEntry.getConnection();
|
||||
try {
|
||||
conn.shutdown();
|
||||
} catch (final IOException ignore) {
|
||||
}
|
||||
this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
|
||||
this.poolEntry = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.config.ConnectionConfig;
|
||||
import ch.boye.httpclientandroidlib.conn.HttpConnectionFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.impl.io.DefaultHttpRequestWriterFactory;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageParserFactory;
|
||||
import ch.boye.httpclientandroidlib.io.HttpMessageWriterFactory;
|
||||
|
||||
/**
|
||||
* Factory for {@link ManagedHttpClientConnection} instances.
|
||||
* @since 4.3
|
||||
*/
|
||||
@Immutable
|
||||
public class ManagedHttpClientConnectionFactory
|
||||
implements HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> {
|
||||
|
||||
private static final AtomicLong COUNTER = new AtomicLong();
|
||||
|
||||
public static final ManagedHttpClientConnectionFactory INSTANCE = new ManagedHttpClientConnectionFactory();
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(DefaultManagedHttpClientConnection.class);
|
||||
public HttpClientAndroidLog headerlog = new HttpClientAndroidLog("ch.boye.httpclientandroidlib.headers");
|
||||
public HttpClientAndroidLog wirelog = new HttpClientAndroidLog("ch.boye.httpclientandroidlib.wire");
|
||||
|
||||
private final HttpMessageWriterFactory<HttpRequest> requestWriterFactory;
|
||||
private final HttpMessageParserFactory<HttpResponse> responseParserFactory;
|
||||
|
||||
public ManagedHttpClientConnectionFactory(
|
||||
final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
|
||||
final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
|
||||
super();
|
||||
this.requestWriterFactory = requestWriterFactory != null ? requestWriterFactory :
|
||||
DefaultHttpRequestWriterFactory.INSTANCE;
|
||||
this.responseParserFactory = responseParserFactory != null ? responseParserFactory :
|
||||
DefaultHttpResponseParserFactory.INSTANCE;
|
||||
}
|
||||
|
||||
public ManagedHttpClientConnectionFactory(
|
||||
final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
|
||||
this(null, responseParserFactory);
|
||||
}
|
||||
|
||||
public ManagedHttpClientConnectionFactory() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public ManagedHttpClientConnection create(final HttpRoute route, final ConnectionConfig config) {
|
||||
final ConnectionConfig cconfig = config != null ? config : ConnectionConfig.DEFAULT;
|
||||
CharsetDecoder chardecoder = null;
|
||||
CharsetEncoder charencoder = null;
|
||||
final Charset charset = cconfig.getCharset();
|
||||
final CodingErrorAction malformedInputAction = cconfig.getMalformedInputAction() != null ?
|
||||
cconfig.getMalformedInputAction() : CodingErrorAction.REPORT;
|
||||
final CodingErrorAction unmappableInputAction = cconfig.getUnmappableInputAction() != null ?
|
||||
cconfig.getUnmappableInputAction() : CodingErrorAction.REPORT;
|
||||
if (charset != null) {
|
||||
chardecoder = charset.newDecoder();
|
||||
chardecoder.onMalformedInput(malformedInputAction);
|
||||
chardecoder.onUnmappableCharacter(unmappableInputAction);
|
||||
charencoder = charset.newEncoder();
|
||||
charencoder.onMalformedInput(malformedInputAction);
|
||||
charencoder.onUnmappableCharacter(unmappableInputAction);
|
||||
}
|
||||
final String id = "http-outgoing-" + Long.toString(COUNTER.getAndIncrement());
|
||||
return new LoggingManagedHttpClientConnection(
|
||||
id,
|
||||
log,
|
||||
headerlog,
|
||||
wirelog,
|
||||
cconfig.getBufferSize(),
|
||||
cconfig.getFragmentSizeHint(),
|
||||
chardecoder,
|
||||
charencoder,
|
||||
cconfig.getMessageConstraints(),
|
||||
null,
|
||||
null,
|
||||
requestWriterFactory,
|
||||
responseParserFactory);
|
||||
}
|
||||
|
||||
}
|
||||
328
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/PoolingClientConnectionManager.java
vendored
Normal file
328
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/PoolingClientConnectionManager.java
vendored
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionRequest;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectionPoolTimeoutException;
|
||||
import ch.boye.httpclientandroidlib.conn.DnsResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
|
||||
import ch.boye.httpclientandroidlib.pool.ConnPoolControl;
|
||||
import ch.boye.httpclientandroidlib.pool.PoolStats;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* Manages a pool of {@link ch.boye.httpclientandroidlib.conn.OperatedClientConnection}
|
||||
* and is able to service connection requests from multiple execution threads.
|
||||
* Connections are pooled on a per route basis. A request for a route which
|
||||
* already the manager has persistent connections for available in the pool
|
||||
* will be services by leasing a connection from the pool rather than
|
||||
* creating a brand new connection.
|
||||
* <p>
|
||||
* PoolingConnectionManager maintains a maximum limit of connection on
|
||||
* a per route basis and in total. Per default this implementation will
|
||||
* create no more than than 2 concurrent connections per given route
|
||||
* and no more 20 connections in total. For many real-world applications
|
||||
* these limits may prove too constraining, especially if they use HTTP
|
||||
* as a transport protocol for their services. Connection limits, however,
|
||||
* can be adjusted using HTTP parameters.
|
||||
*
|
||||
* @since 4.2
|
||||
*
|
||||
* @deprecated (4.3) use {@link PoolingHttpClientConnectionManager}.
|
||||
*/
|
||||
@Deprecated
|
||||
@ThreadSafe
|
||||
public class PoolingClientConnectionManager implements ClientConnectionManager, ConnPoolControl<HttpRoute> {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
private final SchemeRegistry schemeRegistry;
|
||||
|
||||
private final HttpConnPool pool;
|
||||
|
||||
private final ClientConnectionOperator operator;
|
||||
|
||||
/** the custom-configured DNS lookup mechanism. */
|
||||
private final DnsResolver dnsResolver;
|
||||
|
||||
public PoolingClientConnectionManager(final SchemeRegistry schreg) {
|
||||
this(schreg, -1, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public PoolingClientConnectionManager(final SchemeRegistry schreg,final DnsResolver dnsResolver) {
|
||||
this(schreg, -1, TimeUnit.MILLISECONDS,dnsResolver);
|
||||
}
|
||||
|
||||
public PoolingClientConnectionManager() {
|
||||
this(SchemeRegistryFactory.createDefault());
|
||||
}
|
||||
|
||||
public PoolingClientConnectionManager(
|
||||
final SchemeRegistry schemeRegistry,
|
||||
final long timeToLive, final TimeUnit tunit) {
|
||||
this(schemeRegistry, timeToLive, tunit, new SystemDefaultDnsResolver());
|
||||
}
|
||||
|
||||
public PoolingClientConnectionManager(final SchemeRegistry schemeRegistry,
|
||||
final long timeToLive, final TimeUnit tunit,
|
||||
final DnsResolver dnsResolver) {
|
||||
super();
|
||||
Args.notNull(schemeRegistry, "Scheme registry");
|
||||
Args.notNull(dnsResolver, "DNS resolver");
|
||||
this.schemeRegistry = schemeRegistry;
|
||||
this.dnsResolver = dnsResolver;
|
||||
this.operator = createConnectionOperator(schemeRegistry);
|
||||
this.pool = new HttpConnPool(this.log, this.operator, 2, 20, timeToLive, tunit);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
shutdown();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for creating the connection operator.
|
||||
* It is called by the constructor.
|
||||
* Derived classes can override this method to change the
|
||||
* instantiation of the operator.
|
||||
* The default implementation here instantiates
|
||||
* {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}.
|
||||
*
|
||||
* @param schreg the scheme registry.
|
||||
*
|
||||
* @return the connection operator to use
|
||||
*/
|
||||
protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry schreg) {
|
||||
return new DefaultClientConnectionOperator(schreg, this.dnsResolver);
|
||||
}
|
||||
|
||||
public SchemeRegistry getSchemeRegistry() {
|
||||
return this.schemeRegistry;
|
||||
}
|
||||
|
||||
private String format(final HttpRoute route, final Object state) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("[route: ").append(route).append("]");
|
||||
if (state != null) {
|
||||
buf.append("[state: ").append(state).append("]");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String formatStats(final HttpRoute route) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
final PoolStats totals = this.pool.getTotalStats();
|
||||
final PoolStats stats = this.pool.getStats(route);
|
||||
buf.append("[total kept alive: ").append(totals.getAvailable()).append("; ");
|
||||
buf.append("route allocated: ").append(stats.getLeased() + stats.getAvailable());
|
||||
buf.append(" of ").append(stats.getMax()).append("; ");
|
||||
buf.append("total allocated: ").append(totals.getLeased() + totals.getAvailable());
|
||||
buf.append(" of ").append(totals.getMax()).append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String format(final HttpPoolEntry entry) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("[id: ").append(entry.getId()).append("]");
|
||||
buf.append("[route: ").append(entry.getRoute()).append("]");
|
||||
final Object state = entry.getState();
|
||||
if (state != null) {
|
||||
buf.append("[state: ").append(state).append("]");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public ClientConnectionRequest requestConnection(
|
||||
final HttpRoute route,
|
||||
final Object state) {
|
||||
Args.notNull(route, "HTTP route");
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection request: " + format(route, state) + formatStats(route));
|
||||
}
|
||||
final Future<HttpPoolEntry> future = this.pool.lease(route, state);
|
||||
|
||||
return new ClientConnectionRequest() {
|
||||
|
||||
public void abortRequest() {
|
||||
future.cancel(true);
|
||||
}
|
||||
|
||||
public ManagedClientConnection getConnection(
|
||||
final long timeout,
|
||||
final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException {
|
||||
return leaseConnection(future, timeout, tunit);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
ManagedClientConnection leaseConnection(
|
||||
final Future<HttpPoolEntry> future,
|
||||
final long timeout,
|
||||
final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException {
|
||||
final HttpPoolEntry entry;
|
||||
try {
|
||||
entry = future.get(timeout, tunit);
|
||||
if (entry == null || future.isCancelled()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
Asserts.check(entry.getConnection() != null, "Pool entry with no connection");
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection leased: " + format(entry) + formatStats(entry.getRoute()));
|
||||
}
|
||||
return new ManagedClientConnectionImpl(this, this.operator, entry);
|
||||
} catch (final ExecutionException ex) {
|
||||
Throwable cause = ex.getCause();
|
||||
if (cause == null) {
|
||||
cause = ex;
|
||||
}
|
||||
this.log.error("Unexpected exception leasing connection from pool", cause);
|
||||
// Should never happen
|
||||
throw new InterruptedException();
|
||||
} catch (final TimeoutException ex) {
|
||||
throw new ConnectionPoolTimeoutException("Timeout waiting for connection from pool");
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseConnection(
|
||||
final ManagedClientConnection conn, final long keepalive, final TimeUnit tunit) {
|
||||
|
||||
Args.check(conn instanceof ManagedClientConnectionImpl, "Connection class mismatch, " +
|
||||
"connection not obtained from this manager");
|
||||
final ManagedClientConnectionImpl managedConn = (ManagedClientConnectionImpl) conn;
|
||||
Asserts.check(managedConn.getManager() == this, "Connection not obtained from this manager");
|
||||
synchronized (managedConn) {
|
||||
final HttpPoolEntry entry = managedConn.detach();
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (managedConn.isOpen() && !managedConn.isMarkedReusable()) {
|
||||
try {
|
||||
managedConn.shutdown();
|
||||
} catch (final IOException iox) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("I/O exception shutting down released connection", iox);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only reusable connections can be kept alive
|
||||
if (managedConn.isMarkedReusable()) {
|
||||
entry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS);
|
||||
if (this.log.isDebugEnabled()) {
|
||||
final String s;
|
||||
if (keepalive > 0) {
|
||||
s = "for " + keepalive + " " + tunit;
|
||||
} else {
|
||||
s = "indefinitely";
|
||||
}
|
||||
this.log.debug("Connection " + format(entry) + " can be kept alive " + s);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.pool.release(entry, managedConn.isMarkedReusable());
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
this.log.debug("Connection manager is shutting down");
|
||||
try {
|
||||
this.pool.shutdown();
|
||||
} catch (final IOException ex) {
|
||||
this.log.debug("I/O exception shutting down connection manager", ex);
|
||||
}
|
||||
this.log.debug("Connection manager shut down");
|
||||
}
|
||||
|
||||
public void closeIdleConnections(final long idleTimeout, final TimeUnit tunit) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit);
|
||||
}
|
||||
this.pool.closeIdle(idleTimeout, tunit);
|
||||
}
|
||||
|
||||
public void closeExpiredConnections() {
|
||||
this.log.debug("Closing expired connections");
|
||||
this.pool.closeExpired();
|
||||
}
|
||||
|
||||
public int getMaxTotal() {
|
||||
return this.pool.getMaxTotal();
|
||||
}
|
||||
|
||||
public void setMaxTotal(final int max) {
|
||||
this.pool.setMaxTotal(max);
|
||||
}
|
||||
|
||||
public int getDefaultMaxPerRoute() {
|
||||
return this.pool.getDefaultMaxPerRoute();
|
||||
}
|
||||
|
||||
public void setDefaultMaxPerRoute(final int max) {
|
||||
this.pool.setDefaultMaxPerRoute(max);
|
||||
}
|
||||
|
||||
public int getMaxPerRoute(final HttpRoute route) {
|
||||
return this.pool.getMaxPerRoute(route);
|
||||
}
|
||||
|
||||
public void setMaxPerRoute(final HttpRoute route, final int max) {
|
||||
this.pool.setMaxPerRoute(route, max);
|
||||
}
|
||||
|
||||
public PoolStats getTotalStats() {
|
||||
return this.pool.getTotalStats();
|
||||
}
|
||||
|
||||
public PoolStats getStats(final HttpRoute route) {
|
||||
return this.pool.getStats(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,516 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.HttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.config.ConnectionConfig;
|
||||
import ch.boye.httpclientandroidlib.config.Lookup;
|
||||
import ch.boye.httpclientandroidlib.config.Registry;
|
||||
import ch.boye.httpclientandroidlib.config.RegistryBuilder;
|
||||
import ch.boye.httpclientandroidlib.config.SocketConfig;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectionPoolTimeoutException;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectionRequest;
|
||||
import ch.boye.httpclientandroidlib.conn.DnsResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.HttpClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.HttpConnectionFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.SchemePortResolver;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedHttpClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.socket.ConnectionSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.socket.PlainConnectionSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.ssl.SSLConnectionSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.pool.ConnFactory;
|
||||
import ch.boye.httpclientandroidlib.pool.ConnPoolControl;
|
||||
import ch.boye.httpclientandroidlib.pool.PoolStats;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* <tt>ClientConnectionPoolManager</tt> maintains a pool of
|
||||
* {@link HttpClientConnection}s and is able to service connection requests
|
||||
* from multiple execution threads. Connections are pooled on a per route
|
||||
* basis. A request for a route which already the manager has persistent
|
||||
* connections for available in the pool will be services by leasing
|
||||
* a connection from the pool rather than creating a brand new connection.
|
||||
* <p/>
|
||||
* <tt>ClientConnectionPoolManager</tt> maintains a maximum limit of connection
|
||||
* on a per route basis and in total. Per default this implementation will
|
||||
* create no more than than 2 concurrent connections per given route
|
||||
* and no more 20 connections in total. For many real-world applications
|
||||
* these limits may prove too constraining, especially if they use HTTP
|
||||
* as a transport protocol for their services. Connection limits, however,
|
||||
* can be adjusted using {@link ConnPoolControl} methods.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class PoolingHttpClientConnectionManager
|
||||
implements HttpClientConnectionManager, ConnPoolControl<HttpRoute>, Closeable {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
private final ConfigData configData;
|
||||
private final CPool pool;
|
||||
private final HttpClientConnectionOperator connectionOperator;
|
||||
private final AtomicBoolean isShutDown;
|
||||
|
||||
private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
|
||||
return RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
||||
.register("https", SSLConnectionSocketFactory.getSocketFactory())
|
||||
.build();
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager() {
|
||||
this(getDefaultRegistry());
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(final long timeToLive, final TimeUnit tunit) {
|
||||
this(getDefaultRegistry(), null, null ,null, timeToLive, tunit);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry) {
|
||||
this(socketFactoryRegistry, null, null);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final DnsResolver dnsResolver) {
|
||||
this(socketFactoryRegistry, null, dnsResolver);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory) {
|
||||
this(socketFactoryRegistry, connFactory, null);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory) {
|
||||
this(getDefaultRegistry(), connFactory, null);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory,
|
||||
final DnsResolver dnsResolver) {
|
||||
this(socketFactoryRegistry, connFactory, null, dnsResolver, -1, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver,
|
||||
final long timeToLive, final TimeUnit tunit) {
|
||||
super();
|
||||
this.configData = new ConfigData();
|
||||
this.pool = new CPool(
|
||||
new InternalConnectionFactory(this.configData, connFactory), 2, 20, timeToLive, tunit);
|
||||
this.connectionOperator = new HttpClientConnectionOperator(
|
||||
socketFactoryRegistry, schemePortResolver, dnsResolver);
|
||||
this.isShutDown = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
PoolingHttpClientConnectionManager(
|
||||
final CPool pool,
|
||||
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver) {
|
||||
super();
|
||||
this.configData = new ConfigData();
|
||||
this.pool = pool;
|
||||
this.connectionOperator = new HttpClientConnectionOperator(
|
||||
socketFactoryRegistry, schemePortResolver, dnsResolver);
|
||||
this.isShutDown = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
shutdown();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
private String format(final HttpRoute route, final Object state) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("[route: ").append(route).append("]");
|
||||
if (state != null) {
|
||||
buf.append("[state: ").append(state).append("]");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String formatStats(final HttpRoute route) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
final PoolStats totals = this.pool.getTotalStats();
|
||||
final PoolStats stats = this.pool.getStats(route);
|
||||
buf.append("[total kept alive: ").append(totals.getAvailable()).append("; ");
|
||||
buf.append("route allocated: ").append(stats.getLeased() + stats.getAvailable());
|
||||
buf.append(" of ").append(stats.getMax()).append("; ");
|
||||
buf.append("total allocated: ").append(totals.getLeased() + totals.getAvailable());
|
||||
buf.append(" of ").append(totals.getMax()).append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String format(final CPoolEntry entry) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("[id: ").append(entry.getId()).append("]");
|
||||
buf.append("[route: ").append(entry.getRoute()).append("]");
|
||||
final Object state = entry.getState();
|
||||
if (state != null) {
|
||||
buf.append("[state: ").append(state).append("]");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public ConnectionRequest requestConnection(
|
||||
final HttpRoute route,
|
||||
final Object state) {
|
||||
Args.notNull(route, "HTTP route");
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection request: " + format(route, state) + formatStats(route));
|
||||
}
|
||||
final Future<CPoolEntry> future = this.pool.lease(route, state, null);
|
||||
return new ConnectionRequest() {
|
||||
|
||||
public boolean cancel() {
|
||||
return future.cancel(true);
|
||||
}
|
||||
|
||||
public HttpClientConnection get(
|
||||
final long timeout,
|
||||
final TimeUnit tunit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException {
|
||||
return leaseConnection(future, timeout, tunit);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
protected HttpClientConnection leaseConnection(
|
||||
final Future<CPoolEntry> future,
|
||||
final long timeout,
|
||||
final TimeUnit tunit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException {
|
||||
final CPoolEntry entry;
|
||||
try {
|
||||
entry = future.get(timeout, tunit);
|
||||
if (entry == null || future.isCancelled()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
Asserts.check(entry.getConnection() != null, "Pool entry with no connection");
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection leased: " + format(entry) + formatStats(entry.getRoute()));
|
||||
}
|
||||
return CPoolProxy.newProxy(entry);
|
||||
} catch (final TimeoutException ex) {
|
||||
throw new ConnectionPoolTimeoutException("Timeout waiting for connection from pool");
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseConnection(
|
||||
final HttpClientConnection managedConn,
|
||||
final Object state,
|
||||
final long keepalive, final TimeUnit tunit) {
|
||||
Args.notNull(managedConn, "Managed connection");
|
||||
synchronized (managedConn) {
|
||||
final CPoolEntry entry = CPoolProxy.detach(managedConn);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
final ManagedHttpClientConnection conn = entry.getConnection();
|
||||
try {
|
||||
if (conn.isOpen()) {
|
||||
entry.setState(state);
|
||||
entry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS);
|
||||
if (this.log.isDebugEnabled()) {
|
||||
final String s;
|
||||
if (keepalive > 0) {
|
||||
s = "for " + (double) keepalive / 1000 + " seconds";
|
||||
} else {
|
||||
s = "indefinitely";
|
||||
}
|
||||
this.log.debug("Connection " + format(entry) + " can be kept alive " + s);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.pool.release(entry, conn.isOpen() && entry.isRouteComplete());
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void connect(
|
||||
final HttpClientConnection managedConn,
|
||||
final HttpRoute route,
|
||||
final int connectTimeout,
|
||||
final HttpContext context) throws IOException {
|
||||
Args.notNull(managedConn, "Managed Connection");
|
||||
Args.notNull(route, "HTTP route");
|
||||
final ManagedHttpClientConnection conn;
|
||||
synchronized (managedConn) {
|
||||
final CPoolEntry entry = CPoolProxy.getPoolEntry(managedConn);
|
||||
conn = entry.getConnection();
|
||||
}
|
||||
final HttpHost host;
|
||||
if (route.getProxyHost() != null) {
|
||||
host = route.getProxyHost();
|
||||
} else {
|
||||
host = route.getTargetHost();
|
||||
}
|
||||
final InetSocketAddress localAddress = route.getLocalSocketAddress();
|
||||
SocketConfig socketConfig = this.configData.getSocketConfig(host);
|
||||
if (socketConfig == null) {
|
||||
socketConfig = this.configData.getDefaultSocketConfig();
|
||||
}
|
||||
if (socketConfig == null) {
|
||||
socketConfig = SocketConfig.DEFAULT;
|
||||
}
|
||||
this.connectionOperator.connect(
|
||||
conn, host, localAddress, connectTimeout, socketConfig, context);
|
||||
}
|
||||
|
||||
public void upgrade(
|
||||
final HttpClientConnection managedConn,
|
||||
final HttpRoute route,
|
||||
final HttpContext context) throws IOException {
|
||||
Args.notNull(managedConn, "Managed Connection");
|
||||
Args.notNull(route, "HTTP route");
|
||||
final ManagedHttpClientConnection conn;
|
||||
synchronized (managedConn) {
|
||||
final CPoolEntry entry = CPoolProxy.getPoolEntry(managedConn);
|
||||
conn = entry.getConnection();
|
||||
}
|
||||
this.connectionOperator.upgrade(conn, route.getTargetHost(), context);
|
||||
}
|
||||
|
||||
public void routeComplete(
|
||||
final HttpClientConnection managedConn,
|
||||
final HttpRoute route,
|
||||
final HttpContext context) throws IOException {
|
||||
Args.notNull(managedConn, "Managed Connection");
|
||||
Args.notNull(route, "HTTP route");
|
||||
synchronized (managedConn) {
|
||||
final CPoolEntry entry = CPoolProxy.getPoolEntry(managedConn);
|
||||
entry.markRouteComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
if (this.isShutDown.compareAndSet(false, true)) {
|
||||
this.log.debug("Connection manager is shutting down");
|
||||
try {
|
||||
this.pool.shutdown();
|
||||
} catch (final IOException ex) {
|
||||
this.log.debug("I/O exception shutting down connection manager", ex);
|
||||
}
|
||||
this.log.debug("Connection manager shut down");
|
||||
}
|
||||
}
|
||||
|
||||
public void closeIdleConnections(final long idleTimeout, final TimeUnit tunit) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit);
|
||||
}
|
||||
this.pool.closeIdle(idleTimeout, tunit);
|
||||
}
|
||||
|
||||
public void closeExpiredConnections() {
|
||||
this.log.debug("Closing expired connections");
|
||||
this.pool.closeExpired();
|
||||
}
|
||||
|
||||
public int getMaxTotal() {
|
||||
return this.pool.getMaxTotal();
|
||||
}
|
||||
|
||||
public void setMaxTotal(final int max) {
|
||||
this.pool.setMaxTotal(max);
|
||||
}
|
||||
|
||||
public int getDefaultMaxPerRoute() {
|
||||
return this.pool.getDefaultMaxPerRoute();
|
||||
}
|
||||
|
||||
public void setDefaultMaxPerRoute(final int max) {
|
||||
this.pool.setDefaultMaxPerRoute(max);
|
||||
}
|
||||
|
||||
public int getMaxPerRoute(final HttpRoute route) {
|
||||
return this.pool.getMaxPerRoute(route);
|
||||
}
|
||||
|
||||
public void setMaxPerRoute(final HttpRoute route, final int max) {
|
||||
this.pool.setMaxPerRoute(route, max);
|
||||
}
|
||||
|
||||
public PoolStats getTotalStats() {
|
||||
return this.pool.getTotalStats();
|
||||
}
|
||||
|
||||
public PoolStats getStats(final HttpRoute route) {
|
||||
return this.pool.getStats(route);
|
||||
}
|
||||
|
||||
public SocketConfig getDefaultSocketConfig() {
|
||||
return this.configData.getDefaultSocketConfig();
|
||||
}
|
||||
|
||||
public void setDefaultSocketConfig(final SocketConfig defaultSocketConfig) {
|
||||
this.configData.setDefaultSocketConfig(defaultSocketConfig);
|
||||
}
|
||||
|
||||
public ConnectionConfig getDefaultConnectionConfig() {
|
||||
return this.configData.getDefaultConnectionConfig();
|
||||
}
|
||||
|
||||
public void setDefaultConnectionConfig(final ConnectionConfig defaultConnectionConfig) {
|
||||
this.configData.setDefaultConnectionConfig(defaultConnectionConfig);
|
||||
}
|
||||
|
||||
public SocketConfig getSocketConfig(final HttpHost host) {
|
||||
return this.configData.getSocketConfig(host);
|
||||
}
|
||||
|
||||
public void setSocketConfig(final HttpHost host, final SocketConfig socketConfig) {
|
||||
this.configData.setSocketConfig(host, socketConfig);
|
||||
}
|
||||
|
||||
public ConnectionConfig getConnectionConfig(final HttpHost host) {
|
||||
return this.configData.getConnectionConfig(host);
|
||||
}
|
||||
|
||||
public void setConnectionConfig(final HttpHost host, final ConnectionConfig connectionConfig) {
|
||||
this.configData.setConnectionConfig(host, connectionConfig);
|
||||
}
|
||||
|
||||
static class ConfigData {
|
||||
|
||||
private final Map<HttpHost, SocketConfig> socketConfigMap;
|
||||
private final Map<HttpHost, ConnectionConfig> connectionConfigMap;
|
||||
private volatile SocketConfig defaultSocketConfig;
|
||||
private volatile ConnectionConfig defaultConnectionConfig;
|
||||
|
||||
ConfigData() {
|
||||
super();
|
||||
this.socketConfigMap = new ConcurrentHashMap<HttpHost, SocketConfig>();
|
||||
this.connectionConfigMap = new ConcurrentHashMap<HttpHost, ConnectionConfig>();
|
||||
}
|
||||
|
||||
public SocketConfig getDefaultSocketConfig() {
|
||||
return this.defaultSocketConfig;
|
||||
}
|
||||
|
||||
public void setDefaultSocketConfig(final SocketConfig defaultSocketConfig) {
|
||||
this.defaultSocketConfig = defaultSocketConfig;
|
||||
}
|
||||
|
||||
public ConnectionConfig getDefaultConnectionConfig() {
|
||||
return this.defaultConnectionConfig;
|
||||
}
|
||||
|
||||
public void setDefaultConnectionConfig(final ConnectionConfig defaultConnectionConfig) {
|
||||
this.defaultConnectionConfig = defaultConnectionConfig;
|
||||
}
|
||||
|
||||
public SocketConfig getSocketConfig(final HttpHost host) {
|
||||
return this.socketConfigMap.get(host);
|
||||
}
|
||||
|
||||
public void setSocketConfig(final HttpHost host, final SocketConfig socketConfig) {
|
||||
this.socketConfigMap.put(host, socketConfig);
|
||||
}
|
||||
|
||||
public ConnectionConfig getConnectionConfig(final HttpHost host) {
|
||||
return this.connectionConfigMap.get(host);
|
||||
}
|
||||
|
||||
public void setConnectionConfig(final HttpHost host, final ConnectionConfig connectionConfig) {
|
||||
this.connectionConfigMap.put(host, connectionConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class InternalConnectionFactory implements ConnFactory<HttpRoute, ManagedHttpClientConnection> {
|
||||
|
||||
private final ConfigData configData;
|
||||
private final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory;
|
||||
|
||||
InternalConnectionFactory(
|
||||
final ConfigData configData,
|
||||
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory) {
|
||||
super();
|
||||
this.configData = configData != null ? configData : new ConfigData();
|
||||
this.connFactory = connFactory != null ? connFactory :
|
||||
ManagedHttpClientConnectionFactory.INSTANCE;
|
||||
}
|
||||
|
||||
public ManagedHttpClientConnection create(final HttpRoute route) throws IOException {
|
||||
ConnectionConfig config = null;
|
||||
if (route.getProxyHost() != null) {
|
||||
config = this.configData.getConnectionConfig(route.getProxyHost());
|
||||
}
|
||||
if (config == null) {
|
||||
config = this.configData.getConnectionConfig(route.getTargetHost());
|
||||
}
|
||||
if (config == null) {
|
||||
config = this.configData.getDefaultConnectionConfig();
|
||||
}
|
||||
if (config == null) {
|
||||
config = ConnectionConfig.DEFAULT;
|
||||
}
|
||||
return this.connFactory.create(route, config);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
279
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/ProxySelectorRoutePlanner.java
vendored
Normal file
279
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/ProxySelectorRoutePlanner.java
vendored
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.annotation.NotThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.params.ConnRouteParams;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoutePlanner;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.Scheme;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of an {@link HttpRoutePlanner}.
|
||||
* This implementation is based on {@link java.net.ProxySelector}.
|
||||
* By default, it will pick up the proxy settings of the JVM, either
|
||||
* from system properties or from the browser running the application.
|
||||
* Additionally, it interprets some
|
||||
* {@link ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames parameters},
|
||||
* though not the {@link
|
||||
* ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames#DEFAULT_PROXY DEFAULT_PROXY}.
|
||||
* <p>
|
||||
* The following parameters can be used to customize the behavior of this
|
||||
* class:
|
||||
* <ul>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames#LOCAL_ADDRESS}</li>
|
||||
* <li>{@link ch.boye.httpclientandroidlib.conn.params.ConnRoutePNames#FORCED_ROUTE}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.3) use {@link SystemDefaultRoutePlanner}
|
||||
*/
|
||||
@NotThreadSafe // e.g [gs]etProxySelector()
|
||||
@Deprecated
|
||||
public class ProxySelectorRoutePlanner implements HttpRoutePlanner {
|
||||
|
||||
/** The scheme registry. */
|
||||
protected final SchemeRegistry schemeRegistry; // @ThreadSafe
|
||||
|
||||
/** The proxy selector to use, or <code>null</code> for system default. */
|
||||
protected ProxySelector proxySelector;
|
||||
|
||||
/**
|
||||
* Creates a new proxy selector route planner.
|
||||
*
|
||||
* @param schreg the scheme registry
|
||||
* @param prosel the proxy selector, or
|
||||
* <code>null</code> for the system default
|
||||
*/
|
||||
public ProxySelectorRoutePlanner(final SchemeRegistry schreg,
|
||||
final ProxySelector prosel) {
|
||||
Args.notNull(schreg, "SchemeRegistry");
|
||||
schemeRegistry = schreg;
|
||||
proxySelector = prosel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the proxy selector to use.
|
||||
*
|
||||
* @return the proxy selector, or <code>null</code> for the system default
|
||||
*/
|
||||
public ProxySelector getProxySelector() {
|
||||
return this.proxySelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the proxy selector to use.
|
||||
*
|
||||
* @param prosel the proxy selector, or
|
||||
* <code>null</code> to use the system default
|
||||
*/
|
||||
public void setProxySelector(final ProxySelector prosel) {
|
||||
this.proxySelector = prosel;
|
||||
}
|
||||
|
||||
public HttpRoute determineRoute(final HttpHost target,
|
||||
final HttpRequest request,
|
||||
final HttpContext context)
|
||||
throws HttpException {
|
||||
|
||||
Args.notNull(request, "HTTP request");
|
||||
|
||||
// If we have a forced route, we can do without a target.
|
||||
HttpRoute route =
|
||||
ConnRouteParams.getForcedRoute(request.getParams());
|
||||
if (route != null) {
|
||||
return route;
|
||||
}
|
||||
|
||||
// If we get here, there is no forced route.
|
||||
// So we need a target to compute a route.
|
||||
|
||||
Asserts.notNull(target, "Target host");
|
||||
|
||||
final InetAddress local =
|
||||
ConnRouteParams.getLocalAddress(request.getParams());
|
||||
final HttpHost proxy = determineProxy(target, request, context);
|
||||
|
||||
final Scheme schm =
|
||||
this.schemeRegistry.getScheme(target.getSchemeName());
|
||||
// as it is typically used for TLS/SSL, we assume that
|
||||
// a layered scheme implies a secure connection
|
||||
final boolean secure = schm.isLayered();
|
||||
|
||||
if (proxy == null) {
|
||||
route = new HttpRoute(target, local, secure);
|
||||
} else {
|
||||
route = new HttpRoute(target, local, proxy, secure);
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines a proxy for the given target.
|
||||
*
|
||||
* @param target the planned target, never <code>null</code>
|
||||
* @param request the request to be sent, never <code>null</code>
|
||||
* @param context the context, or <code>null</code>
|
||||
*
|
||||
* @return the proxy to use, or <code>null</code> for a direct route
|
||||
*
|
||||
* @throws HttpException
|
||||
* in case of system proxy settings that cannot be handled
|
||||
*/
|
||||
protected HttpHost determineProxy(final HttpHost target,
|
||||
final HttpRequest request,
|
||||
final HttpContext context)
|
||||
throws HttpException {
|
||||
|
||||
// the proxy selector can be 'unset', so we better deal with null here
|
||||
ProxySelector psel = this.proxySelector;
|
||||
if (psel == null) {
|
||||
psel = ProxySelector.getDefault();
|
||||
}
|
||||
if (psel == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
URI targetURI = null;
|
||||
try {
|
||||
targetURI = new URI(target.toURI());
|
||||
} catch (final URISyntaxException usx) {
|
||||
throw new HttpException
|
||||
("Cannot convert host to URI: " + target, usx);
|
||||
}
|
||||
final List<Proxy> proxies = psel.select(targetURI);
|
||||
|
||||
final Proxy p = chooseProxy(proxies, target, request, context);
|
||||
|
||||
HttpHost result = null;
|
||||
if (p.type() == Proxy.Type.HTTP) {
|
||||
// convert the socket address to an HttpHost
|
||||
if (!(p.address() instanceof InetSocketAddress)) {
|
||||
throw new HttpException
|
||||
("Unable to handle non-Inet proxy address: "+p.address());
|
||||
}
|
||||
final InetSocketAddress isa = (InetSocketAddress) p.address();
|
||||
// assume default scheme (http)
|
||||
result = new HttpHost(getHost(isa), isa.getPort());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a host from an {@link InetSocketAddress}.
|
||||
*
|
||||
* @param isa the socket address
|
||||
*
|
||||
* @return a host string, either as a symbolic name or
|
||||
* as a literal IP address string
|
||||
* <br/>
|
||||
* (TODO: determine format for IPv6 addresses, with or without [brackets])
|
||||
*/
|
||||
protected String getHost(final InetSocketAddress isa) {
|
||||
|
||||
//@@@ Will this work with literal IPv6 addresses, or do we
|
||||
//@@@ need to wrap these in [] for the string representation?
|
||||
//@@@ Having it in this method at least allows for easy workarounds.
|
||||
return isa.isUnresolved() ?
|
||||
isa.getHostName() : isa.getAddress().getHostAddress();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses a proxy from a list of available proxies.
|
||||
* The default implementation just picks the first non-SOCKS proxy
|
||||
* from the list. If there are only SOCKS proxies,
|
||||
* {@link Proxy#NO_PROXY Proxy.NO_PROXY} is returned.
|
||||
* Derived classes may implement more advanced strategies,
|
||||
* such as proxy rotation if there are multiple options.
|
||||
*
|
||||
* @param proxies the list of proxies to choose from,
|
||||
* never <code>null</code> or empty
|
||||
* @param target the planned target, never <code>null</code>
|
||||
* @param request the request to be sent, never <code>null</code>
|
||||
* @param context the context, or <code>null</code>
|
||||
*
|
||||
* @return a proxy type
|
||||
*/
|
||||
protected Proxy chooseProxy(final List<Proxy> proxies,
|
||||
final HttpHost target,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) {
|
||||
Args.notEmpty(proxies, "List of proxies");
|
||||
|
||||
Proxy result = null;
|
||||
|
||||
// check the list for one we can use
|
||||
for (int i=0; (result == null) && (i < proxies.size()); i++) {
|
||||
|
||||
final Proxy p = proxies.get(i);
|
||||
switch (p.type()) {
|
||||
|
||||
case DIRECT:
|
||||
case HTTP:
|
||||
result = p;
|
||||
break;
|
||||
|
||||
case SOCKS:
|
||||
// SOCKS hosts are not handled on the route level.
|
||||
// The socket may make use of the SOCKS host though.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
//@@@ log as warning or info that only a socks proxy is available?
|
||||
// result can only be null if all proxies are socks proxies
|
||||
// socks proxies are not handled on the route planning level
|
||||
result = Proxy.NO_PROXY;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
90
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SchemeRegistryFactory.java
vendored
Normal file
90
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SchemeRegistryFactory.java
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.PlainSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.Scheme;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
|
||||
import ch.boye.httpclientandroidlib.conn.ssl.SSLSocketFactory;
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*
|
||||
* @deprecated (4.3) use {@link ch.boye.httpclientandroidlib.impl.client.HttpClientBuilder}.
|
||||
*/
|
||||
@ThreadSafe
|
||||
@Deprecated
|
||||
public final class SchemeRegistryFactory {
|
||||
|
||||
/**
|
||||
* Initializes default scheme registry based on JSSE defaults. System properties will
|
||||
* not be taken into consideration.
|
||||
*/
|
||||
public static SchemeRegistry createDefault() {
|
||||
final SchemeRegistry registry = new SchemeRegistry();
|
||||
registry.register(
|
||||
new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
|
||||
registry.register(
|
||||
new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
|
||||
return registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes default scheme registry using system properties as described in
|
||||
* <a href="http://download.oracle.com/javase/1,5.0/docs/guide/security/jsse/JSSERefGuide.html">
|
||||
* "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform
|
||||
* Standard Edition 5</a>
|
||||
* <p>
|
||||
* The following system properties are taken into account by this method:
|
||||
* <ul>
|
||||
* <li>ssl.TrustManagerFactory.algorithm</li>
|
||||
* <li>javax.net.ssl.trustStoreType</li>
|
||||
* <li>javax.net.ssl.trustStore</li>
|
||||
* <li>javax.net.ssl.trustStoreProvider</li>
|
||||
* <li>javax.net.ssl.trustStorePassword</li>
|
||||
* <li>java.home</li>
|
||||
* <li>ssl.KeyManagerFactory.algorithm</li>
|
||||
* <li>javax.net.ssl.keyStoreType</li>
|
||||
* <li>javax.net.ssl.keyStore</li>
|
||||
* <li>javax.net.ssl.keyStoreProvider</li>
|
||||
* <li>javax.net.ssl.keyStorePassword</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public static SchemeRegistry createSystemDefault() {
|
||||
final SchemeRegistry registry = new SchemeRegistry();
|
||||
registry.register(
|
||||
new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
|
||||
registry.register(
|
||||
new Scheme("https", 443, SSLSocketFactory.getSystemSocketFactory()));
|
||||
return registry;
|
||||
}
|
||||
}
|
||||
|
||||
427
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SingleClientConnManager.java
vendored
Normal file
427
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SingleClientConnManager.java
vendored
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.annotation.GuardedBy;
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionRequest;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.RouteTracker;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* A connection manager for a single connection. This connection manager
|
||||
* maintains only one active connection at a time. Even though this class
|
||||
* is thread-safe it ought to be used by one execution thread only.
|
||||
* <p>
|
||||
* SingleClientConnManager will make an effort to reuse the connection
|
||||
* for subsequent requests with the same {@link HttpRoute route}.
|
||||
* It will, however, close the existing connection and open it
|
||||
* for the given route, if the route of the persistent connection does
|
||||
* not match that of the connection request. If the connection has been
|
||||
* already been allocated {@link IllegalStateException} is thrown.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) use {@link BasicClientConnectionManager}
|
||||
*/
|
||||
@ThreadSafe
|
||||
@Deprecated
|
||||
public class SingleClientConnManager implements ClientConnectionManager {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
/** The message to be logged on multiple allocation. */
|
||||
public final static String MISUSE_MESSAGE =
|
||||
"Invalid use of SingleClientConnManager: connection still allocated.\n" +
|
||||
"Make sure to release the connection before allocating another one.";
|
||||
|
||||
/** The schemes supported by this connection manager. */
|
||||
protected final SchemeRegistry schemeRegistry;
|
||||
|
||||
/** The operator for opening and updating connections. */
|
||||
protected final ClientConnectionOperator connOperator;
|
||||
|
||||
/** Whether the connection should be shut down on release. */
|
||||
protected final boolean alwaysShutDown;
|
||||
|
||||
/** The one and only entry in this pool. */
|
||||
@GuardedBy("this")
|
||||
protected volatile PoolEntry uniquePoolEntry;
|
||||
|
||||
/** The currently issued managed connection, if any. */
|
||||
@GuardedBy("this")
|
||||
protected volatile ConnAdapter managedConn;
|
||||
|
||||
/** The time of the last connection release, or -1. */
|
||||
@GuardedBy("this")
|
||||
protected volatile long lastReleaseTime;
|
||||
|
||||
/** The time the last released connection expires and shouldn't be reused. */
|
||||
@GuardedBy("this")
|
||||
protected volatile long connectionExpiresTime;
|
||||
|
||||
/** Indicates whether this connection manager is shut down. */
|
||||
protected volatile boolean isShutDown;
|
||||
|
||||
/**
|
||||
* Creates a new simple connection manager.
|
||||
*
|
||||
* @param params the parameters for this manager
|
||||
* @param schreg the scheme registry
|
||||
*
|
||||
* @deprecated (4.1) use {@link SingleClientConnManager#SingleClientConnManager(SchemeRegistry)}
|
||||
*/
|
||||
@Deprecated
|
||||
public SingleClientConnManager(final HttpParams params,
|
||||
final SchemeRegistry schreg) {
|
||||
this(schreg);
|
||||
}
|
||||
/**
|
||||
* Creates a new simple connection manager.
|
||||
*
|
||||
* @param schreg the scheme registry
|
||||
*/
|
||||
public SingleClientConnManager(final SchemeRegistry schreg) {
|
||||
Args.notNull(schreg, "Scheme registry");
|
||||
this.schemeRegistry = schreg;
|
||||
this.connOperator = createConnectionOperator(schreg);
|
||||
this.uniquePoolEntry = new PoolEntry();
|
||||
this.managedConn = null;
|
||||
this.lastReleaseTime = -1L;
|
||||
this.alwaysShutDown = false; //@@@ from params? as argument?
|
||||
this.isShutDown = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public SingleClientConnManager() {
|
||||
this(SchemeRegistryFactory.createDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
shutdown();
|
||||
} finally { // Make sure we call overridden method even if shutdown barfs
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
public SchemeRegistry getSchemeRegistry() {
|
||||
return this.schemeRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for creating the connection operator.
|
||||
* It is called by the constructor.
|
||||
* Derived classes can override this method to change the
|
||||
* instantiation of the operator.
|
||||
* The default implementation here instantiates
|
||||
* {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}.
|
||||
*
|
||||
* @param schreg the scheme registry to use, or <code>null</code>
|
||||
*
|
||||
* @return the connection operator to use
|
||||
*/
|
||||
protected ClientConnectionOperator
|
||||
createConnectionOperator(final SchemeRegistry schreg) {
|
||||
return new DefaultClientConnectionOperator(schreg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that this manager is not shut down.
|
||||
*
|
||||
* @throws IllegalStateException if this manager is shut down
|
||||
*/
|
||||
protected final void assertStillUp() throws IllegalStateException {
|
||||
Asserts.check(!this.isShutDown, "Manager is shut down");
|
||||
}
|
||||
|
||||
public final ClientConnectionRequest requestConnection(
|
||||
final HttpRoute route,
|
||||
final Object state) {
|
||||
|
||||
return new ClientConnectionRequest() {
|
||||
|
||||
public void abortRequest() {
|
||||
// Nothing to abort, since requests are immediate.
|
||||
}
|
||||
|
||||
public ManagedClientConnection getConnection(
|
||||
final long timeout, final TimeUnit tunit) {
|
||||
return SingleClientConnManager.this.getConnection(
|
||||
route, state);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a connection.
|
||||
*
|
||||
* @param route where the connection should point to
|
||||
*
|
||||
* @return a connection that can be used to communicate
|
||||
* along the given route
|
||||
*/
|
||||
public ManagedClientConnection getConnection(final HttpRoute route, final Object state) {
|
||||
Args.notNull(route, "Route");
|
||||
assertStillUp();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Get connection for route " + route);
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
|
||||
Asserts.check(managedConn == null, MISUSE_MESSAGE);
|
||||
|
||||
// check re-usability of the connection
|
||||
boolean recreate = false;
|
||||
boolean shutdown = false;
|
||||
|
||||
// Kill the connection if it expired.
|
||||
closeExpiredConnections();
|
||||
|
||||
if (uniquePoolEntry.connection.isOpen()) {
|
||||
final RouteTracker tracker = uniquePoolEntry.tracker;
|
||||
shutdown = (tracker == null || // can happen if method is aborted
|
||||
!tracker.toRoute().equals(route));
|
||||
} else {
|
||||
// If the connection is not open, create a new PoolEntry,
|
||||
// as the connection may have been marked not reusable,
|
||||
// due to aborts -- and the PoolEntry should not be reused
|
||||
// either. There's no harm in recreating an entry if
|
||||
// the connection is closed.
|
||||
recreate = true;
|
||||
}
|
||||
|
||||
if (shutdown) {
|
||||
recreate = true;
|
||||
try {
|
||||
uniquePoolEntry.shutdown();
|
||||
} catch (final IOException iox) {
|
||||
log.debug("Problem shutting down connection.", iox);
|
||||
}
|
||||
}
|
||||
|
||||
if (recreate) {
|
||||
uniquePoolEntry = new PoolEntry();
|
||||
}
|
||||
|
||||
managedConn = new ConnAdapter(uniquePoolEntry, route);
|
||||
|
||||
return managedConn;
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseConnection(
|
||||
final ManagedClientConnection conn,
|
||||
final long validDuration, final TimeUnit timeUnit) {
|
||||
Args.check(conn instanceof ConnAdapter, "Connection class mismatch, " +
|
||||
"connection not obtained from this manager");
|
||||
assertStillUp();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Releasing connection " + conn);
|
||||
}
|
||||
|
||||
final ConnAdapter sca = (ConnAdapter) conn;
|
||||
synchronized (sca) {
|
||||
if (sca.poolEntry == null)
|
||||
{
|
||||
return; // already released
|
||||
}
|
||||
final ClientConnectionManager manager = sca.getManager();
|
||||
Asserts.check(manager == this, "Connection not obtained from this manager");
|
||||
try {
|
||||
// make sure that the response has been read completely
|
||||
if (sca.isOpen() && (this.alwaysShutDown ||
|
||||
!sca.isMarkedReusable())
|
||||
) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug
|
||||
("Released connection open but not reusable.");
|
||||
}
|
||||
|
||||
// make sure this connection will not be re-used
|
||||
// we might have gotten here because of a shutdown trigger
|
||||
// shutdown of the adapter also clears the tracked route
|
||||
sca.shutdown();
|
||||
}
|
||||
} catch (final IOException iox) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Exception shutting down released connection.",
|
||||
iox);
|
||||
}
|
||||
} finally {
|
||||
sca.detach();
|
||||
synchronized (this) {
|
||||
managedConn = null;
|
||||
lastReleaseTime = System.currentTimeMillis();
|
||||
if(validDuration > 0) {
|
||||
connectionExpiresTime = timeUnit.toMillis(validDuration) + lastReleaseTime;
|
||||
} else {
|
||||
connectionExpiresTime = Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeExpiredConnections() {
|
||||
final long time = connectionExpiresTime;
|
||||
if (System.currentTimeMillis() >= time) {
|
||||
closeIdleConnections(0, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeIdleConnections(final long idletime, final TimeUnit tunit) {
|
||||
assertStillUp();
|
||||
|
||||
// idletime can be 0 or negative, no problem there
|
||||
Args.notNull(tunit, "Time unit");
|
||||
|
||||
synchronized (this) {
|
||||
if ((managedConn == null) && uniquePoolEntry.connection.isOpen()) {
|
||||
final long cutoff =
|
||||
System.currentTimeMillis() - tunit.toMillis(idletime);
|
||||
if (lastReleaseTime <= cutoff) {
|
||||
try {
|
||||
uniquePoolEntry.close();
|
||||
} catch (final IOException iox) {
|
||||
// ignore
|
||||
log.debug("Problem closing idle connection.", iox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
this.isShutDown = true;
|
||||
synchronized (this) {
|
||||
try {
|
||||
if (uniquePoolEntry != null) {
|
||||
uniquePoolEntry.shutdown();
|
||||
}
|
||||
} catch (final IOException iox) {
|
||||
// ignore
|
||||
log.debug("Problem while shutting down manager.", iox);
|
||||
} finally {
|
||||
uniquePoolEntry = null;
|
||||
managedConn = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void revokeConnection() {
|
||||
final ConnAdapter conn = managedConn;
|
||||
if (conn == null) {
|
||||
return;
|
||||
}
|
||||
conn.detach();
|
||||
|
||||
synchronized (this) {
|
||||
try {
|
||||
uniquePoolEntry.shutdown();
|
||||
} catch (final IOException iox) {
|
||||
// ignore
|
||||
log.debug("Problem while shutting down connection.", iox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The pool entry for this connection manager.
|
||||
*/
|
||||
protected class PoolEntry extends AbstractPoolEntry {
|
||||
|
||||
/**
|
||||
* Creates a new pool entry.
|
||||
*
|
||||
*/
|
||||
protected PoolEntry() {
|
||||
super(SingleClientConnManager.this.connOperator, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection in this pool entry.
|
||||
*/
|
||||
protected void close() throws IOException {
|
||||
shutdownEntry();
|
||||
if (connection.isOpen()) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the connection in this pool entry.
|
||||
*/
|
||||
protected void shutdown() throws IOException {
|
||||
shutdownEntry();
|
||||
if (connection.isOpen()) {
|
||||
connection.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The connection adapter used by this manager.
|
||||
*/
|
||||
protected class ConnAdapter extends AbstractPooledConnAdapter {
|
||||
|
||||
/**
|
||||
* Creates a new connection adapter.
|
||||
*
|
||||
* @param entry the pool entry for the connection being wrapped
|
||||
* @param route the planned route for this connection
|
||||
*/
|
||||
protected ConnAdapter(final PoolEntry entry, final HttpRoute route) {
|
||||
super(SingleClientConnManager.this, entry);
|
||||
markReusable();
|
||||
entry.route = route;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
47
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SystemDefaultDnsResolver.java
vendored
Normal file
47
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SystemDefaultDnsResolver.java
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import ch.boye.httpclientandroidlib.conn.DnsResolver;
|
||||
|
||||
/**
|
||||
* DNS resolver that uses the default OS implementation for resolving host names.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public class SystemDefaultDnsResolver implements DnsResolver {
|
||||
|
||||
public static final SystemDefaultDnsResolver INSTANCE = new SystemDefaultDnsResolver();
|
||||
|
||||
public InetAddress[] resolve(final String host) throws UnknownHostException {
|
||||
return InetAddress.getAllByName(host);
|
||||
}
|
||||
|
||||
}
|
||||
132
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SystemDefaultRoutePlanner.java
vendored
Normal file
132
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/SystemDefaultRoutePlanner.java
vendored
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
|
||||
import ch.boye.httpclientandroidlib.HttpException;
|
||||
import ch.boye.httpclientandroidlib.HttpHost;
|
||||
import ch.boye.httpclientandroidlib.HttpRequest;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.conn.SchemePortResolver;
|
||||
import ch.boye.httpclientandroidlib.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
* {@link ch.boye.httpclientandroidlib.conn.routing.HttpRoutePlanner} implementation
|
||||
* based on {@link ProxySelector}. By default, this class will pick up
|
||||
* the proxy settings of the JVM, either from system properties
|
||||
* or from the browser running the application.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@Immutable
|
||||
public class SystemDefaultRoutePlanner extends DefaultRoutePlanner {
|
||||
|
||||
private final ProxySelector proxySelector;
|
||||
|
||||
public SystemDefaultRoutePlanner(
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final ProxySelector proxySelector) {
|
||||
super(schemePortResolver);
|
||||
this.proxySelector = proxySelector != null ? proxySelector : ProxySelector.getDefault();
|
||||
}
|
||||
|
||||
public SystemDefaultRoutePlanner(final ProxySelector proxySelector) {
|
||||
this(null, proxySelector);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpHost determineProxy(
|
||||
final HttpHost target,
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws HttpException {
|
||||
final URI targetURI;
|
||||
try {
|
||||
targetURI = new URI(target.toURI());
|
||||
} catch (final URISyntaxException ex) {
|
||||
throw new HttpException("Cannot convert host to URI: " + target, ex);
|
||||
}
|
||||
final List<Proxy> proxies = this.proxySelector.select(targetURI);
|
||||
final Proxy p = chooseProxy(proxies);
|
||||
HttpHost result = null;
|
||||
if (p.type() == Proxy.Type.HTTP) {
|
||||
// convert the socket address to an HttpHost
|
||||
if (!(p.address() instanceof InetSocketAddress)) {
|
||||
throw new HttpException("Unable to handle non-Inet proxy address: " + p.address());
|
||||
}
|
||||
final InetSocketAddress isa = (InetSocketAddress) p.address();
|
||||
// assume default scheme (http)
|
||||
result = new HttpHost(getHost(isa), isa.getPort());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getHost(final InetSocketAddress isa) {
|
||||
|
||||
//@@@ Will this work with literal IPv6 addresses, or do we
|
||||
//@@@ need to wrap these in [] for the string representation?
|
||||
//@@@ Having it in this method at least allows for easy workarounds.
|
||||
return isa.isUnresolved() ?
|
||||
isa.getHostName() : isa.getAddress().getHostAddress();
|
||||
|
||||
}
|
||||
|
||||
private Proxy chooseProxy(final List<Proxy> proxies) {
|
||||
Proxy result = null;
|
||||
// check the list for one we can use
|
||||
for (int i=0; (result == null) && (i < proxies.size()); i++) {
|
||||
final Proxy p = proxies.get(i);
|
||||
switch (p.type()) {
|
||||
|
||||
case DIRECT:
|
||||
case HTTP:
|
||||
result = p;
|
||||
break;
|
||||
|
||||
case SOCKS:
|
||||
// SOCKS hosts are not handled on the route level.
|
||||
// The socket may make use of the SOCKS host though.
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
//@@@ log as warning or info that only a socks proxy is available?
|
||||
// result can only be null if all proxies are socks proxies
|
||||
// socks proxies are not handled on the route planning level
|
||||
result = Proxy.NO_PROXY;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
152
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/Wire.java
vendored
Normal file
152
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/Wire.java
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
import ch.boye.httpclientandroidlib.annotation.Immutable;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* Logs data to the wire LOG.
|
||||
* TODO: make package private. Should not be part of the public API.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
@Immutable
|
||||
public class Wire {
|
||||
|
||||
public HttpClientAndroidLog log;
|
||||
private final String id;
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public Wire(final HttpClientAndroidLog log, final String id) {
|
||||
this.log = log;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Wire(final HttpClientAndroidLog log) {
|
||||
this(log, "");
|
||||
}
|
||||
|
||||
private void wire(final String header, final InputStream instream)
|
||||
throws IOException {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
int ch;
|
||||
while ((ch = instream.read()) != -1) {
|
||||
if (ch == 13) {
|
||||
buffer.append("[\\r]");
|
||||
} else if (ch == 10) {
|
||||
buffer.append("[\\n]\"");
|
||||
buffer.insert(0, "\"");
|
||||
buffer.insert(0, header);
|
||||
log.debug(id + " " + buffer.toString());
|
||||
buffer.setLength(0);
|
||||
} else if ((ch < 32) || (ch > 127)) {
|
||||
buffer.append("[0x");
|
||||
buffer.append(Integer.toHexString(ch));
|
||||
buffer.append("]");
|
||||
} else {
|
||||
buffer.append((char) ch);
|
||||
}
|
||||
}
|
||||
if (buffer.length() > 0) {
|
||||
buffer.append('\"');
|
||||
buffer.insert(0, '\"');
|
||||
buffer.insert(0, header);
|
||||
log.debug(id + " " + buffer.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean enabled() {
|
||||
return log.isDebugEnabled();
|
||||
}
|
||||
|
||||
public void output(final InputStream outstream)
|
||||
throws IOException {
|
||||
Args.notNull(outstream, "Output");
|
||||
wire(">> ", outstream);
|
||||
}
|
||||
|
||||
public void input(final InputStream instream)
|
||||
throws IOException {
|
||||
Args.notNull(instream, "Input");
|
||||
wire("<< ", instream);
|
||||
}
|
||||
|
||||
public void output(final byte[] b, final int off, final int len)
|
||||
throws IOException {
|
||||
Args.notNull(b, "Output");
|
||||
wire(">> ", new ByteArrayInputStream(b, off, len));
|
||||
}
|
||||
|
||||
public void input(final byte[] b, final int off, final int len)
|
||||
throws IOException {
|
||||
Args.notNull(b, "Input");
|
||||
wire("<< ", new ByteArrayInputStream(b, off, len));
|
||||
}
|
||||
|
||||
public void output(final byte[] b)
|
||||
throws IOException {
|
||||
Args.notNull(b, "Output");
|
||||
wire(">> ", new ByteArrayInputStream(b));
|
||||
}
|
||||
|
||||
public void input(final byte[] b)
|
||||
throws IOException {
|
||||
Args.notNull(b, "Input");
|
||||
wire("<< ", new ByteArrayInputStream(b));
|
||||
}
|
||||
|
||||
public void output(final int b)
|
||||
throws IOException {
|
||||
output(new byte[] {(byte) b});
|
||||
}
|
||||
|
||||
public void input(final int b)
|
||||
throws IOException {
|
||||
input(new byte[] {(byte) b});
|
||||
}
|
||||
|
||||
public void output(final String s)
|
||||
throws IOException {
|
||||
Args.notNull(s, "Output");
|
||||
output(s.getBytes());
|
||||
}
|
||||
|
||||
public void input(final String s)
|
||||
throws IOException {
|
||||
Args.notNull(s, "Input");
|
||||
input(s.getBytes());
|
||||
}
|
||||
}
|
||||
32
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/package-info.java
vendored
Normal file
32
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/package-info.java
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default implementations of client connection management
|
||||
* functions.
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn;
|
||||
234
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/AbstractConnPool.java
vendored
Normal file
234
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/AbstractConnPool.java
vendored
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.annotation.GuardedBy;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectionPoolTimeoutException;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.impl.conn.IdleConnectionHandler;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* An abstract connection pool.
|
||||
* It is used by the {@link ThreadSafeClientConnManager}.
|
||||
* The abstract pool includes a {@link #poolLock}, which is used to
|
||||
* synchronize access to the internal pool datastructures.
|
||||
* Don't use <code>synchronized</code> for that purpose!
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) use {@link ch.boye.httpclientandroidlib.pool.AbstractConnPool}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractConnPool {
|
||||
|
||||
public HttpClientAndroidLog log;
|
||||
|
||||
/**
|
||||
* The global lock for this pool.
|
||||
*/
|
||||
protected final Lock poolLock;
|
||||
|
||||
/** References to issued connections */
|
||||
@GuardedBy("poolLock")
|
||||
protected Set<BasicPoolEntry> leasedConnections;
|
||||
|
||||
/** The current total number of connections. */
|
||||
@GuardedBy("poolLock")
|
||||
protected int numConnections;
|
||||
|
||||
/** Indicates whether this pool is shut down. */
|
||||
protected volatile boolean isShutDown;
|
||||
|
||||
protected Set<BasicPoolEntryRef> issuedConnections;
|
||||
|
||||
protected ReferenceQueue<Object> refQueue;
|
||||
|
||||
protected IdleConnectionHandler idleConnHandler;
|
||||
|
||||
/**
|
||||
* Creates a new connection pool.
|
||||
*/
|
||||
protected AbstractConnPool() {
|
||||
super();
|
||||
this.log = new HttpClientAndroidLog(getClass());
|
||||
this.leasedConnections = new HashSet<BasicPoolEntry>();
|
||||
this.idleConnHandler = new IdleConnectionHandler();
|
||||
this.poolLock = new ReentrantLock();
|
||||
}
|
||||
|
||||
public void enableConnectionGC()
|
||||
throws IllegalStateException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a pool entry with a connection within the given timeout.
|
||||
*
|
||||
* @param route the route for which to get the connection
|
||||
* @param timeout the timeout, 0 or negative for no timeout
|
||||
* @param tunit the unit for the <code>timeout</code>,
|
||||
* may be <code>null</code> only if there is no timeout
|
||||
*
|
||||
* @return pool entry holding a connection for the route
|
||||
*
|
||||
* @throws ConnectionPoolTimeoutException
|
||||
* if the timeout expired
|
||||
* @throws InterruptedException
|
||||
* if the calling thread was interrupted
|
||||
*/
|
||||
public final
|
||||
BasicPoolEntry getEntry(
|
||||
final HttpRoute route,
|
||||
final Object state,
|
||||
final long timeout,
|
||||
final TimeUnit tunit)
|
||||
throws ConnectionPoolTimeoutException, InterruptedException {
|
||||
return requestPoolEntry(route, state).getPoolEntry(timeout, tunit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry}
|
||||
* can be obtained, or the request can be aborted.
|
||||
*/
|
||||
public abstract PoolEntryRequest requestPoolEntry(HttpRoute route, Object state);
|
||||
|
||||
|
||||
/**
|
||||
* Returns an entry into the pool.
|
||||
* The connection of the entry is expected to be in a suitable state,
|
||||
* either open and re-usable, or closed. The pool will not make any
|
||||
* attempt to determine whether it can be re-used or not.
|
||||
*
|
||||
* @param entry the entry for the connection to release
|
||||
* @param reusable <code>true</code> if the entry is deemed
|
||||
* reusable, <code>false</code> otherwise.
|
||||
* @param validDuration The duration that the entry should remain free and reusable.
|
||||
* @param timeUnit The unit of time the duration is measured in.
|
||||
*/
|
||||
public abstract void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit)
|
||||
;
|
||||
|
||||
public void handleReference(final Reference<?> ref) {
|
||||
}
|
||||
|
||||
protected abstract void handleLostEntry(HttpRoute route);
|
||||
|
||||
/**
|
||||
* Closes idle connections.
|
||||
*
|
||||
* @param idletime the time the connections should have been idle
|
||||
* in order to be closed now
|
||||
* @param tunit the unit for the <code>idletime</code>
|
||||
*/
|
||||
public void closeIdleConnections(final long idletime, final TimeUnit tunit) {
|
||||
|
||||
// idletime can be 0 or negative, no problem there
|
||||
Args.notNull(tunit, "Time unit");
|
||||
|
||||
poolLock.lock();
|
||||
try {
|
||||
idleConnHandler.closeIdleConnections(tunit.toMillis(idletime));
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void closeExpiredConnections() {
|
||||
poolLock.lock();
|
||||
try {
|
||||
idleConnHandler.closeExpiredConnections();
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes all entries for closed connections.
|
||||
*/
|
||||
public abstract void deleteClosedConnections();
|
||||
|
||||
/**
|
||||
* Shuts down this pool and all associated resources.
|
||||
* Overriding methods MUST call the implementation here!
|
||||
*/
|
||||
public void shutdown() {
|
||||
|
||||
poolLock.lock();
|
||||
try {
|
||||
|
||||
if (isShutDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
// close all connections that are issued to an application
|
||||
final Iterator<BasicPoolEntry> iter = leasedConnections.iterator();
|
||||
while (iter.hasNext()) {
|
||||
final BasicPoolEntry entry = iter.next();
|
||||
iter.remove();
|
||||
closeConnection(entry.getConnection());
|
||||
}
|
||||
idleConnHandler.removeAll();
|
||||
|
||||
isShutDown = true;
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes a connection from this pool.
|
||||
*
|
||||
* @param conn the connection to close, or <code>null</code>
|
||||
*/
|
||||
protected void closeConnection(final OperatedClientConnection conn) {
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (final IOException ex) {
|
||||
log.debug("I/O error closing connection", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // class AbstractConnPool
|
||||
|
||||
163
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/BasicPoolEntry.java
vendored
Normal file
163
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/BasicPoolEntry.java
vendored
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.impl.conn.AbstractPoolEntry;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* Basic implementation of a connection pool entry.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) use {@link ch.boye.httpclientandroidlib.pool.PoolEntry}
|
||||
*/
|
||||
@Deprecated
|
||||
public class BasicPoolEntry extends AbstractPoolEntry {
|
||||
|
||||
private final long created;
|
||||
|
||||
private long updated;
|
||||
private final long validUntil;
|
||||
private long expiry;
|
||||
|
||||
public BasicPoolEntry(final ClientConnectionOperator op,
|
||||
final HttpRoute route,
|
||||
final ReferenceQueue<Object> queue) {
|
||||
super(op, route);
|
||||
Args.notNull(route, "HTTP route");
|
||||
this.created = System.currentTimeMillis();
|
||||
this.validUntil = Long.MAX_VALUE;
|
||||
this.expiry = this.validUntil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new pool entry.
|
||||
*
|
||||
* @param op the connection operator
|
||||
* @param route the planned route for the connection
|
||||
*/
|
||||
public BasicPoolEntry(final ClientConnectionOperator op,
|
||||
final HttpRoute route) {
|
||||
this(op, route, -1, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new pool entry with a specified maximum lifetime.
|
||||
*
|
||||
* @param op the connection operator
|
||||
* @param route the planned route for the connection
|
||||
* @param connTTL maximum lifetime of this entry, <=0 implies "infinity"
|
||||
* @param timeunit TimeUnit of connTTL
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public BasicPoolEntry(final ClientConnectionOperator op,
|
||||
final HttpRoute route, final long connTTL, final TimeUnit timeunit) {
|
||||
super(op, route);
|
||||
Args.notNull(route, "HTTP route");
|
||||
this.created = System.currentTimeMillis();
|
||||
if (connTTL > 0) {
|
||||
this.validUntil = this.created + timeunit.toMillis(connTTL);
|
||||
} else {
|
||||
this.validUntil = Long.MAX_VALUE;
|
||||
}
|
||||
this.expiry = this.validUntil;
|
||||
}
|
||||
|
||||
protected final OperatedClientConnection getConnection() {
|
||||
return super.connection;
|
||||
}
|
||||
|
||||
protected final HttpRoute getPlannedRoute() {
|
||||
return super.route;
|
||||
}
|
||||
|
||||
protected final BasicPoolEntryRef getWeakRef() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutdownEntry() {
|
||||
super.shutdownEntry();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public long getCreated() {
|
||||
return this.created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public long getUpdated() {
|
||||
return this.updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public long getExpiry() {
|
||||
return this.expiry;
|
||||
}
|
||||
|
||||
public long getValidUntil() {
|
||||
return this.validUntil;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public void updateExpiry(final long time, final TimeUnit timeunit) {
|
||||
this.updated = System.currentTimeMillis();
|
||||
final long newExpiry;
|
||||
if (time > 0) {
|
||||
newExpiry = this.updated + timeunit.toMillis(time);
|
||||
} else {
|
||||
newExpiry = Long.MAX_VALUE;
|
||||
}
|
||||
this.expiry = Math.min(validUntil, newExpiry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public boolean isExpired(final long now) {
|
||||
return now >= this.expiry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
76
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/BasicPoolEntryRef.java
vendored
Normal file
76
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/BasicPoolEntryRef.java
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* A weak reference to a {@link BasicPoolEntry BasicPoolEntry}.
|
||||
* This reference explicitly keeps the planned route, so the connection
|
||||
* can be reclaimed if it is lost to garbage collection.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) do not use
|
||||
*/
|
||||
@Deprecated
|
||||
public class BasicPoolEntryRef extends WeakReference<BasicPoolEntry> {
|
||||
|
||||
/** The planned route of the entry. */
|
||||
private final HttpRoute route; // HttpRoute is @Immutable
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new reference to a pool entry.
|
||||
*
|
||||
* @param entry the pool entry, must not be <code>null</code>
|
||||
* @param queue the reference queue, or <code>null</code>
|
||||
*/
|
||||
public BasicPoolEntryRef(final BasicPoolEntry entry,
|
||||
final ReferenceQueue<Object> queue) {
|
||||
super(entry, queue);
|
||||
Args.notNull(entry, "Pool entry");
|
||||
route = entry.getPlannedRoute();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the planned route for the referenced entry.
|
||||
* The planned route is still available, even if the entry is gone.
|
||||
*
|
||||
* @return the planned route
|
||||
*/
|
||||
public final HttpRoute getRoute() {
|
||||
return this.route;
|
||||
}
|
||||
|
||||
} // class BasicPoolEntryRef
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.impl.conn.AbstractPoolEntry;
|
||||
import ch.boye.httpclientandroidlib.impl.conn.AbstractPooledConnAdapter;
|
||||
|
||||
/**
|
||||
* A connection wrapper and callback handler.
|
||||
* All connections given out by the manager are wrappers which
|
||||
* can be {@link #detach detach}ed to prevent further use on release.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) do not use
|
||||
*/
|
||||
@Deprecated
|
||||
public class BasicPooledConnAdapter extends AbstractPooledConnAdapter {
|
||||
|
||||
/**
|
||||
* Creates a new adapter.
|
||||
*
|
||||
* @param tsccm the connection manager
|
||||
* @param entry the pool entry for the connection being wrapped
|
||||
*/
|
||||
protected BasicPooledConnAdapter(final ThreadSafeClientConnManager tsccm,
|
||||
final AbstractPoolEntry entry) {
|
||||
super(tsccm, entry);
|
||||
markReusable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClientConnectionManager getManager() {
|
||||
// override needed only to make method visible in this package
|
||||
return super.getManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractPoolEntry getPoolEntry() {
|
||||
// override needed only to make method visible in this package
|
||||
return super.getPoolEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void detach() {
|
||||
// override needed only to make method visible in this package
|
||||
super.detach();
|
||||
}
|
||||
|
||||
}
|
||||
829
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/ConnPoolByRoute.java
vendored
Normal file
829
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/ConnPoolByRoute.java
vendored
Normal file
|
|
@ -0,0 +1,829 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectionPoolTimeoutException;
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.params.ConnManagerParams;
|
||||
import ch.boye.httpclientandroidlib.conn.params.ConnPerRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* A connection pool that maintains connections by route.
|
||||
* This class is derived from <code>MultiThreadedHttpConnectionManager</code>
|
||||
* in HttpClient 3.x, see there for original authors. It implements the same
|
||||
* algorithm for connection re-use and connection-per-host enforcement:
|
||||
* <ul>
|
||||
* <li>connections are re-used only for the exact same route</li>
|
||||
* <li>connection limits are enforced per route rather than per host</li>
|
||||
* </ul>
|
||||
* Note that access to the pool data structures is synchronized via the
|
||||
* {@link AbstractConnPool#poolLock poolLock} in the base class,
|
||||
* not via <code>synchronized</code> methods.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) use {@link ch.boye.httpclientandroidlib.pool.AbstractConnPool}
|
||||
*/
|
||||
@Deprecated
|
||||
public class ConnPoolByRoute extends AbstractConnPool {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
private final Lock poolLock;
|
||||
|
||||
/** Connection operator for this pool */
|
||||
protected final ClientConnectionOperator operator;
|
||||
|
||||
/** Connections per route lookup */
|
||||
protected final ConnPerRoute connPerRoute;
|
||||
|
||||
/** References to issued connections */
|
||||
protected final Set<BasicPoolEntry> leasedConnections;
|
||||
|
||||
/** The list of free connections */
|
||||
protected final Queue<BasicPoolEntry> freeConnections;
|
||||
|
||||
/** The list of WaitingThreads waiting for a connection */
|
||||
protected final Queue<WaitingThread> waitingThreads;
|
||||
|
||||
/** Map of route-specific pools */
|
||||
protected final Map<HttpRoute, RouteSpecificPool> routeToPool;
|
||||
|
||||
private final long connTTL;
|
||||
|
||||
private final TimeUnit connTTLTimeUnit;
|
||||
|
||||
protected volatile boolean shutdown;
|
||||
|
||||
protected volatile int maxTotalConnections;
|
||||
|
||||
protected volatile int numConnections;
|
||||
|
||||
/**
|
||||
* Creates a new connection pool, managed by route.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public ConnPoolByRoute(
|
||||
final ClientConnectionOperator operator,
|
||||
final ConnPerRoute connPerRoute,
|
||||
final int maxTotalConnections) {
|
||||
this(operator, connPerRoute, maxTotalConnections, -1, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public ConnPoolByRoute(
|
||||
final ClientConnectionOperator operator,
|
||||
final ConnPerRoute connPerRoute,
|
||||
final int maxTotalConnections,
|
||||
final long connTTL,
|
||||
final TimeUnit connTTLTimeUnit) {
|
||||
super();
|
||||
Args.notNull(operator, "Connection operator");
|
||||
Args.notNull(connPerRoute, "Connections per route");
|
||||
this.poolLock = super.poolLock;
|
||||
this.leasedConnections = super.leasedConnections;
|
||||
this.operator = operator;
|
||||
this.connPerRoute = connPerRoute;
|
||||
this.maxTotalConnections = maxTotalConnections;
|
||||
this.freeConnections = createFreeConnQueue();
|
||||
this.waitingThreads = createWaitingThreadQueue();
|
||||
this.routeToPool = createRouteToPoolMap();
|
||||
this.connTTL = connTTL;
|
||||
this.connTTLTimeUnit = connTTLTimeUnit;
|
||||
}
|
||||
|
||||
protected Lock getLock() {
|
||||
return this.poolLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection pool, managed by route.
|
||||
*
|
||||
* @deprecated (4.1) use {@link ConnPoolByRoute#ConnPoolByRoute(ClientConnectionOperator, ConnPerRoute, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ConnPoolByRoute(final ClientConnectionOperator operator, final HttpParams params) {
|
||||
this(operator,
|
||||
ConnManagerParams.getMaxConnectionsPerRoute(params),
|
||||
ConnManagerParams.getMaxTotalConnections(params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the queue for {@link #freeConnections}.
|
||||
* Called once by the constructor.
|
||||
*
|
||||
* @return a queue
|
||||
*/
|
||||
protected Queue<BasicPoolEntry> createFreeConnQueue() {
|
||||
return new LinkedList<BasicPoolEntry>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the queue for {@link #waitingThreads}.
|
||||
* Called once by the constructor.
|
||||
*
|
||||
* @return a queue
|
||||
*/
|
||||
protected Queue<WaitingThread> createWaitingThreadQueue() {
|
||||
return new LinkedList<WaitingThread>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the map for {@link #routeToPool}.
|
||||
* Called once by the constructor.
|
||||
*
|
||||
* @return a map
|
||||
*/
|
||||
protected Map<HttpRoute, RouteSpecificPool> createRouteToPoolMap() {
|
||||
return new HashMap<HttpRoute, RouteSpecificPool>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new route-specific pool.
|
||||
* Called by {@link #getRoutePool} when necessary.
|
||||
*
|
||||
* @param route the route
|
||||
*
|
||||
* @return the new pool
|
||||
*/
|
||||
protected RouteSpecificPool newRouteSpecificPool(final HttpRoute route) {
|
||||
return new RouteSpecificPool(route, this.connPerRoute);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new waiting thread.
|
||||
* Called by {@link #getRoutePool} when necessary.
|
||||
*
|
||||
* @param cond the condition to wait for
|
||||
* @param rospl the route specific pool, or <code>null</code>
|
||||
*
|
||||
* @return a waiting thread representation
|
||||
*/
|
||||
protected WaitingThread newWaitingThread(final Condition cond,
|
||||
final RouteSpecificPool rospl) {
|
||||
return new WaitingThread(cond, rospl);
|
||||
}
|
||||
|
||||
private void closeConnection(final BasicPoolEntry entry) {
|
||||
final OperatedClientConnection conn = entry.getConnection();
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (final IOException ex) {
|
||||
log.debug("I/O error closing connection", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a route-specific pool of available connections.
|
||||
*
|
||||
* @param route the route
|
||||
* @param create whether to create the pool if it doesn't exist
|
||||
*
|
||||
* @return the pool for the argument route,
|
||||
* never <code>null</code> if <code>create</code> is <code>true</code>
|
||||
*/
|
||||
protected RouteSpecificPool getRoutePool(final HttpRoute route,
|
||||
final boolean create) {
|
||||
RouteSpecificPool rospl = null;
|
||||
poolLock.lock();
|
||||
try {
|
||||
|
||||
rospl = routeToPool.get(route);
|
||||
if ((rospl == null) && create) {
|
||||
// no pool for this route yet (or anymore)
|
||||
rospl = newRouteSpecificPool(route);
|
||||
routeToPool.put(route, rospl);
|
||||
}
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
|
||||
return rospl;
|
||||
}
|
||||
|
||||
public int getConnectionsInPool(final HttpRoute route) {
|
||||
poolLock.lock();
|
||||
try {
|
||||
// don't allow a pool to be created here!
|
||||
final RouteSpecificPool rospl = getRoutePool(route, false);
|
||||
return (rospl != null) ? rospl.getEntryCount() : 0;
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getConnectionsInPool() {
|
||||
poolLock.lock();
|
||||
try {
|
||||
return numConnections;
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PoolEntryRequest requestPoolEntry(
|
||||
final HttpRoute route,
|
||||
final Object state) {
|
||||
|
||||
final WaitingThreadAborter aborter = new WaitingThreadAborter();
|
||||
|
||||
return new PoolEntryRequest() {
|
||||
|
||||
public void abortRequest() {
|
||||
poolLock.lock();
|
||||
try {
|
||||
aborter.abort();
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public BasicPoolEntry getPoolEntry(
|
||||
final long timeout,
|
||||
final TimeUnit tunit)
|
||||
throws InterruptedException, ConnectionPoolTimeoutException {
|
||||
return getEntryBlocking(route, state, timeout, tunit, aborter);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a pool entry with a connection within the given timeout.
|
||||
* If a {@link WaitingThread} is used to block, {@link WaitingThreadAborter#setWaitingThread(WaitingThread)}
|
||||
* must be called before blocking, to allow the thread to be interrupted.
|
||||
*
|
||||
* @param route the route for which to get the connection
|
||||
* @param timeout the timeout, 0 or negative for no timeout
|
||||
* @param tunit the unit for the <code>timeout</code>,
|
||||
* may be <code>null</code> only if there is no timeout
|
||||
* @param aborter an object which can abort a {@link WaitingThread}.
|
||||
*
|
||||
* @return pool entry holding a connection for the route
|
||||
*
|
||||
* @throws ConnectionPoolTimeoutException
|
||||
* if the timeout expired
|
||||
* @throws InterruptedException
|
||||
* if the calling thread was interrupted
|
||||
*/
|
||||
protected BasicPoolEntry getEntryBlocking(
|
||||
final HttpRoute route, final Object state,
|
||||
final long timeout, final TimeUnit tunit,
|
||||
final WaitingThreadAborter aborter)
|
||||
throws ConnectionPoolTimeoutException, InterruptedException {
|
||||
|
||||
Date deadline = null;
|
||||
if (timeout > 0) {
|
||||
deadline = new Date
|
||||
(System.currentTimeMillis() + tunit.toMillis(timeout));
|
||||
}
|
||||
|
||||
BasicPoolEntry entry = null;
|
||||
poolLock.lock();
|
||||
try {
|
||||
|
||||
RouteSpecificPool rospl = getRoutePool(route, true);
|
||||
WaitingThread waitingThread = null;
|
||||
|
||||
while (entry == null) {
|
||||
Asserts.check(!shutdown, "Connection pool shut down");
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("[" + route + "] total kept alive: " + freeConnections.size() +
|
||||
", total issued: " + leasedConnections.size() +
|
||||
", total allocated: " + numConnections + " out of " + maxTotalConnections);
|
||||
}
|
||||
|
||||
// the cases to check for:
|
||||
// - have a free connection for that route
|
||||
// - allowed to create a free connection for that route
|
||||
// - can delete and replace a free connection for another route
|
||||
// - need to wait for one of the things above to come true
|
||||
|
||||
entry = getFreeEntry(rospl, state);
|
||||
if (entry != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
final boolean hasCapacity = rospl.getCapacity() > 0;
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Available capacity: " + rospl.getCapacity()
|
||||
+ " out of " + rospl.getMaxEntries()
|
||||
+ " [" + route + "][" + state + "]");
|
||||
}
|
||||
|
||||
if (hasCapacity && numConnections < maxTotalConnections) {
|
||||
|
||||
entry = createEntry(rospl, operator);
|
||||
|
||||
} else if (hasCapacity && !freeConnections.isEmpty()) {
|
||||
|
||||
deleteLeastUsedEntry();
|
||||
// if least used entry's route was the same as rospl,
|
||||
// rospl is now out of date : we preemptively refresh
|
||||
rospl = getRoutePool(route, true);
|
||||
entry = createEntry(rospl, operator);
|
||||
|
||||
} else {
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Need to wait for connection" +
|
||||
" [" + route + "][" + state + "]");
|
||||
}
|
||||
|
||||
if (waitingThread == null) {
|
||||
waitingThread =
|
||||
newWaitingThread(poolLock.newCondition(), rospl);
|
||||
aborter.setWaitingThread(waitingThread);
|
||||
}
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
rospl.queueThread(waitingThread);
|
||||
waitingThreads.add(waitingThread);
|
||||
success = waitingThread.await(deadline);
|
||||
|
||||
} finally {
|
||||
// In case of 'success', we were woken up by the
|
||||
// connection pool and should now have a connection
|
||||
// waiting for us, or else we're shutting down.
|
||||
// Just continue in the loop, both cases are checked.
|
||||
rospl.removeThread(waitingThread);
|
||||
waitingThreads.remove(waitingThread);
|
||||
}
|
||||
|
||||
// check for spurious wakeup vs. timeout
|
||||
if (!success && (deadline != null) &&
|
||||
(deadline.getTime() <= System.currentTimeMillis())) {
|
||||
throw new ConnectionPoolTimeoutException
|
||||
("Timeout waiting for connection from pool");
|
||||
}
|
||||
}
|
||||
} // while no entry
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void freeEntry(final BasicPoolEntry entry, final boolean reusable, final long validDuration, final TimeUnit timeUnit) {
|
||||
|
||||
final HttpRoute route = entry.getPlannedRoute();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Releasing connection" +
|
||||
" [" + route + "][" + entry.getState() + "]");
|
||||
}
|
||||
|
||||
poolLock.lock();
|
||||
try {
|
||||
if (shutdown) {
|
||||
// the pool is shut down, release the
|
||||
// connection's resources and get out of here
|
||||
closeConnection(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
// no longer issued, we keep a hard reference now
|
||||
leasedConnections.remove(entry);
|
||||
|
||||
final RouteSpecificPool rospl = getRoutePool(route, true);
|
||||
|
||||
if (reusable && rospl.getCapacity() >= 0) {
|
||||
if (log.isDebugEnabled()) {
|
||||
final String s;
|
||||
if (validDuration > 0) {
|
||||
s = "for " + validDuration + " " + timeUnit;
|
||||
} else {
|
||||
s = "indefinitely";
|
||||
}
|
||||
log.debug("Pooling connection" +
|
||||
" [" + route + "][" + entry.getState() + "]; keep alive " + s);
|
||||
}
|
||||
rospl.freeEntry(entry);
|
||||
entry.updateExpiry(validDuration, timeUnit);
|
||||
freeConnections.add(entry);
|
||||
} else {
|
||||
closeConnection(entry);
|
||||
rospl.dropEntry();
|
||||
numConnections--;
|
||||
}
|
||||
|
||||
notifyWaitingThread(rospl);
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If available, get a free pool entry for a route.
|
||||
*
|
||||
* @param rospl the route-specific pool from which to get an entry
|
||||
*
|
||||
* @return an available pool entry for the given route, or
|
||||
* <code>null</code> if none is available
|
||||
*/
|
||||
protected BasicPoolEntry getFreeEntry(final RouteSpecificPool rospl, final Object state) {
|
||||
|
||||
BasicPoolEntry entry = null;
|
||||
poolLock.lock();
|
||||
try {
|
||||
boolean done = false;
|
||||
while(!done) {
|
||||
|
||||
entry = rospl.allocEntry(state);
|
||||
|
||||
if (entry != null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Getting free connection"
|
||||
+ " [" + rospl.getRoute() + "][" + state + "]");
|
||||
|
||||
}
|
||||
freeConnections.remove(entry);
|
||||
if (entry.isExpired(System.currentTimeMillis())) {
|
||||
// If the free entry isn't valid anymore, get rid of it
|
||||
// and loop to find another one that might be valid.
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing expired free connection"
|
||||
+ " [" + rospl.getRoute() + "][" + state + "]");
|
||||
}
|
||||
closeConnection(entry);
|
||||
// We use dropEntry instead of deleteEntry because the entry
|
||||
// is no longer "free" (we just allocated it), and deleteEntry
|
||||
// can only be used to delete free entries.
|
||||
rospl.dropEntry();
|
||||
numConnections--;
|
||||
} else {
|
||||
leasedConnections.add(entry);
|
||||
done = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
done = true;
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("No free connections"
|
||||
+ " [" + rospl.getRoute() + "][" + state + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new pool entry.
|
||||
* This method assumes that the new connection will be handed
|
||||
* out immediately.
|
||||
*
|
||||
* @param rospl the route-specific pool for which to create the entry
|
||||
* @param op the operator for creating a connection
|
||||
*
|
||||
* @return the new pool entry for a new connection
|
||||
*/
|
||||
protected BasicPoolEntry createEntry(final RouteSpecificPool rospl,
|
||||
final ClientConnectionOperator op) {
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Creating new connection [" + rospl.getRoute() + "]");
|
||||
}
|
||||
|
||||
// the entry will create the connection when needed
|
||||
final BasicPoolEntry entry = new BasicPoolEntry(op, rospl.getRoute(), connTTL, connTTLTimeUnit);
|
||||
|
||||
poolLock.lock();
|
||||
try {
|
||||
rospl.createdEntry(entry);
|
||||
numConnections++;
|
||||
leasedConnections.add(entry);
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes a given pool entry.
|
||||
* This closes the pooled connection and removes all references,
|
||||
* so that it can be GCed.
|
||||
*
|
||||
* <p><b>Note:</b> Does not remove the entry from the freeConnections list.
|
||||
* It is assumed that the caller has already handled this step.</p>
|
||||
* <!-- @@@ is that a good idea? or rather fix it? -->
|
||||
*
|
||||
* @param entry the pool entry for the connection to delete
|
||||
*/
|
||||
protected void deleteEntry(final BasicPoolEntry entry) {
|
||||
|
||||
final HttpRoute route = entry.getPlannedRoute();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Deleting connection"
|
||||
+ " [" + route + "][" + entry.getState() + "]");
|
||||
}
|
||||
|
||||
poolLock.lock();
|
||||
try {
|
||||
|
||||
closeConnection(entry);
|
||||
|
||||
final RouteSpecificPool rospl = getRoutePool(route, true);
|
||||
rospl.deleteEntry(entry);
|
||||
numConnections--;
|
||||
if (rospl.isUnused()) {
|
||||
routeToPool.remove(route);
|
||||
}
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete an old, free pool entry to make room for a new one.
|
||||
* Used to replace pool entries with ones for a different route.
|
||||
*/
|
||||
protected void deleteLeastUsedEntry() {
|
||||
poolLock.lock();
|
||||
try {
|
||||
|
||||
final BasicPoolEntry entry = freeConnections.remove();
|
||||
|
||||
if (entry != null) {
|
||||
deleteEntry(entry);
|
||||
} else if (log.isDebugEnabled()) {
|
||||
log.debug("No free connection to delete");
|
||||
}
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleLostEntry(final HttpRoute route) {
|
||||
|
||||
poolLock.lock();
|
||||
try {
|
||||
|
||||
final RouteSpecificPool rospl = getRoutePool(route, true);
|
||||
rospl.dropEntry();
|
||||
if (rospl.isUnused()) {
|
||||
routeToPool.remove(route);
|
||||
}
|
||||
|
||||
numConnections--;
|
||||
notifyWaitingThread(rospl);
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies a waiting thread that a connection is available.
|
||||
* This will wake a thread waiting in the specific route pool,
|
||||
* if there is one.
|
||||
* Otherwise, a thread in the connection pool will be notified.
|
||||
*
|
||||
* @param rospl the pool in which to notify, or <code>null</code>
|
||||
*/
|
||||
protected void notifyWaitingThread(final RouteSpecificPool rospl) {
|
||||
|
||||
//@@@ while this strategy provides for best connection re-use,
|
||||
//@@@ is it fair? only do this if the connection is open?
|
||||
// Find the thread we are going to notify. We want to ensure that
|
||||
// each waiting thread is only interrupted once, so we will remove
|
||||
// it from all wait queues before interrupting.
|
||||
WaitingThread waitingThread = null;
|
||||
|
||||
poolLock.lock();
|
||||
try {
|
||||
|
||||
if ((rospl != null) && rospl.hasThread()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Notifying thread waiting on pool" +
|
||||
" [" + rospl.getRoute() + "]");
|
||||
}
|
||||
waitingThread = rospl.nextThread();
|
||||
} else if (!waitingThreads.isEmpty()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Notifying thread waiting on any pool");
|
||||
}
|
||||
waitingThread = waitingThreads.remove();
|
||||
} else if (log.isDebugEnabled()) {
|
||||
log.debug("Notifying no-one, there are no waiting threads");
|
||||
}
|
||||
|
||||
if (waitingThread != null) {
|
||||
waitingThread.wakeup();
|
||||
}
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void deleteClosedConnections() {
|
||||
poolLock.lock();
|
||||
try {
|
||||
final Iterator<BasicPoolEntry> iter = freeConnections.iterator();
|
||||
while (iter.hasNext()) {
|
||||
final BasicPoolEntry entry = iter.next();
|
||||
if (!entry.getConnection().isOpen()) {
|
||||
iter.remove();
|
||||
deleteEntry(entry);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes idle connections.
|
||||
*
|
||||
* @param idletime the time the connections should have been idle
|
||||
* in order to be closed now
|
||||
* @param tunit the unit for the <code>idletime</code>
|
||||
*/
|
||||
@Override
|
||||
public void closeIdleConnections(final long idletime, final TimeUnit tunit) {
|
||||
Args.notNull(tunit, "Time unit");
|
||||
final long t = idletime > 0 ? idletime : 0;
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing connections idle longer than " + t + " " + tunit);
|
||||
}
|
||||
// the latest time for which connections will be closed
|
||||
final long deadline = System.currentTimeMillis() - tunit.toMillis(t);
|
||||
poolLock.lock();
|
||||
try {
|
||||
final Iterator<BasicPoolEntry> iter = freeConnections.iterator();
|
||||
while (iter.hasNext()) {
|
||||
final BasicPoolEntry entry = iter.next();
|
||||
if (entry.getUpdated() <= deadline) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing connection last used @ " + new Date(entry.getUpdated()));
|
||||
}
|
||||
iter.remove();
|
||||
deleteEntry(entry);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeExpiredConnections() {
|
||||
log.debug("Closing expired connections");
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
poolLock.lock();
|
||||
try {
|
||||
final Iterator<BasicPoolEntry> iter = freeConnections.iterator();
|
||||
while (iter.hasNext()) {
|
||||
final BasicPoolEntry entry = iter.next();
|
||||
if (entry.isExpired(now)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing connection expired @ " + new Date(entry.getExpiry()));
|
||||
}
|
||||
iter.remove();
|
||||
deleteEntry(entry);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
poolLock.lock();
|
||||
try {
|
||||
if (shutdown) {
|
||||
return;
|
||||
}
|
||||
shutdown = true;
|
||||
|
||||
// close all connections that are issued to an application
|
||||
final Iterator<BasicPoolEntry> iter1 = leasedConnections.iterator();
|
||||
while (iter1.hasNext()) {
|
||||
final BasicPoolEntry entry = iter1.next();
|
||||
iter1.remove();
|
||||
closeConnection(entry);
|
||||
}
|
||||
|
||||
// close all free connections
|
||||
final Iterator<BasicPoolEntry> iter2 = freeConnections.iterator();
|
||||
while (iter2.hasNext()) {
|
||||
final BasicPoolEntry entry = iter2.next();
|
||||
iter2.remove();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing connection"
|
||||
+ " [" + entry.getPlannedRoute() + "][" + entry.getState() + "]");
|
||||
}
|
||||
closeConnection(entry);
|
||||
}
|
||||
|
||||
// wake up all waiting threads
|
||||
final Iterator<WaitingThread> iwth = waitingThreads.iterator();
|
||||
while (iwth.hasNext()) {
|
||||
final WaitingThread waiter = iwth.next();
|
||||
iwth.remove();
|
||||
waiter.wakeup();
|
||||
}
|
||||
|
||||
routeToPool.clear();
|
||||
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* since 4.1
|
||||
*/
|
||||
public void setMaxTotalConnections(final int max) {
|
||||
poolLock.lock();
|
||||
try {
|
||||
maxTotalConnections = max;
|
||||
} finally {
|
||||
poolLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* since 4.1
|
||||
*/
|
||||
public int getMaxTotalConnections() {
|
||||
return maxTotalConnections;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
69
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/PoolEntryRequest.java
vendored
Normal file
69
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/PoolEntryRequest.java
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectionPoolTimeoutException;
|
||||
|
||||
/**
|
||||
* Encapsulates a request for a {@link BasicPoolEntry}.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) use {@link java.util.concurrent.Future}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface PoolEntryRequest {
|
||||
|
||||
/**
|
||||
* Obtains a pool entry with a connection within the given timeout.
|
||||
* If {@link #abortRequest()} is called before this completes
|
||||
* an {@link InterruptedException} is thrown.
|
||||
*
|
||||
* @param timeout the timeout, 0 or negative for no timeout
|
||||
* @param tunit the unit for the <code>timeout</code>,
|
||||
* may be <code>null</code> only if there is no timeout
|
||||
*
|
||||
* @return pool entry holding a connection for the route
|
||||
*
|
||||
* @throws ConnectionPoolTimeoutException
|
||||
* if the timeout expired
|
||||
* @throws InterruptedException
|
||||
* if the calling thread was interrupted or the request was aborted
|
||||
*/
|
||||
BasicPoolEntry getPoolEntry(
|
||||
long timeout,
|
||||
TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException;
|
||||
|
||||
/**
|
||||
* Aborts the active or next call to
|
||||
* {@link #getPoolEntry(long, TimeUnit)}.
|
||||
*/
|
||||
void abortRequest();
|
||||
|
||||
}
|
||||
313
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/RouteSpecificPool.java
vendored
Normal file
313
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/RouteSpecificPool.java
vendored
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Queue;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.params.ConnPerRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
import ch.boye.httpclientandroidlib.util.LangUtils;
|
||||
|
||||
|
||||
/**
|
||||
* A connection sub-pool for a specific route, used by {@link ConnPoolByRoute}.
|
||||
* The methods in this class are unsynchronized. It is expected that the
|
||||
* containing pool takes care of synchronization.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) use {@link ch.boye.httpclientandroidlib.pool.AbstractConnPool}
|
||||
*/
|
||||
@Deprecated
|
||||
public class RouteSpecificPool {
|
||||
|
||||
public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
|
||||
|
||||
/** The route this pool is for. */
|
||||
protected final HttpRoute route; //Immutable
|
||||
|
||||
protected final int maxEntries;
|
||||
|
||||
/** Connections per route */
|
||||
protected final ConnPerRoute connPerRoute;
|
||||
|
||||
/**
|
||||
* The list of free entries.
|
||||
* This list is managed LIFO, to increase idle times and
|
||||
* allow for closing connections that are not really needed.
|
||||
*/
|
||||
protected final LinkedList<BasicPoolEntry> freeEntries;
|
||||
|
||||
/** The list of threads waiting for this pool. */
|
||||
protected final Queue<WaitingThread> waitingThreads;
|
||||
|
||||
/** The number of created entries. */
|
||||
protected int numEntries;
|
||||
|
||||
/**
|
||||
* @deprecated (4.1) use {@link RouteSpecificPool#RouteSpecificPool(HttpRoute, ConnPerRoute)}
|
||||
*/
|
||||
@Deprecated
|
||||
public RouteSpecificPool(final HttpRoute route, final int maxEntries) {
|
||||
this.route = route;
|
||||
this.maxEntries = maxEntries;
|
||||
this.connPerRoute = new ConnPerRoute() {
|
||||
public int getMaxForRoute(final HttpRoute route) {
|
||||
return RouteSpecificPool.this.maxEntries;
|
||||
}
|
||||
};
|
||||
this.freeEntries = new LinkedList<BasicPoolEntry>();
|
||||
this.waitingThreads = new LinkedList<WaitingThread>();
|
||||
this.numEntries = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new route-specific pool.
|
||||
*
|
||||
* @param route the route for which to pool
|
||||
* @param connPerRoute the connections per route configuration
|
||||
*/
|
||||
public RouteSpecificPool(final HttpRoute route, final ConnPerRoute connPerRoute) {
|
||||
this.route = route;
|
||||
this.connPerRoute = connPerRoute;
|
||||
this.maxEntries = connPerRoute.getMaxForRoute(route);
|
||||
this.freeEntries = new LinkedList<BasicPoolEntry>();
|
||||
this.waitingThreads = new LinkedList<WaitingThread>();
|
||||
this.numEntries = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the route for which this pool is specific.
|
||||
*
|
||||
* @return the route
|
||||
*/
|
||||
public final HttpRoute getRoute() {
|
||||
return route;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the maximum number of entries allowed for this pool.
|
||||
*
|
||||
* @return the max entry number
|
||||
*/
|
||||
public final int getMaxEntries() {
|
||||
return maxEntries;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether this pool is unused.
|
||||
* A pool is unused if there is neither an entry nor a waiting thread.
|
||||
* All entries count, not only the free but also the allocated ones.
|
||||
*
|
||||
* @return <code>true</code> if this pool is unused,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isUnused() {
|
||||
return (numEntries < 1) && waitingThreads.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return remaining capacity of this pool
|
||||
*
|
||||
* @return capacity
|
||||
*/
|
||||
public int getCapacity() {
|
||||
return connPerRoute.getMaxForRoute(route) - numEntries;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the number of entries.
|
||||
* This includes not only the free entries, but also those that
|
||||
* have been created and are currently issued to an application.
|
||||
*
|
||||
* @return the number of entries for the route of this pool
|
||||
*/
|
||||
public final int getEntryCount() {
|
||||
return numEntries;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains a free entry from this pool, if one is available.
|
||||
*
|
||||
* @return an available pool entry, or <code>null</code> if there is none
|
||||
*/
|
||||
public BasicPoolEntry allocEntry(final Object state) {
|
||||
if (!freeEntries.isEmpty()) {
|
||||
final ListIterator<BasicPoolEntry> it = freeEntries.listIterator(freeEntries.size());
|
||||
while (it.hasPrevious()) {
|
||||
final BasicPoolEntry entry = it.previous();
|
||||
if (entry.getState() == null || LangUtils.equals(state, entry.getState())) {
|
||||
it.remove();
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getCapacity() == 0 && !freeEntries.isEmpty()) {
|
||||
final BasicPoolEntry entry = freeEntries.remove();
|
||||
entry.shutdownEntry();
|
||||
final OperatedClientConnection conn = entry.getConnection();
|
||||
try {
|
||||
conn.close();
|
||||
} catch (final IOException ex) {
|
||||
log.debug("I/O error closing connection", ex);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an allocated entry to this pool.
|
||||
*
|
||||
* @param entry the entry obtained from {@link #allocEntry allocEntry}
|
||||
* or presented to {@link #createdEntry createdEntry}
|
||||
*/
|
||||
public void freeEntry(final BasicPoolEntry entry) {
|
||||
if (numEntries < 1) {
|
||||
throw new IllegalStateException
|
||||
("No entry created for this pool. " + route);
|
||||
}
|
||||
if (numEntries <= freeEntries.size()) {
|
||||
throw new IllegalStateException
|
||||
("No entry allocated from this pool. " + route);
|
||||
}
|
||||
freeEntries.add(entry);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates creation of an entry for this pool.
|
||||
* The entry will <i>not</i> be added to the list of free entries,
|
||||
* it is only recognized as belonging to this pool now. It can then
|
||||
* be passed to {@link #freeEntry freeEntry}.
|
||||
*
|
||||
* @param entry the entry that was created for this pool
|
||||
*/
|
||||
public void createdEntry(final BasicPoolEntry entry) {
|
||||
Args.check(route.equals(entry.getPlannedRoute()), "Entry not planned for this pool");
|
||||
numEntries++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes an entry from this pool.
|
||||
* Only entries that are currently free in this pool can be deleted.
|
||||
* Allocated entries can not be deleted.
|
||||
*
|
||||
* @param entry the entry to delete from this pool
|
||||
*
|
||||
* @return <code>true</code> if the entry was found and deleted, or
|
||||
* <code>false</code> if the entry was not found
|
||||
*/
|
||||
public boolean deleteEntry(final BasicPoolEntry entry) {
|
||||
|
||||
final boolean found = freeEntries.remove(entry);
|
||||
if (found) {
|
||||
numEntries--;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Forgets about an entry from this pool.
|
||||
* This method is used to indicate that an entry
|
||||
* {@link #allocEntry allocated}
|
||||
* from this pool has been lost and will not be returned.
|
||||
*/
|
||||
public void dropEntry() {
|
||||
Asserts.check(numEntries > 0, "There is no entry that could be dropped");
|
||||
numEntries--;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a waiting thread.
|
||||
* This pool makes no attempt to match waiting threads with pool entries.
|
||||
* It is the caller's responsibility to check that there is no entry
|
||||
* before adding a waiting thread.
|
||||
*
|
||||
* @param wt the waiting thread
|
||||
*/
|
||||
public void queueThread(final WaitingThread wt) {
|
||||
Args.notNull(wt, "Waiting thread");
|
||||
this.waitingThreads.add(wt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether there is a waiting thread in this pool.
|
||||
*
|
||||
* @return <code>true</code> if there is a waiting thread,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean hasThread() {
|
||||
return !this.waitingThreads.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the next thread in the queue.
|
||||
*
|
||||
* @return a waiting thread, or <code>null</code> if there is none
|
||||
*/
|
||||
public WaitingThread nextThread() {
|
||||
return this.waitingThreads.peek();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a waiting thread, if it is queued.
|
||||
*
|
||||
* @param wt the waiting thread
|
||||
*/
|
||||
public void removeThread(final WaitingThread wt) {
|
||||
if (wt == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.waitingThreads.remove(wt);
|
||||
}
|
||||
|
||||
|
||||
} // class RouteSpecificPool
|
||||
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
|
||||
/* LogFactory removed by HttpClient for Android script. */
|
||||
import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.conn.ClientConnectionRequest;
|
||||
import ch.boye.httpclientandroidlib.conn.ConnectionPoolTimeoutException;
|
||||
import ch.boye.httpclientandroidlib.conn.ManagedClientConnection;
|
||||
import ch.boye.httpclientandroidlib.conn.params.ConnPerRouteBean;
|
||||
import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
|
||||
import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
|
||||
import ch.boye.httpclientandroidlib.impl.conn.DefaultClientConnectionOperator;
|
||||
import ch.boye.httpclientandroidlib.impl.conn.SchemeRegistryFactory;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
import ch.boye.httpclientandroidlib.util.Asserts;
|
||||
|
||||
/**
|
||||
* Manages a pool of {@link ch.boye.httpclientandroidlib.conn.OperatedClientConnection }
|
||||
* and is able to service connection requests from multiple execution threads.
|
||||
* Connections are pooled on a per route basis. A request for a route which
|
||||
* already the manager has persistent connections for available in the pool
|
||||
* will be services by leasing a connection from the pool rather than
|
||||
* creating a brand new connection.
|
||||
* <p>
|
||||
* ThreadSafeClientConnManager maintains a maximum limit of connection on
|
||||
* a per route basis and in total. Per default this implementation will
|
||||
* create no more than than 2 concurrent connections per given route
|
||||
* and no more 20 connections in total. For many real-world applications
|
||||
* these limits may prove too constraining, especially if they use HTTP
|
||||
* as a transport protocol for their services. Connection limits, however,
|
||||
* can be adjusted using HTTP parameters.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) use {@link ch.boye.httpclientandroidlib.impl.conn.PoolingHttpClientConnectionManager}
|
||||
*/
|
||||
@ThreadSafe
|
||||
@Deprecated
|
||||
public class ThreadSafeClientConnManager implements ClientConnectionManager {
|
||||
|
||||
public HttpClientAndroidLog log;
|
||||
|
||||
/** The schemes supported by this connection manager. */
|
||||
protected final SchemeRegistry schemeRegistry; // @ThreadSafe
|
||||
|
||||
protected final AbstractConnPool connectionPool;
|
||||
|
||||
/** The pool of connections being managed. */
|
||||
protected final ConnPoolByRoute pool;
|
||||
|
||||
/** The operator for opening and updating connections. */
|
||||
protected final ClientConnectionOperator connOperator; // DefaultClientConnectionOperator is @ThreadSafe
|
||||
|
||||
protected final ConnPerRouteBean connPerRoute;
|
||||
|
||||
/**
|
||||
* Creates a new thread safe connection manager.
|
||||
*
|
||||
* @param schreg the scheme registry.
|
||||
*/
|
||||
public ThreadSafeClientConnManager(final SchemeRegistry schreg) {
|
||||
this(schreg, -1, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public ThreadSafeClientConnManager() {
|
||||
this(SchemeRegistryFactory.createDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new thread safe connection manager.
|
||||
*
|
||||
* @param schreg the scheme registry.
|
||||
* @param connTTL max connection lifetime, <=0 implies "infinity"
|
||||
* @param connTTLTimeUnit TimeUnit of connTTL
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public ThreadSafeClientConnManager(final SchemeRegistry schreg,
|
||||
final long connTTL, final TimeUnit connTTLTimeUnit) {
|
||||
this(schreg, connTTL, connTTLTimeUnit, new ConnPerRouteBean());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new thread safe connection manager.
|
||||
*
|
||||
* @param schreg the scheme registry.
|
||||
* @param connTTL max connection lifetime, <=0 implies "infinity"
|
||||
* @param connTTLTimeUnit TimeUnit of connTTL
|
||||
* @param connPerRoute mapping of maximum connections per route,
|
||||
* provided as a dependency so it can be managed externally, e.g.
|
||||
* for dynamic connection pool size management.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public ThreadSafeClientConnManager(final SchemeRegistry schreg,
|
||||
final long connTTL, final TimeUnit connTTLTimeUnit, final ConnPerRouteBean connPerRoute) {
|
||||
super();
|
||||
Args.notNull(schreg, "Scheme registry");
|
||||
this.log = new HttpClientAndroidLog(getClass());
|
||||
this.schemeRegistry = schreg;
|
||||
this.connPerRoute = connPerRoute;
|
||||
this.connOperator = createConnectionOperator(schreg);
|
||||
this.pool = createConnectionPool(connTTL, connTTLTimeUnit) ;
|
||||
this.connectionPool = this.pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new thread safe connection manager.
|
||||
*
|
||||
* @param params the parameters for this manager.
|
||||
* @param schreg the scheme registry.
|
||||
*
|
||||
* @deprecated (4.1) use {@link ThreadSafeClientConnManager#ThreadSafeClientConnManager(SchemeRegistry)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ThreadSafeClientConnManager(final HttpParams params,
|
||||
final SchemeRegistry schreg) {
|
||||
Args.notNull(schreg, "Scheme registry");
|
||||
this.log = new HttpClientAndroidLog(getClass());
|
||||
this.schemeRegistry = schreg;
|
||||
this.connPerRoute = new ConnPerRouteBean();
|
||||
this.connOperator = createConnectionOperator(schreg);
|
||||
this.pool = (ConnPoolByRoute) createConnectionPool(params) ;
|
||||
this.connectionPool = this.pool;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
shutdown();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for creating the connection pool.
|
||||
*
|
||||
* @return the connection pool to use
|
||||
*
|
||||
* @deprecated (4.1) use #createConnectionPool(long, TimeUnit))
|
||||
*/
|
||||
@Deprecated
|
||||
protected AbstractConnPool createConnectionPool(final HttpParams params) {
|
||||
return new ConnPoolByRoute(connOperator, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for creating the connection pool.
|
||||
*
|
||||
* @return the connection pool to use
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
protected ConnPoolByRoute createConnectionPool(final long connTTL, final TimeUnit connTTLTimeUnit) {
|
||||
return new ConnPoolByRoute(connOperator, connPerRoute, 20, connTTL, connTTLTimeUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for creating the connection operator.
|
||||
* It is called by the constructor.
|
||||
* Derived classes can override this method to change the
|
||||
* instantiation of the operator.
|
||||
* The default implementation here instantiates
|
||||
* {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}.
|
||||
*
|
||||
* @param schreg the scheme registry.
|
||||
*
|
||||
* @return the connection operator to use
|
||||
*/
|
||||
protected ClientConnectionOperator
|
||||
createConnectionOperator(final SchemeRegistry schreg) {
|
||||
|
||||
return new DefaultClientConnectionOperator(schreg);// @ThreadSafe
|
||||
}
|
||||
|
||||
public SchemeRegistry getSchemeRegistry() {
|
||||
return this.schemeRegistry;
|
||||
}
|
||||
|
||||
public ClientConnectionRequest requestConnection(
|
||||
final HttpRoute route,
|
||||
final Object state) {
|
||||
|
||||
final PoolEntryRequest poolRequest = pool.requestPoolEntry(
|
||||
route, state);
|
||||
|
||||
return new ClientConnectionRequest() {
|
||||
|
||||
public void abortRequest() {
|
||||
poolRequest.abortRequest();
|
||||
}
|
||||
|
||||
public ManagedClientConnection getConnection(
|
||||
final long timeout, final TimeUnit tunit) throws InterruptedException,
|
||||
ConnectionPoolTimeoutException {
|
||||
Args.notNull(route, "Route");
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Get connection: " + route + ", timeout = " + timeout);
|
||||
}
|
||||
|
||||
final BasicPoolEntry entry = poolRequest.getPoolEntry(timeout, tunit);
|
||||
return new BasicPooledConnAdapter(ThreadSafeClientConnManager.this, entry);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public void releaseConnection(final ManagedClientConnection conn, final long validDuration, final TimeUnit timeUnit) {
|
||||
Args.check(conn instanceof BasicPooledConnAdapter, "Connection class mismatch, " +
|
||||
"connection not obtained from this manager");
|
||||
final BasicPooledConnAdapter hca = (BasicPooledConnAdapter) conn;
|
||||
if (hca.getPoolEntry() != null) {
|
||||
Asserts.check(hca.getManager() == this, "Connection not obtained from this manager");
|
||||
}
|
||||
synchronized (hca) {
|
||||
final BasicPoolEntry entry = (BasicPoolEntry) hca.getPoolEntry();
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// make sure that the response has been read completely
|
||||
if (hca.isOpen() && !hca.isMarkedReusable()) {
|
||||
// In MTHCM, there would be a call to
|
||||
// SimpleHttpConnectionManager.finishLastResponse(conn);
|
||||
// Consuming the response is handled outside in 4.0.
|
||||
|
||||
// make sure this connection will not be re-used
|
||||
// Shut down rather than close, we might have gotten here
|
||||
// because of a shutdown trigger.
|
||||
// Shutdown of the adapter also clears the tracked route.
|
||||
hca.shutdown();
|
||||
}
|
||||
} catch (final IOException iox) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Exception shutting down released connection.",
|
||||
iox);
|
||||
}
|
||||
} finally {
|
||||
final boolean reusable = hca.isMarkedReusable();
|
||||
if (log.isDebugEnabled()) {
|
||||
if (reusable) {
|
||||
log.debug("Released connection is reusable.");
|
||||
} else {
|
||||
log.debug("Released connection is not reusable.");
|
||||
}
|
||||
}
|
||||
hca.detach();
|
||||
pool.freeEntry(entry, reusable, validDuration, timeUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
log.debug("Shutting down");
|
||||
pool.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total number of pooled connections for the given route.
|
||||
* This is the total number of connections that have been created and
|
||||
* are still in use by this connection manager for the route.
|
||||
* This value will not exceed the maximum number of connections per host.
|
||||
*
|
||||
* @param route the route in question
|
||||
*
|
||||
* @return the total number of pooled connections for that route
|
||||
*/
|
||||
public int getConnectionsInPool(final HttpRoute route) {
|
||||
return pool.getConnectionsInPool(route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total number of pooled connections. This is the total number of
|
||||
* connections that have been created and are still in use by this connection
|
||||
* manager. This value will not exceed the maximum number of connections
|
||||
* in total.
|
||||
*
|
||||
* @return the total number of pooled connections
|
||||
*/
|
||||
public int getConnectionsInPool() {
|
||||
return pool.getConnectionsInPool();
|
||||
}
|
||||
|
||||
public void closeIdleConnections(final long idleTimeout, final TimeUnit tunit) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit);
|
||||
}
|
||||
pool.closeIdleConnections(idleTimeout, tunit);
|
||||
}
|
||||
|
||||
public void closeExpiredConnections() {
|
||||
log.debug("Closing expired connections");
|
||||
pool.closeExpiredConnections();
|
||||
}
|
||||
|
||||
/**
|
||||
* since 4.1
|
||||
*/
|
||||
public int getMaxTotal() {
|
||||
return pool.getMaxTotalConnections();
|
||||
}
|
||||
|
||||
/**
|
||||
* since 4.1
|
||||
*/
|
||||
public void setMaxTotal(final int max) {
|
||||
pool.setMaxTotalConnections(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public int getDefaultMaxPerRoute() {
|
||||
return connPerRoute.getDefaultMaxPerRoute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setDefaultMaxPerRoute(final int max) {
|
||||
connPerRoute.setDefaultMaxPerRoute(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public int getMaxForRoute(final HttpRoute route) {
|
||||
return connPerRoute.getMaxForRoute(route);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setMaxForRoute(final HttpRoute route, final int max) {
|
||||
connPerRoute.setMaxForRoute(route, max);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
198
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/WaitingThread.java
vendored
Normal file
198
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/WaitingThread.java
vendored
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
|
||||
import ch.boye.httpclientandroidlib.util.Args;
|
||||
|
||||
/**
|
||||
* Represents a thread waiting for a connection.
|
||||
* This class implements throwaway objects. It is instantiated whenever
|
||||
* a thread needs to wait. Instances are not re-used, except if the
|
||||
* waiting thread experiences a spurious wakeup and continues to wait.
|
||||
* <br/>
|
||||
* All methods assume external synchronization on the condition
|
||||
* passed to the constructor.
|
||||
* Instances of this class do <i>not</i> synchronize access!
|
||||
*
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) do not use
|
||||
*/
|
||||
@Deprecated
|
||||
public class WaitingThread {
|
||||
|
||||
/** The condition on which the thread is waiting. */
|
||||
private final Condition cond;
|
||||
|
||||
/** The route specific pool on which the thread is waiting. */
|
||||
//@@@ replace with generic pool interface
|
||||
private final RouteSpecificPool pool;
|
||||
|
||||
/** The thread that is waiting for an entry. */
|
||||
private Thread waiter;
|
||||
|
||||
/** True if this was interrupted. */
|
||||
private boolean aborted;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new entry for a waiting thread.
|
||||
*
|
||||
* @param cond the condition for which to wait
|
||||
* @param pool the pool on which the thread will be waiting,
|
||||
* or <code>null</code>
|
||||
*/
|
||||
public WaitingThread(final Condition cond, final RouteSpecificPool pool) {
|
||||
|
||||
Args.notNull(cond, "Condition");
|
||||
|
||||
this.cond = cond;
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the condition.
|
||||
*
|
||||
* @return the condition on which to wait, never <code>null</code>
|
||||
*/
|
||||
public final Condition getCondition() {
|
||||
// not synchronized
|
||||
return this.cond;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the pool, if there is one.
|
||||
*
|
||||
* @return the pool on which a thread is or was waiting,
|
||||
* or <code>null</code>
|
||||
*/
|
||||
public final RouteSpecificPool getPool() {
|
||||
// not synchronized
|
||||
return this.pool;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the thread, if there is one.
|
||||
*
|
||||
* @return the thread which is waiting, or <code>null</code>
|
||||
*/
|
||||
public final Thread getThread() {
|
||||
// not synchronized
|
||||
return this.waiter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Blocks the calling thread.
|
||||
* This method returns when the thread is notified or interrupted,
|
||||
* if a timeout occurrs, or if there is a spurious wakeup.
|
||||
* <br/>
|
||||
* This method assumes external synchronization.
|
||||
*
|
||||
* @param deadline when to time out, or <code>null</code> for no timeout
|
||||
*
|
||||
* @return <code>true</code> if the condition was satisfied,
|
||||
* <code>false</code> in case of a timeout.
|
||||
* Typically, a call to {@link #wakeup} is used to indicate
|
||||
* that the condition was satisfied. Since the condition is
|
||||
* accessible outside, this cannot be guaranteed though.
|
||||
*
|
||||
* @throws InterruptedException if the waiting thread was interrupted
|
||||
*
|
||||
* @see #wakeup
|
||||
*/
|
||||
public boolean await(final Date deadline)
|
||||
throws InterruptedException {
|
||||
|
||||
// This is only a sanity check. We cannot synchronize here,
|
||||
// the lock would not be released on calling cond.await() below.
|
||||
if (this.waiter != null) {
|
||||
throw new IllegalStateException
|
||||
("A thread is already waiting on this object." +
|
||||
"\ncaller: " + Thread.currentThread() +
|
||||
"\nwaiter: " + this.waiter);
|
||||
}
|
||||
|
||||
if (aborted) {
|
||||
throw new InterruptedException("Operation interrupted");
|
||||
}
|
||||
|
||||
this.waiter = Thread.currentThread();
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
if (deadline != null) {
|
||||
success = this.cond.awaitUntil(deadline);
|
||||
} else {
|
||||
this.cond.await();
|
||||
success = true;
|
||||
}
|
||||
if (aborted) {
|
||||
throw new InterruptedException("Operation interrupted");
|
||||
}
|
||||
} finally {
|
||||
this.waiter = null;
|
||||
}
|
||||
return success;
|
||||
|
||||
} // await
|
||||
|
||||
|
||||
/**
|
||||
* Wakes up the waiting thread.
|
||||
* <br/>
|
||||
* This method assumes external synchronization.
|
||||
*/
|
||||
public void wakeup() {
|
||||
|
||||
// If external synchronization and pooling works properly,
|
||||
// this cannot happen. Just a sanity check.
|
||||
if (this.waiter == null) {
|
||||
throw new IllegalStateException
|
||||
("Nobody waiting on this object.");
|
||||
}
|
||||
|
||||
// One condition might be shared by several WaitingThread instances.
|
||||
// It probably isn't, but just in case: wake all, not just one.
|
||||
this.cond.signalAll();
|
||||
}
|
||||
|
||||
public void interrupt() {
|
||||
aborted = true;
|
||||
this.cond.signalAll();
|
||||
}
|
||||
|
||||
|
||||
} // class WaitingThread
|
||||
69
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/WaitingThreadAborter.java
vendored
Normal file
69
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/WaitingThreadAborter.java
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
|
||||
/**
|
||||
* A simple class that can interrupt a {@link WaitingThread}.
|
||||
*
|
||||
* Must be called with the pool lock held.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated (4.2) do not use
|
||||
*/
|
||||
@Deprecated
|
||||
public class WaitingThreadAborter {
|
||||
|
||||
private WaitingThread waitingThread;
|
||||
private boolean aborted;
|
||||
|
||||
/**
|
||||
* If a waiting thread has been set, interrupts it.
|
||||
*/
|
||||
public void abort() {
|
||||
aborted = true;
|
||||
|
||||
if (waitingThread != null) {
|
||||
waitingThread.interrupt();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the waiting thread. If this has already been aborted,
|
||||
* the waiting thread is immediately interrupted.
|
||||
*
|
||||
* @param waitingThread The thread to interrupt when aborting.
|
||||
*/
|
||||
public void setWaitingThread(final WaitingThread waitingThread) {
|
||||
this.waitingThread = waitingThread;
|
||||
if (aborted) {
|
||||
waitingThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
33
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/package-info.java
vendored
Normal file
33
mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/conn/tsccm/package-info.java
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Deprecated.
|
||||
*
|
||||
* @deprecated (4.3)
|
||||
*/
|
||||
package ch.boye.httpclientandroidlib.impl.conn.tsccm;
|
||||
Loading…
Add table
Add a link
Reference in a new issue