init
This commit is contained in:
208
java/org/apache/catalina/ha/backend/TcpSender.java
Normal file
208
java/org/apache/catalina/ha/backend/TcpSender.java
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
package org.apache.catalina.ha.backend;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
/*
|
||||
* Sender to proxies using multicast socket.
|
||||
*/
|
||||
public class TcpSender
|
||||
implements Sender {
|
||||
|
||||
private static final Log log = LogFactory.getLog(HeartbeatListener.class);
|
||||
|
||||
HeartbeatListener config = null;
|
||||
|
||||
/**
|
||||
* Proxies.
|
||||
*/
|
||||
protected Proxy[] proxies = null;
|
||||
|
||||
|
||||
/**
|
||||
* Active connections.
|
||||
*/
|
||||
|
||||
protected Socket[] connections = null;
|
||||
protected BufferedReader[] connectionReaders = null;
|
||||
protected BufferedWriter[] connectionWriters = null;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(HeartbeatListener config) throws Exception {
|
||||
this.config = config;
|
||||
StringTokenizer tok = new StringTokenizer(config.getProxyList(), ",");
|
||||
proxies = new Proxy[tok.countTokens()];
|
||||
int i = 0;
|
||||
while (tok.hasMoreTokens()) {
|
||||
String token = tok.nextToken().trim();
|
||||
int pos = token.indexOf(':');
|
||||
if (pos <=0)
|
||||
throw new Exception("bad ProxyList");
|
||||
proxies[i] = new Proxy();
|
||||
proxies[i].port = Integer.parseInt(token.substring(pos + 1));
|
||||
try {
|
||||
proxies[i].address = InetAddress.getByName(token.substring(0, pos));
|
||||
} catch (Exception e) {
|
||||
throw new Exception("bad ProxyList");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
connections = new Socket[proxies.length];
|
||||
connectionReaders = new BufferedReader[proxies.length];
|
||||
connectionWriters = new BufferedWriter[proxies.length];
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int send(String mess) throws Exception {
|
||||
if (connections == null) {
|
||||
log.error("Not initialized");
|
||||
return -1;
|
||||
}
|
||||
String requestLine = "POST " + config.getProxyURL() + " HTTP/1.0";
|
||||
|
||||
for (int i = 0; i < connections.length; i++) {
|
||||
if (connections[i] == null) {
|
||||
try {
|
||||
if (config.getHost() != null) {
|
||||
connections[i] = new Socket();
|
||||
InetAddress addr = InetAddress.getByName(config.getHost());
|
||||
InetSocketAddress addrs = new InetSocketAddress(addr, 0);
|
||||
connections[i].setReuseAddress(true);
|
||||
connections[i].bind(addrs);
|
||||
addrs = new InetSocketAddress(proxies[i].address, proxies[i].port);
|
||||
connections[i].connect(addrs);
|
||||
} else
|
||||
connections[i] = new Socket(proxies[i].address, proxies[i].port);
|
||||
connectionReaders[i] = new BufferedReader(new InputStreamReader(connections[i].getInputStream()));
|
||||
connectionWriters[i] = new BufferedWriter(new OutputStreamWriter(connections[i].getOutputStream()));
|
||||
} catch (Exception ex) {
|
||||
log.error("Unable to connect to proxy: " + ex);
|
||||
close(i);
|
||||
}
|
||||
}
|
||||
if (connections[i] == null)
|
||||
continue; // try next proxy in the list
|
||||
BufferedWriter writer = connectionWriters[i];
|
||||
try {
|
||||
writer.write(requestLine);
|
||||
writer.write("\r\n");
|
||||
writer.write("Content-Length: " + mess.length() + "\r\n");
|
||||
writer.write("User-Agent: HeartbeatListener/1.0\r\n");
|
||||
writer.write("Connection: Keep-Alive\r\n");
|
||||
writer.write("\r\n");
|
||||
writer.write(mess);
|
||||
writer.write("\r\n");
|
||||
writer.flush();
|
||||
} catch (Exception ex) {
|
||||
log.error("Unable to send collected load information to proxy: " + ex);
|
||||
close(i);
|
||||
}
|
||||
if (connections[i] == null)
|
||||
continue; // try next proxy in the list
|
||||
|
||||
/* Read httpd answer */
|
||||
String responseStatus = connectionReaders[i].readLine();
|
||||
if (responseStatus == null) {
|
||||
log.error("Unable to read response from proxy");
|
||||
close(i);
|
||||
continue;
|
||||
} else {
|
||||
responseStatus = responseStatus.substring(responseStatus.indexOf(' ') + 1, responseStatus.indexOf(' ', responseStatus.indexOf(' ') + 1));
|
||||
int status = Integer.parseInt(responseStatus);
|
||||
if (status != 200) {
|
||||
log.error("Status is " + status);
|
||||
close(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// read all the headers.
|
||||
String header = connectionReaders[i].readLine();
|
||||
int contentLength = 0;
|
||||
while (!"".equals(header)) {
|
||||
int colon = header.indexOf(':');
|
||||
String headerName = header.substring(0, colon).trim();
|
||||
String headerValue = header.substring(colon + 1).trim();
|
||||
if ("content-length".equalsIgnoreCase(headerName)) {
|
||||
contentLength = Integer.parseInt(headerValue);
|
||||
}
|
||||
header = connectionReaders[i].readLine();
|
||||
}
|
||||
if (contentLength > 0) {
|
||||
char[] buf = new char[512];
|
||||
while (contentLength > 0) {
|
||||
int thisTime = (contentLength > buf.length) ? buf.length : contentLength;
|
||||
int n = connectionReaders[i].read(buf, 0, thisTime);
|
||||
if (n <= 0) {
|
||||
log.error("Read content failed");
|
||||
close(i);
|
||||
break;
|
||||
} else {
|
||||
contentLength -= n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close connection.
|
||||
* @param i The index of the connection that will be closed
|
||||
*/
|
||||
protected void close(int i) {
|
||||
try {
|
||||
if (connectionReaders[i] != null) {
|
||||
connectionReaders[i].close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
connectionReaders[i] = null;
|
||||
try {
|
||||
if (connectionWriters[i] != null) {
|
||||
connectionWriters[i].close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
connectionWriters[i] = null;
|
||||
try {
|
||||
if (connections[i] != null) {
|
||||
connections[i].close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
connections[i] = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user