?? httpconnection.java
字號:
package com.maverick.http;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.maverick.ssl.*;
import java.io.*;
public class HttpConnection {
SocketWithLayeredTransport socket;
InputStream in;
OutputStream out;
OutputStream monitorInOut;
OutputStream monitorOutOut;
HttpClient client;
boolean isClosed = false;
boolean canReuse = true;
boolean keepAlive = true;
long lastAccessed;
HttpAuthenticator authenticator;
boolean monitoring = "true".equals(System.getProperty("http.connection.debug"));
public static final int CONNECTION_TIMEOUT_LIMIT = 120000;
private static int sequence = 0;
private static SimpleDateFormat f = new SimpleDateFormat("HH-mm-ss-SS");
private static Object lock = new Object();
private static boolean linger = true;
/* DEBUG */static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(HttpConnection.class);
public HttpConnection(HttpClient client) throws UnknownHostException, IOException, HttpException, UnsupportedAuthenticationException, AuthenticationCancelledException {
this.client = client;
reconnect();
}
public static void setDefaultSoLinger(boolean linger) {
HttpConnection.linger = linger;
}
public synchronized void reconnect() throws UnknownHostException, IOException, HttpException, UnsupportedAuthenticationException, AuthenticationCancelledException {
close();
if(!client.isProxyConfigured()) {
/* DEBUG */log.debug("Connecting to " + client.hostname + ":" + client.port);
this.socket = new SocketWithLayeredTransport(client.hostname, client.port);
if (client.isSecure)
socket.pushTransport(new SSLTransport());
} else {
synchronized(client) {
switch(client.proxyType) {
case HttpClient.PROXY_HTTP:
case HttpClient.PROXY_HTTPS:
/* DEBUG */log.debug("Connecting to " + client.hostname + ":" + client.port + " through " + (client.proxyType==HttpClient.PROXY_HTTPS?"https":"http") + " proxy " + client.proxyHost + ":" + client.proxyPort);
// Setup the proxy client connection
if(client.proxyClient==null) {
client.proxyClient = new HttpClient(client);
}
ConnectMethod proxyConnect = new ConnectMethod(client.hostname, client.port, client.isSecure);
// Execute and retreive the direct socket
HttpResponse response = client.proxyClient.execute(proxyConnect);
if(response.getStatus()==200) {
socket = response.getConnection().socket;
}
else
throw new IOException("Proxy returned HTTP status code " + response.getStatus());
break;
default:
throw new IllegalArgumentException("Invalid proxy type set! type=" + client.proxyType);
}
}
}
int lingerTime = socket.getSoLinger();
socket.setSoLinger(linger, false ? 0 : ( lingerTime == -1 ? 0 : lingerTime ) );
in = new HttpConnectionInputStream(socket.getInputStream(), 32768);
out = new HttpConnectionOutputStream();
isClosed = false;
canReuse = true;
}
public boolean isMonitoring() {
return monitoring;
}
void monitor(String uri) throws IOException {
File dir = new File(System.getProperty("java.io.tmpdir"), client.getHost() + "." + client.getPort());
if(!dir.exists() && !dir.mkdirs()) {
/* DEBUG */log.error("Failed to create Maverick HTTP debug directory in " + dir + ", no debug will occur.");
}
else {
synchronized(lock) {
File inFile = new File(dir,
String.valueOf(sequence) + "_" + f.format(new Date()) +
".response.log");
File outFile = new File(dir,
String.valueOf(sequence) + "_" + f.format(new Date()) +
".request.log");
monitorInOut = new FileOutputStream(inFile);
monitorOutOut = new FileOutputStream(outFile);
in = new MonitorInputStream(new HttpConnectionInputStream(socket.
getInputStream(), 32768), monitorInOut);
out = new MonitorOutputStream(new HttpConnectionOutputStream(),
monitorOutOut);
sequence++;
}
}
}
void stopMonitor() throws IOException {
try {
in.close();
} catch(IOException ex) { }
try {
out.close();
} catch(IOException ex) { }
in = socket.getInputStream();
out = new HttpConnectionOutputStream();
}
void updateState() {
this.lastAccessed = System.currentTimeMillis();
}
void release() {
try {
if (monitoring)
stopMonitor();
} catch(IOException ex) { }
if(!canReuse)
close();
client.connections.releaseConnection(this);
}
void verify() throws UnknownHostException, IOException, HttpException, UnsupportedAuthenticationException, AuthenticationCancelledException {
try {
if(System.currentTimeMillis() > lastAccessed + CONNECTION_TIMEOUT_LIMIT)
canReuse = false;
else {
try {
socket.setSoTimeout(1);
in.mark(1);
int byteRead = in.read();
if (byteRead == -1) {
// again - if the socket is reporting all data read,
// probably stale
/* DEBUG */log.debug("Connection is EOF");
canReuse = false;
} else {
in.reset();
}
} finally {
socket.setSoTimeout(0);
}
}
} catch(InterruptedIOException ex) {
// Connection should be ok
} catch(SSLIOException ex) {
canReuse = (ex.getRealException().getStatus() == SSLException.READ_TIMEOUT);
} catch(IOException ex) {
// Connection is dead
/* DEBUG */log.debug("Connection is dead");
canReuse = false;
}
if(!canReuse)
reconnect();
}
public boolean isClosed() {
return isClosed;
}
public boolean isKeepAlive() {
return keepAlive;
}
public boolean canReuse() {
return canReuse;
}
public synchronized void close() {
try {
try {
if(socket!=null)
socket.close();
} catch(IOException ex) { }
}
finally {
if(monitorInOut != null) {
try {
monitorInOut.close();
}
catch(IOException ioe) {
}
}
if(monitorOutOut != null) {
try {
monitorOutOut.close();
}
catch(IOException ioe) {
}
}
}
isClosed = true;
}
public OutputStream getOutputStream() throws IOException {
return out;
// return socket.getOutputStream();
}
public InputStream getInputStream() throws IOException {
return in;
}
public int getPort() {
return client.port;
}
public String getHost() {
return client.hostname;
}
public boolean isSecure() {
return client.isSecure;
}
public Socket getSocket() {
return socket;
}
public void setAuthenticator(HttpAuthenticator authenticator) {
this.authenticator = authenticator;
}
public HttpAuthenticator getAuthenticator() {
return authenticator;
}
class HttpConnectionInputStream extends BufferedInputStream {
HttpConnectionInputStream(InputStream in, int len) {
super(in, len);
}
public void close() throws IOException {
updateState();
socket.getInputStream().close();
}
public int read() throws IOException {
updateState();
return super.read();
}
public int read(byte[] buf, int off, int len) throws IOException {
updateState();
return super.read(buf, off, len);
}
}
class HttpConnectionOutputStream extends OutputStream {
public void close() throws IOException {
updateState();
socket.getOutputStream().close();
}
public void write(int b) throws IOException {
updateState();
socket.getOutputStream().write(b);
}
public void write(byte[] buf, int off, int len) throws IOException {
updateState();
socket.getOutputStream().write(buf, off, len);
}
}
class MonitorInputStream extends InputStream {
InputStream in = null;
OutputStream monitorOut;
MonitorInputStream(InputStream in, OutputStream monitorOut) {
super();
this.in = in;
this.monitorOut = monitorOut;
}
/* (non-Javadoc)
* @see java.io.InputStream#available()
*/
public int available() throws IOException {
return in.available();
}
/* (non-Javadoc)
* @see java.io.InputStream#close()
*/
public void close() throws IOException {
in.close();
}
/* (non-Javadoc)
* @see java.io.InputStream#mark(int)
*/
public synchronized void mark(int readlimit) {
in.mark(readlimit);
}
/* (non-Javadoc)
* @see java.io.InputStream#markSupported()
*/
public boolean markSupported() {
return in.markSupported();
}
/* (non-Javadoc)
* @see java.io.InputStream#read(byte[], int, int)
*/
public int read(byte[] b, int off, int len) throws IOException {
int r = in.read(b, off, len);
if(r != -1) {
try {
monitorOut.write(b, off, r);
monitorOut.flush();
}
catch(IOException ioe) {
}
}
return r;
}
/* (non-Javadoc)
* @see java.io.InputStream#read(byte[])
*/
public int read(byte[] b) throws IOException {
int r = in.read(b);
if(r != -1) {
try {
monitorOut.write(b, 0, r);
monitorOut.flush();
}
catch(IOException ioe) {
}
}
return r;
}
/* (non-Javadoc)
* @see java.io.InputStream#reset()
*/
public synchronized void reset() throws IOException {
in.reset();
}
/* (non-Javadoc)
* @see java.io.InputStream#skip(long)
*/
public long skip(long n) throws IOException {
return in.skip(n);
}
public int read() throws IOException {
int r = in.read();
if(r != -1) {
try {
monitorOut.write(r);
monitorOut.flush();
}
catch(IOException ioe) {
}
}
return r;
}
}
class MonitorOutputStream extends OutputStream {
OutputStream out;
OutputStream monitorOut;
MonitorOutputStream(OutputStream out, OutputStream monitorOut) {
super();
this.out = out;
this.monitorOut = monitorOut;
}
/* (non-Javadoc)
* @see java.io.OutputStream#close()
*/
public void close() throws IOException {
out.close();
}
/* (non-Javadoc)
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException {
out.flush();
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
try {
monitorOut.write(b, off, len);
monitorOut.flush();
}
catch(IOException ioe) {
}
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(byte[])
*/
public void write(byte[] b) throws IOException {
out.write(b);
try {
monitorOut.write(b);
monitorOut.flush();
}
catch(IOException ioe) {
}
}
public void write(int b) throws IOException {
out.write(b);
try {
monitorOut.write(b);
monitorOut.flush();
}
catch(IOException ioe) {
}
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -