/*
* ====================================================================
* 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 org.apache.http.impl;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import org.apache.http.HttpInetConnection;
import org.apache.http.impl.io.SocketInputBuffer;
import org.apache.http.impl.io.SocketOutputBuffer;
import org.apache.http.io.SessionInputBuffer;
import org.apache.http.io.SessionOutputBuffer;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.Args;
import org.apache.http.util.Asserts;
Implementation of a client-side HTTP connection that can be bound to an arbitrary Socket
for receiving data from and transmitting data to a remote server. Since: 4.0 Deprecated: (4.3) use DefaultBHttpClientConnection
/**
* Implementation of a client-side HTTP connection that can be bound to an
* arbitrary {@link Socket} for receiving data from and transmitting data to
* a remote server.
*
* @since 4.0
*
* @deprecated (4.3) use {@link DefaultBHttpClientConnection}
*/
@Deprecated
public class SocketHttpClientConnection
extends AbstractHttpClientConnection implements HttpInetConnection {
private volatile boolean open;
private volatile Socket socket = null;
public SocketHttpClientConnection() {
super();
}
protected void assertNotOpen() {
Asserts.check(!this.open, "Connection is already open");
}
@Override
protected void assertOpen() {
Asserts.check(this.open, "Connection is not open");
}
Creates an instance of SocketInputBuffer
to be used for receiving data from the given Socket
. This method can be overridden in a super class in order to provide a custom implementation of SessionInputBuffer
interface.
Params: - socket – the socket.
- bufferSize – the buffer size.
- params – HTTP parameters.
Throws: - IOException – in case of an I/O error.
See Also: Returns: session input buffer.
/**
* Creates an instance of {@link SocketInputBuffer} to be used for
* receiving data from the given {@link Socket}.
* <p>
* This method can be overridden in a super class in order to provide
* a custom implementation of {@link SessionInputBuffer} interface.
*
* @see SocketInputBuffer#SocketInputBuffer(Socket, int, HttpParams)
*
* @param socket the socket.
* @param bufferSize the buffer size.
* @param params HTTP parameters.
* @return session input buffer.
* @throws IOException in case of an I/O error.
*/
protected SessionInputBuffer createSessionInputBuffer(
final Socket socket,
final int bufferSize,
final HttpParams params) throws IOException {
return new SocketInputBuffer(socket, bufferSize, params);
}
Creates an instance of SessionOutputBuffer
to be used for sending data to the given Socket
. This method can be overridden in a super class in order to provide a custom implementation of SocketOutputBuffer
interface.
Params: - socket – the socket.
- bufferSize – the buffer size.
- params – HTTP parameters.
Throws: - IOException – in case of an I/O error.
See Also: Returns: session output buffer.
/**
* Creates an instance of {@link SessionOutputBuffer} to be used for
* sending data to the given {@link Socket}.
* <p>
* This method can be overridden in a super class in order to provide
* a custom implementation of {@link SocketOutputBuffer} interface.
*
* @see SocketOutputBuffer#SocketOutputBuffer(Socket, int, HttpParams)
*
* @param socket the socket.
* @param bufferSize the buffer size.
* @param params HTTP parameters.
* @return session output buffer.
* @throws IOException in case of an I/O error.
*/
protected SessionOutputBuffer createSessionOutputBuffer(
final Socket socket,
final int bufferSize,
final HttpParams params) throws IOException {
return new SocketOutputBuffer(socket, bufferSize, params);
}
Binds this connection to the given Socket
. This socket will be used by the connection to send and receive data. This method will invoke createSessionInputBuffer(Socket, int, HttpParams)
and createSessionOutputBuffer(Socket, int, HttpParams)
methods to create session input / output buffers bound to this socket and then will invoke AbstractHttpClientConnection.init(SessionInputBuffer, SessionOutputBuffer, HttpParams)
method to pass references to those buffers to the underlying HTTP message parser and formatter.
After this method's execution the connection status will be reported as open and the isOpen()
will return true
.
Params: - socket – the socket.
- params – HTTP parameters.
Throws: - IOException – in case of an I/O error.
/**
* Binds this connection to the given {@link Socket}. This socket will be
* used by the connection to send and receive data.
* <p>
* This method will invoke {@link #createSessionInputBuffer(Socket, int, HttpParams)}
* and {@link #createSessionOutputBuffer(Socket, int, HttpParams)} methods
* to create session input / output buffers bound to this socket and then
* will invoke {@link #init(SessionInputBuffer, SessionOutputBuffer, HttpParams)}
* method to pass references to those buffers to the underlying HTTP message
* parser and formatter.
* <p>
* After this method's execution the connection status will be reported
* as open and the {@link #isOpen()} will return {@code true}.
*
* @param socket the socket.
* @param params HTTP parameters.
* @throws IOException in case of an I/O error.
*/
protected void bind(
final Socket socket,
final HttpParams params) throws IOException {
Args.notNull(socket, "Socket");
Args.notNull(params, "HTTP parameters");
this.socket = socket;
final int bufferSize = params.getIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1);
init(
createSessionInputBuffer(socket, bufferSize, params),
createSessionOutputBuffer(socket, bufferSize, params),
params);
this.open = true;
}
@Override
public boolean isOpen() {
return this.open;
}
protected Socket getSocket() {
return this.socket;
}
@Override
public InetAddress getLocalAddress() {
if (this.socket != null) {
return this.socket.getLocalAddress();
}
return null;
}
@Override
public int getLocalPort() {
if (this.socket != null) {
return this.socket.getLocalPort();
}
return -1;
}
@Override
public InetAddress getRemoteAddress() {
if (this.socket != null) {
return this.socket.getInetAddress();
}
return null;
}
@Override
public int getRemotePort() {
if (this.socket != null) {
return this.socket.getPort();
}
return -1;
}
@Override
public void setSocketTimeout(final int timeout) {
assertOpen();
if (this.socket != null) {
try {
this.socket.setSoTimeout(timeout);
} catch (final SocketException ignore) {
// It is not quite clear from the Sun's documentation if there are any
// other legitimate cases for a socket exception to be thrown when setting
// SO_TIMEOUT besides the socket being already closed
}
}
}
@Override
public int getSocketTimeout() {
if (this.socket != null) {
try {
return this.socket.getSoTimeout();
} catch (final SocketException ignore) {
return -1;
}
}
return -1;
}
@Override
public void shutdown() throws IOException {
this.open = false;
final Socket tmpsocket = this.socket;
if (tmpsocket != null) {
tmpsocket.close();
}
}
@Override
public void close() throws IOException {
if (!this.open) {
return;
}
this.open = false;
final Socket sock = this.socket;
try {
doFlush();
try {
try {
sock.shutdownOutput();
} catch (final IOException ignore) {
// ignore
}
try {
sock.shutdownInput();
} catch (final IOException ignore) {
// ignore
}
} catch (final UnsupportedOperationException ignore) {
// if one isn't supported, the other one isn't either
}
} finally {
sock.close();
}
}
private static void formatAddress(final StringBuilder buffer, final SocketAddress socketAddress) {
if (socketAddress instanceof InetSocketAddress) {
final InetSocketAddress addr = ((InetSocketAddress) socketAddress);
buffer.append(addr.getAddress() != null ? addr.getAddress().getHostAddress() :
addr.getAddress())
.append(':')
.append(addr.getPort());
} else {
buffer.append(socketAddress);
}
}
@Override
public String toString() {
if (this.socket != null) {
final StringBuilder buffer = new StringBuilder();
final SocketAddress remoteAddress = this.socket.getRemoteSocketAddress();
final SocketAddress localAddress = this.socket.getLocalSocketAddress();
if (remoteAddress != null && localAddress != null) {
formatAddress(buffer, localAddress);
buffer.append("<->");
formatAddress(buffer, remoteAddress);
}
return buffer.toString();
}
return super.toString();
}
}