diff options
Diffstat (limited to 'contrib/t2hproxy/T2hproxy.java')
-rw-r--r-- | contrib/t2hproxy/T2hproxy.java | 508 |
1 files changed, 0 insertions, 508 deletions
diff --git a/contrib/t2hproxy/T2hproxy.java b/contrib/t2hproxy/T2hproxy.java deleted file mode 100644 index cfe1d1a7..00000000 --- a/contrib/t2hproxy/T2hproxy.java +++ /dev/null @@ -1,508 +0,0 @@ -/* - * TFTP to HTTP proxy in Java - * - * Copyright Ken Yap 2003 - * Released under GPL2 - */ -import java.io.IOException; -import java.io.InputStream; -import java.io.FileInputStream; -import java.io.BufferedInputStream; -import java.io.UnsupportedEncodingException; -import java.lang.String; -import java.lang.StringBuffer; -import java.lang.Thread; -import java.lang.NumberFormatException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.BufferUnderflowException; -import java.util.HashMap; -import java.util.Properties; - -import org.apache.commons.httpclient.Credentials; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HostConfiguration; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.methods.GetMethod; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Description of the Class - * - *@author ken - *@created 24 September 2003 - */ -public class T2hproxy implements Runnable { - /** - * Description of the Field - */ - public final static String NAME = T2hproxy.class.getName(); - /** - * Description of the Field - */ - public final static String VERSION = "0.1"; - /** - * Description of the Field - */ - public final static int MTU = 1500; - /** - * Description of the Field - */ - public final static short TFTP_RRQ = 1; - /** - * Description of the Field - */ - public final static short TFTP_DATA = 3; - /** - * Description of the Field - */ - public final static short TFTP_ACK = 4; - /** - * Description of the Field - */ - public final static short TFTP_ERROR = 5; - /** - * Description of the Field - */ - public final static short TFTP_OACK = 6; - /** - * Description of the Field - */ - public final static short ERR_NOFILE = 1; - /** - * Description of the Field - */ - public final static short ERR_ILLOP = 4; - /** - * Description of the Field - */ - public final static int MAX_RETRIES = 5; - /** - * TFTP timeout in milliseconds - */ - public final static int TFTP_ACK_TIMEOUT = 2000; - /** - * Description of the Field - */ - public final static int DEFAULT_PROXY_PORT = 3128; - - private static Log log = LogFactory.getLog(T2hproxy.class); - /** - * The members below must be per thread and must not share any storage with - * the main thread - */ - private DatagramSocket responsesocket; - private DatagramPacket response; - private InetAddress iaddr; - private int port; - private byte[] req; - private String prefix; - private String proxy = null; - private int timeout; - private HashMap options = new HashMap(); - private int blocksize = 512; - private HttpClient client = new HttpClient(); - private HttpMethod method; - private BufferedInputStream bstream = null; - private String message; - - - /** - * Constructor for the T2hproxy object - * - *@param i Description of the Parameter - *@param p Description of the Parameter - *@param b Description of the Parameter - *@param pf Description of the Parameter - *@param pr Description of the Parameter - *@param t Timeout for HTTP GET - */ - public T2hproxy(InetAddress i, int p, byte[] b, String pf, String pr, int t) { - iaddr = i; - port = p; - // make a copy of the request buffer - req = new byte[b.length]; - System.arraycopy(b, 0, req, 0, b.length); - prefix = pf; - // proxy can be null - proxy = pr; - timeout = t; - } - - - /** - * Extract an asciz string from bufer - * - *@param buffer Description of the Parameter - *@return The asciz value - */ - private String getAsciz(ByteBuffer buffer) { - StringBuffer s = new StringBuffer(); - try { - byte b; - while ((b = buffer.get()) != 0) { - s.append((char) b); - } - } catch (BufferUnderflowException e) { - } finally { - return (s.toString()); - } - } - - - /** - * Convert a string of digits to a number, invalid => 0 - * - *@param s Description of the Parameter - *@return Description of the Return Value - */ - private int atoi(String s) { - if (s == null) { - return (0); - } - int value = 0; - try { - value = (new Integer(s)).intValue(); - } catch (NumberFormatException e) { - } - return (value); - } - - - /** - * Wait for ack packet with timeout - * - *@return Return block number acked - */ - private int waitForAck() { - DatagramPacket ack = new DatagramPacket(new byte[MTU], MTU); - try { - do { - responsesocket.setSoTimeout(TFTP_ACK_TIMEOUT); - responsesocket.receive(ack); - } while (!ack.getAddress().equals(iaddr) || ack.getPort() != port); - } catch (SocketTimeoutException e) { - return (-1); - } catch (Exception e) { - log.info(e.toString(), e); - } - ByteBuffer buffer = ByteBuffer.wrap(ack.getData(), ack.getOffset(), ack.getLength() - ack.getOffset()); - short op; - if ((op = buffer.getShort()) == TFTP_ACK) { - return ((int) buffer.getShort()); - } else if (op == TFTP_ERROR) { - return (-2); - } - return (-3); - } - - - /** - * Description of the Method - * - *@param error Description of the Parameter - *@param message Description of the Parameter - */ - private void sendError(short error, String message) { - ByteBuffer buffer = ByteBuffer.wrap(response.getData()); - buffer.putShort(TFTP_ERROR).putShort(error).put(message.getBytes()); - response.setLength(buffer.position()); - try { - responsesocket.send(response); - } catch (Exception e) { - log.info(e.toString(), e); - } - } - - - /** - * Description of the Method - * - *@return Description of the Return Value - */ - private boolean sendOackRecvAck() { - ByteBuffer buffer = ByteBuffer.wrap(response.getData()); - buffer.putShort(TFTP_OACK).put("blksize".getBytes()).put((byte) 0).put(String.valueOf(blocksize).getBytes()).put((byte) 0); - response.setLength(buffer.position()); - int retry; - for (retry = 0; retry < MAX_RETRIES; retry++) { - try { - responsesocket.send(response); - } catch (Exception e) { - log.info(e.toString(), e); - } - if (waitForAck() == 0) { - log.debug("Ack received"); - break; - } - } - return (retry < MAX_RETRIES); - } - - - /** - * Description of the Method - * - *@param block Description of the Parameter - *@return Description of the Return Value - */ - private boolean sendDataBlock(int block) { - int retry; - for (retry = 0; retry < MAX_RETRIES; retry++) { - try { - responsesocket.send(response); - } catch (Exception e) { - log.info(e.toString(), e); - } - int ablock; - if ((ablock = waitForAck()) == block) { - log.debug("Ack received for " + ablock); - break; - } else if (ablock == -1) { - log.info("Timeout waiting for ack"); - } else if (ablock == -2) { - return (false); - } else { - log.info("Unknown opcode from ack"); - } - } - return (retry < MAX_RETRIES); - } - - - /** - * Description of the Method - * - *@param buffer Description of the Parameter - *@return Description of the Return Value - */ - private boolean handleOptions(ByteBuffer buffer) { - for (; ; ) { - String option = getAsciz(buffer); - String value = getAsciz(buffer); - if (option.equals("") || value.equals("")) { - break; - } - log.info(option + " " + value); - options.put(option, value); - } - blocksize = atoi((String) options.get("blksize")); - if (blocksize < 512) { - blocksize = 512; - } - if (blocksize > 1432) { - blocksize = 1432; - } - return (sendOackRecvAck()); - } - - - /** - * Description of the Method - * - *@param url Description of the Parameter - */ - private void makeStream(String url) { - // establish a connection within timeout milliseconds - client.setConnectionTimeout(timeout); - if (proxy != null) { - String[] hostport = proxy.split(":"); - int port = DEFAULT_PROXY_PORT; - if (hostport.length > 1) { - port = atoi(hostport[1]); - if (port == 0) { - port = DEFAULT_PROXY_PORT; - } - } - log.info("Proxy is " + hostport[0] + ":" + port); - client.getHostConfiguration().setProxy(hostport[0], port); - } - // create a method object - method = new GetMethod(url); - method.setFollowRedirects(true); - method.setStrictMode(false); - try { - int status; - if ((status = client.executeMethod(method)) != 200) { - log.info(message = method.getStatusText()); - return; - } - bstream = new BufferedInputStream(method.getResponseBodyAsStream()); - } catch (HttpException he) { - message = he.getMessage(); - } catch (IOException ioe) { - message = "Unable to get " + url; - } - } - - - /** - * Reads a block of data from URL stream - * - *@param stream Description of the Parameter - *@param data Description of the Parameter - *@param blocksize Description of the Parameter - *@param offset Description of the Parameter - *@return Number of bytes read - */ - private int readBlock(BufferedInputStream stream, byte[] data, int offset, int blocksize) { - int status; - int nread = 0; - while (nread < blocksize) { - try { - status = stream.read(data, offset + nread, blocksize - nread); - } catch (Exception e) { - return (-1); - } - if (status < 0) { - return (nread); - } - nread += status; - } - return (nread); - } - - - /** - * Description of the Method - * - *@param filename Description of the Parameter - */ - private void doRrq(String filename) { - String url = prefix + filename; - log.info("GET " + url); - makeStream(url); - if (bstream == null) { - log.info(message); - sendError(ERR_NOFILE, message); - return; - } - // read directly into send buffer to avoid buffer copying - byte[] data; - ByteBuffer buffer = ByteBuffer.wrap(data = response.getData()); - // dummy puts to get start position of data - buffer.putShort(TFTP_DATA).putShort((short) 0); - int start = buffer.position(); - int length; - int block = 1; - do { - length = readBlock(bstream, data, start, blocksize); - block &= 0xffff; - log.debug("Block " + block + " " + length); - // fill in the block number - buffer.position(0); - buffer.putShort(TFTP_DATA).putShort((short) block); - response.setLength(start + length); - if (!sendDataBlock(block)) { - break; - } - buffer.position(start); - block++; - } while (length >= blocksize); - log.info("Closing TFTP session"); - // clean up the connection resources - method.releaseConnection(); - method.recycle(); - } - - - /** - * Main processing method for the T2hproxy object - */ - public void run() { - ByteBuffer buffer = ByteBuffer.wrap(req); - buffer.getShort(); - String filename = getAsciz(buffer); - String mode = getAsciz(buffer); - log.info(filename + " " + mode); - response = new DatagramPacket(new byte[MTU], MTU, iaddr, port); - try { - responsesocket = new DatagramSocket(); - } catch (SocketException e) { - log.info(e.toString(), e); - return; - } - if (!handleOptions(buffer)) { - return; - } - doRrq(filename); - } - - - /** - * Description of the Method - * - *@param s Description of the Parameter - *@param r Description of the Parameter - *@param prefix Description of the Parameter - *@param proxy Description of the Parameter - *@param timeout Description of the Parameter - */ - public static void handleRequest(DatagramSocket s, DatagramPacket r, String prefix, String proxy, int timeout) { - log.info("Connection from " + r.getAddress().getCanonicalHostName() + ":" + r.getPort()); - ByteBuffer buffer = ByteBuffer.wrap(r.getData(), r.getOffset(), r.getLength() - r.getOffset()); - if (buffer.getShort() != TFTP_RRQ) { - DatagramPacket error = new DatagramPacket(new byte[MTU], MTU); - ByteBuffer rbuf = ByteBuffer.wrap(error.getData()); - rbuf.putShort(TFTP_ERROR).putShort(ERR_ILLOP).put("Illegal operation".getBytes()); - error.setLength(rbuf.position()); - try { - s.send(error); - } catch (Exception e) { - log.info(e.toString(), e); - } - return; - } - // fork thread - new Thread(new T2hproxy(r.getAddress(), r.getPort(), r.getData(), prefix, proxy, timeout)).start(); - } - - - /** - * The main program for the T2hproxy class - * - *@param argv The command line arguments - *@exception IOException Description of the Exception - */ - public static void main(String[] argv) throws IOException { - log.info(T2hproxy.NAME + "." + T2hproxy.VERSION); - int port = Integer.getInteger(T2hproxy.NAME + ".port", 69).intValue(); - String prefix = System.getProperty(T2hproxy.NAME + ".prefix", "http://localhost/"); - String proxy = System.getProperty(T2hproxy.NAME + ".proxy"); - int timeout = Integer.getInteger(T2hproxy.NAME + ".timeout", 5000).intValue(); - String propfile = System.getProperty(T2hproxy.NAME + ".properties"); - if (propfile != null) { - FileInputStream pf = new FileInputStream(propfile); - Properties p = new Properties(System.getProperties()); - p.load(pf); - // set the system properties - System.setProperties(p); - } - DatagramSocket requestsocket; - try { - requestsocket = new DatagramSocket(port); - } catch (SocketException e) { - log.info(e.toString(), e); - return; - } - DatagramPacket request = new DatagramPacket(new byte[MTU], MTU); - for (; ; ) { - try { - requestsocket.receive(request); - handleRequest(requestsocket, request, prefix, proxy, timeout); - } catch (Exception e) { - log.info(e.toString(), e); - } - } - } -} |