Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.wst.wsi/src/org/eclipse/wst/wsi/internal/core/monitor/SocketHandler.java')
-rw-r--r--bundles/org.eclipse.wst.wsi/src/org/eclipse/wst/wsi/internal/core/monitor/SocketHandler.java963
1 files changed, 0 insertions, 963 deletions
diff --git a/bundles/org.eclipse.wst.wsi/src/org/eclipse/wst/wsi/internal/core/monitor/SocketHandler.java b/bundles/org.eclipse.wst.wsi/src/org/eclipse/wst/wsi/internal/core/monitor/SocketHandler.java
deleted file mode 100644
index 8a38a2645..000000000
--- a/bundles/org.eclipse.wst.wsi/src/org/eclipse/wst/wsi/internal/core/monitor/SocketHandler.java
+++ /dev/null
@@ -1,963 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2002-2003 IBM Corporation, Beacon Information Technology Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM - Initial API and implementation
- * BeaconIT - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.wsi.internal.core.monitor;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.Socket;
-
-import org.eclipse.wst.wsi.internal.core.WSIConstants;
-import org.eclipse.wst.wsi.internal.core.WSIException;
-import org.eclipse.wst.wsi.internal.core.log.MessageEntry;
-import org.eclipse.wst.wsi.internal.core.util.Utils;
-
-/**
- * Socket Handler.
- *
- * @author Peter Brittenham (peterbr@us.ibm.com)
- * @version 1.0.1
- */
-public class SocketHandler extends Thread
-{
- protected SocketConnection socketConnection;
- protected SocketHandler pairedSocketHandler;
- protected String connectionType;
- protected int conversationID;
- protected String targetHost;
- protected int readTimeoutSeconds;
-
- protected Socket inSocket;
- protected Socket outSocket;
- protected InputStream inputStream = null;
- protected OutputStream outputStream = null;
-
- protected boolean verbose = false;
-
- protected boolean readTimedOut = false;
-
- // I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
- private String mimeCharset = null;
- private String xmlEncoding = null;
-
- protected static final String CRLF = "\r\n";
-
- protected static final String HTTP_100_CONTINUE =
- "100 Continue".toUpperCase();
- protected static final String CHUNKED =
- "Transfer-Encoding: chunked".toUpperCase();
- protected static final String CHUNKED_WITH_QUOTES =
- "Transfer-Encoding: \"chunked\"".toUpperCase();
- protected static final String CONTENT_LENGTH =
- "Content-Length:".toUpperCase();
-
- /**
- * Create socket handler.
- * @param socketConnection socket connection.
- * @param connectionType connection type.
- * @param conversationID conversation id.
- * @param targetHost target host.
- * @param inSocket in socket.
- * @param outSocket out socket.
- * @param readTimeoutSeconds read timeout seconds.
- */
- public SocketHandler(
- SocketConnection socketConnection,
- String connectionType,
- int conversationID,
- String targetHost,
- Socket inSocket,
- Socket outSocket,
- int readTimeoutSeconds)
- {
- this.socketConnection = socketConnection;
- this.connectionType = connectionType;
- this.conversationID = conversationID;
- this.targetHost = targetHost;
- this.inSocket = inSocket;
- this.outSocket = outSocket;
- this.readTimeoutSeconds = readTimeoutSeconds;
-
- // ADD:
- verbose =
- socketConnection.getMonitor().getMonitorConfig().getVerboseOption();
-
- start();
- }
-
- /**
- * Set paired socket handler.
- * @param pairedSocketHandler paired socket handler.
- */
- public void setPairedSocketHandler(SocketHandler pairedSocketHandler)
- {
- this.pairedSocketHandler = pairedSocketHandler;
- }
-
- /**
- * Send the data from the input socket to the output socket.
- */
- public void run()
- {
- int readLen;
- String readMsg;
- MessageContext messageContext = null;
-
- // Create read buffer
- byte[] readBuffer = new byte[4096];
-
- try
- {
- // Get the input and output streams
- this.inputStream = this.inSocket.getInputStream();
- this.outputStream = this.outSocket.getOutputStream();
-
- // Process while the connection is active
- // (NOTE: there might be more than 1 message per connection)
- boolean connectionActive = true;
- while (connectionActive)
- {
- // Reset all data
- readLen = 0;
- messageContext = new MessageContext();
-
- // Read until message is complete
- boolean messageComplete = false;
- while (!messageComplete)
- {
- try
- {
- // DEBUG:
- debug("run", "Read data from the input stream.");
-
- // Read data from the input stream
- readLen = inputStream.read(readBuffer, 0, readBuffer.length);
-
- // Reset read timeout flag
- readTimedOut = false;
-
- // DEBUG:
- debug("run", "readLen: " + readLen);
-
- if (readLen == -1)
- {
- connectionActive = false;
- messageComplete = true;
- }
-
- // If data was read, then check for 100 continue
- else if (readLen > 0)
- {
- // If this is the first data that was read, then get the timestamp
- if (messageContext.timestamp == null)
- messageContext.timestamp = Utils.getTimestamp();
-
- if (connectionType.equals(MessageEntry.TYPE_REQUEST))
- {
- byte[] toHost =
- new String(
- socketConnection.redirect.getToHost()
- + ":"
- + socketConnection.redirect.getToPort())
- .getBytes();
-
- String message = new String(readBuffer, 0, readLen);
-
- int index = message.indexOf(CRLF + "Host: ");
- if (index > -1)
- {
- index += 8;
- int secondPart = message.indexOf(CRLF, index);
-
- // Write the data to the output stream and then go format it
- write(this.outputStream, readBuffer, 0, index);
- write(this.outputStream, toHost, 0, toHost.length);
- write(
- this.outputStream,
- readBuffer,
- secondPart,
- readLen - secondPart);
- }
- else
- {
- // Write the data to the output stream and then go format it
- write(this.outputStream, readBuffer, 0, readLen);
- }
- }
- else
- {
- // Write the data to the output stream and then go format it
- write(this.outputStream, readBuffer, 0, readLen);
- }
-
- // DEBUG:
- if (verbose)
- {
- String bufferString = new String(readBuffer, 0, readLen);
- debug("run", "buffer as string: [" + bufferString + "]");
- if (bufferString.length() <= 50)
- debug(
- "run",
- "buffer as hexstring: ["
- + Utils.toHexString(bufferString)
- + "]");
- else
- debug(
- "run",
- "buffer as hexstring: ["
- + Utils.toHexString(bufferString.substring(0, 50))
- + " ...]");
- }
-
- // See if this part of the buffer contains the BOM
- if (messageContext.bom == 0)
- {
- messageContext.bom = getBOM(readBuffer);
- }
-
- // DEBUG
- debug("run", "bom: " + messageContext.bom);
-
- String encoding;
-
- try
- {
- encoding = getEncoding();
- readMsg =
- new String(
- readBuffer,
- 0,
- readLen,
- Utils.getJavaEncoding(encoding));
- setEncoding(readMsg);
- if (!encoding.equals(getEncoding()))
- {
- encoding = getEncoding();
- readMsg =
- new String(
- readBuffer,
- 0,
- readLen,
- Utils.getJavaEncoding(encoding));
- }
- }
-
- catch (UnsupportedEncodingException uee)
- {
- debug("run", "EXCEPTION (3): " + uee.toString());
- throw new RuntimeException(uee.toString());
- }
-
- // Set encoding in the message context
- messageContext.encoding = encoding;
-
- // DEBUG
- debug("run", "encoding: " + messageContext.encoding);
-
- // Process message
- messageContext = processMessage(readLen, readMsg, messageContext);
- }
-
- // If message is complete, then log it and reset buffer
- if ((isMessageComplete(messageContext))
- || ((readLen == -1) && (messageContext.messageBuffer.length() > 0)))
- {
- // Log message
- logMessage(messageContext);
-
- // Set message complete
- messageComplete = true;
- }
- }
-
- catch (InterruptedIOException ie)
- {
- // Set read timeout flag
- readTimedOut = true;
-
- debug("run", "InterruptedIOException: " + ie.toString());
-
- // If the read is not done, then shutdown
- if (pairedSocketHandler != null
- && pairedSocketHandler.isReadWaiting()
- && pairedSocketHandler.isReadTimedOut())
- {
- // DEBUG:
- debug("run", "read timed out on both sockets");
-
- // If there is data in the message buffer and it is complete, then log it
- if ((isMessageComplete(messageContext))
- || (messageContext.messageBuffer.length() > 0))
- {
- // Log message
- logMessage(messageContext);
- }
-
- // Set message complete
- connectionActive = false;
- messageComplete = true;
- }
- }
-
- catch (Exception e2)
- {
- // DEBUG:
- debug(
- "run",
- "EXCEPTION (2): "
- + e2.toString()
- + "\n"
- + Utils.getExceptionDetails(e2));
- //e2.printStackTrace();
-
- // If there is data in the message buffer and it is complete, then log it
- if ((isMessageComplete(messageContext))
- || (messageContext.messageBuffer.length() > 0))
- {
- // Log message
- logMessage(messageContext);
- }
-
- // Set message complete
- connectionActive = false;
- messageComplete = true;
- }
- }
- }
- }
-
- catch (Exception e)
- {
- // DEBUG:
- debug(
- "run",
- "EXCEPTION (1): "
- + e.getMessage()
- + "\n"
- + Utils.getExceptionDetails(e));
- //e.printStackTrace();
- }
-
- catch (Error err)
- {
- // DEBUG:
- debug("run", "ERROR: " + err.getMessage());
- //err.printStackTrace();
- }
-
- finally
- {
- shutdown();
- socketConnection.wakeUp();
- }
- }
-
- /**
- * Process the message.
- */
- private MessageContext processMessage(
- int readLen,
- String readMsg,
- MessageContext inMessageContext)
- throws WSIException
- {
- boolean continueRead = false;
-
- // Initialize message context
- MessageContext messageContext = inMessageContext;
-
- // Get message buffer and chunked data from message context
- StringBuffer messageBuffer = messageContext.messageBuffer;
- ChunkedData chunkedData = messageContext.chunkedData;
-
- // If all we received was the header with 100 continue, then ignore it
- if ((readMsg.toUpperCase().indexOf(HTTP_100_CONTINUE) != -1)
- && (readLen >= 25))
- {
- // DEBUG:
- debug("processMessage", "Ignore HTTP 100 Continue.");
-
- // Find the end of the HTTP 100 message
- int index = Utils.getFirstCRLFCRLF(readMsg);
-
- // If there is only the HTTP 100 message, then just ignore it
- if (index == readMsg.length())
- continueRead = true;
-
- // Otherwise remove the HTTP 100 message and continue
- else
- readMsg = readMsg.substring(index);
- }
-
- // ADD: What if a bypassed message contains another message after it?
- if (!continueRead && bypassMessage(readMsg))
- {
- // DEBUG:
- debug(
- "processMessage",
- "Do not log message as defined in the monitor spec, but it will be sent.");
-
- continueRead = true;
- }
-
- if (!continueRead)
- {
- int index = 0;
-
- // If there is chunked data, then get the length
- if ((readMsg.toUpperCase().indexOf(CHUNKED) != -1)
- || (readMsg.toUpperCase().indexOf(CHUNKED_WITH_QUOTES) != -1))
- {
- // DEBUG:
- debug("processMessage", "Processing chunked data...");
-
- // Get the location of the first CFLF
- if ((index = readMsg.indexOf(CRLF + CRLF)) == -1)
- {
- throw new WSIException("Could not locate end of HTTP header.");
- }
-
- // Include the CRLF+CRLF in the index
- index += 4;
-
- // DEBUG:
- debug(
- "processMessage",
- "Add header before decoding chunked data: ["
- + readMsg.substring(0, index)
- + "]");
-
- // Add HTTP header to buffer
- messageBuffer.append(readMsg.substring(0, index));
-
- // If there is no more data (i.e. header only), then just indicate that there is more chunked data
- if (readMsg.length() == index)
- {
- chunkedData = new ChunkedData(this, true);
-
- // DEBUG:
- debug(
- "processMessage",
- "There is chunk data, but none in this part of the message.");
- }
-
- // Determine if the remainder of the data is complete (i.e. ends with [0][CRLF][Optional Footer][CRLF])
- else
- {
- // Create chunked data object
- chunkedData = new ChunkedData(this, readMsg.substring(index));
-
- if (!chunkedData.isMoreChunkedData())
- {
- chunkedData.decodeAndAddDataToBuffer(messageBuffer);
- }
- }
- }
-
- else if (chunkedData != null && chunkedData.isMoreChunkedData())
- {
- // DEBUG:
- debug("processMessage", "Processing MORE chunked data...");
-
- // Add data
- chunkedData.addData(readMsg);
-
- // Decode data
- if (!chunkedData.isMoreChunkedData())
- {
- chunkedData.decodeAndAddDataToBuffer(messageBuffer);
- }
- }
-
- // Else just append the data to the buffer
- else
- {
- // DEBUG:
- debug(
- "processMessage",
- "Add data to message entry buffer: [" + readMsg + "]");
-
- messageBuffer.append(readMsg);
- }
- }
-
- // Set updated message buffer and chunked data in message context
- messageContext.messageBuffer = messageBuffer;
- messageContext.chunkedData = chunkedData;
-
- // Return message context
- return messageContext;
- }
-
- /**
- * Shutdown input socket and close input stream.
- * @param inSocket in socket.
- * @param inputStream input stream.
- */
- protected void stopInput(Socket inSocket, InputStream inputStream)
- {
- try
- {
- // If there is a input socket, then shutdown the input
- if (inSocket != null)
- {
- inSocket.shutdownInput();
- }
-
- // If there is an input stream then close it
- if (inputStream != null)
- {
- inputStream.close();
- }
- }
- catch (Exception e)
- {
- // Ignore since we are stopping everything
- }
-
- inputStream = null;
- }
-
- /**
- * Shutdown output socket and close output stream.
- * @param outSocket out socket.
- * @param outputStream output stream.
- */
- protected void stopOutput(Socket outSocket, OutputStream outputStream)
- {
- try
- {
- // If there is an output stream, then flush it
- if (outputStream != null)
- {
- outputStream.flush();
- }
-
- // If there is a input socket, then shutdown the input
- if (outSocket != null)
- {
- outSocket.shutdownOutput();
- }
-
- // If there is an output stream then close it
- if (outputStream != null)
- {
- outputStream.close();
- }
- }
-
- catch (Exception e)
- {
- // Ignore since we are stopping everything
- }
-
- outputStream = null;
- }
-
- /**
- * Shutdown handler.
- */
- public void shutdown()
- {
- // Stop both the input and output
- stopInput(this.inSocket, this.inputStream);
- stopOutput(this.outSocket, this.outputStream);
- }
-
- /**
- * Display debug messages.
- */
- void debug(String method, String message)
- {
- debug("SocketHandler", method, message);
- }
-
- /**
- * Display debug messages.
- */
- void debug(String className, String method, String message)
- {
- if (verbose)
- print(className, method, message);
- }
-
- /**
- * Display messages.
- */
- void print(String className, String method, String message)
- {
- System.out.println(
- "["
- + Thread.currentThread().getName()
- + "] ["
- + className
- + "."
- + method
- + "] ["
- + this.connectionType
- + "] "
- + message);
- }
-
- /**
- * Write data.
- */
- private void write(
- OutputStream outputStream,
- byte[] buffer,
- int start,
- int length)
- throws IOException
- {
- if (outputStream == null)
- {
- // DEBUG:
- debug("write", "Could not write buffer because output stream is null.");
- }
- else
- {
- // DEBUG:
- debug("write", "buffer: [" + new String(buffer, start, length) + "]");
-
- outputStream.write(buffer, start, length);
- }
- }
-
- /**
- * Check if message is complete.
- *
- * @param messageContext
- */
- private boolean isMessageComplete(MessageContext messageContext)
- throws WSIException
- {
- int index, index2, contentLen;
- boolean messageComplete = false;
-
- boolean moreChunkedData = messageContext.chunkedData.isMoreChunkedData();
-
- String message = messageContext.messageBuffer.toString();
-
- // Find the first CRLF + CRLF which marks the end of the HTTP header
- String httpHeader;
- index = Utils.getFirstCRLFCRLF(message);
- if (index == -1)
- httpHeader = message;
- else
- httpHeader = message.substring(0, index);
-
- // If chunked data, then complete only if there is no more data
- if (((httpHeader.toUpperCase().indexOf(CHUNKED) != -1)
- || (httpHeader.toUpperCase().indexOf(CHUNKED_WITH_QUOTES) != -1))
- && (!moreChunkedData))
- {
- debug(
- "isMessageComplete",
- "HTTP header indicates chunked data and there is no more chunked data");
- messageComplete = true;
- }
-
- // Check for content length
- else if ((index = httpHeader.toUpperCase().indexOf(CONTENT_LENGTH)) == -1)
- {
- debug("isMessageComplete", "HTTP header does not contain content length");
-
- // Should not have complete POST header without content length
- if (httpHeader.startsWith("POST"))
- {
- if (httpHeader.endsWith(CRLF + CRLF))
- {
- throw new WSIException("Could not locate content-length in HTTP POST header.");
- }
-
- messageComplete = false;
- }
-
- // This could be a GET, so see if the the complete header has been received
- else if (
- httpHeader.startsWith("GET")
- && (message.length() == httpHeader.length()
- && message.endsWith(CRLF + CRLF)))
- {
- messageComplete = true;
- }
-
- else
- {
- messageComplete = false;
- }
- }
-
- // If there is content length, then see if the entire message has been received
- else if ((index = httpHeader.toUpperCase().indexOf(CONTENT_LENGTH)) != -1)
- {
- // Find end of content length value
- index2 = httpHeader.indexOf(CRLF, index);
-
- debug("isMessageComplete", "CRLF: " + Utils.toHexString(CRLF));
- debug(
- "isMessageComplete",
- "httpHeader/index: " + Utils.toHexString(httpHeader.substring(index)));
-
- // Get content length
- contentLen =
- Integer
- .decode(
- httpHeader.substring(index + CONTENT_LENGTH.length() + 1, index2))
- .intValue();
-
- // DEBUG:
- debug("isMessageComplete", "contentLen: " + contentLen);
-
- // Find the first CRLF + CRLF which marks the end of the HTTP header
- index = Utils.getFirstCRLFCRLF(message);
-
- // DEBUG:
- debug(
- "isMessageComplete",
- "actual received message length: " + (message.length() - (index)));
-
- // If content length is equal to actual message content length, then message is complete
- if (contentLen == message.length() - index)
- {
- messageComplete = true;
-
- // DEBUG:
- debug(
- "isMessageComplete",
- "contentLen = actual received message length.");
- }
- }
-
- // Message is not complete
- else
- {
- messageComplete = false;
- }
-
- // DEBUG:
- debug("isMessageComplete", "messageComplete: " + messageComplete);
-
- return messageComplete;
- }
-
- /**
- * Log message.
- *
- * @param messageBuffer
- */
- private void logMessage(MessageContext messageContext) throws WSIException
- {
- // Determine sender and receiver host/port
- String senderHostAndPort, receiverHostAndPort;
-
- // Request
- if (connectionType.equals(MessageEntry.TYPE_REQUEST))
- {
- senderHostAndPort =
- inSocket.getInetAddress().getHostAddress() + ":" + inSocket.getPort();
- receiverHostAndPort = targetHost + ":" + outSocket.getPort();
- }
-
- // Response
- else
- {
- senderHostAndPort = targetHost + ":" + inSocket.getPort();
- receiverHostAndPort =
- outSocket.getInetAddress().getHostAddress() + ":" + outSocket.getPort();
- }
-
- // Create message entry
- this.socketConnection.logMessage(
- conversationID,
- this.connectionType,
- messageContext.timestamp,
- senderHostAndPort,
- receiverHostAndPort,
- messageContext.messageBuffer,
- messageContext.bom,
- messageContext.encoding);
- }
-
- /**
- * Check for HTTP messages that should not be logged.
- */
- private boolean bypassMessage(String message)
- {
- boolean bypass = false;
- if ((message.startsWith("CONNECT"))
- || (message.startsWith("TRACE"))
- || (message.startsWith("DELETE"))
- || (message.startsWith("OPTIONS"))
- || (message.startsWith("HEAD")))
- {
- bypass = true;
- }
-
- return bypass;
- }
-
- // I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
- /**
- * Set Encoding Parameters
- * @param messageFragment String of a HTTP message fragment.
- * @author K.Nakagome@BeaconIT Japan SIG
- */
- private void setEncoding(String messageFragment)
- {
- if (mimeCharset == null || mimeCharset.length() == 0)
- {
- mimeCharset = Utils.getHTTPCharset(messageFragment);
- }
- if (xmlEncoding == null || xmlEncoding.length() == 0)
- {
- xmlEncoding = Utils.getXMLEncoding(messageFragment);
- }
- return;
- }
-
- // I18N: 2003.02.26 modified by K.Nakagome@BeaconIT
- /**
- * Get Encoding Parameter
- * @return Character encoding of HTTP message.
- * @author K.Nakagome@BeaconIT Japan SIG
- */
- private String getEncoding()
- {
- String encoding = WSIConstants.DEFAULT_XML_ENCODING;
- if (mimeCharset != null && mimeCharset.length() > 0)
- {
- encoding = mimeCharset;
- }
- if (xmlEncoding != null && xmlEncoding.length() > 0)
- {
- encoding = xmlEncoding;
- }
- return encoding;
- }
-
- /**
- * Get the Byte Order Mark from the message (if there is one).
- */
- private int getBOM(byte[] message)
- {
- int bom = 0;
-
- byte FF = (byte) 0xFF;
- byte FE = (byte) 0xFE;
- byte EF = (byte) 0xEF;
- byte BB = (byte) 0xBB;
- byte BF = (byte) 0xBF;
-
- // Search through the byte array for CRLF+CRLF. This will mark the end of the header.
- int i = Utils.getFirstCRLFCRLF(message, 0);
- if (i != -1)
- {
- // DEBUG:
- debug(
- "getBOM",
- "message[i]: "
- + message[i]
- + ", message[i+1]: "
- + message[i+1]);
-
- // Check for UTF-8 BOM
- if (((i + 2) < message.length)
- && message[i] == EF
- && message[i+1] == BB
- && message[i+2] == BF)
- {
- bom = 0xEFBBBF;
- }
- // Check for UTF-16 big-endian BOM
- else if (
- ((i+1) < message.length)
- && message[i] == FE
- && message[i + 1] == FF)
- {
- bom = 0xFEFF;
- }
- // Check for UTF-16 little-endian BOM
- else if (
- ((i+1) < message.length)
- && message[i] == FF
- && message[i+1] == FE)
- {
- bom = 0xFFFE;
- }
- // ADD: Do we need to check for other BOMs
- }
- return bom;
- }
-
- /**
- * Determine if the read is still waiting for data.
- */
- boolean isReadWaiting()
- {
- boolean readWaiting = false;
-
- try
- {
- // DEBUG:
- debug(
- "isReadWaiting",
- "inSocket.getInputStream().available(): "
- + inSocket.getInputStream().available());
-
- if (inSocket.getInputStream().available() == 0)
- {
- readWaiting = true;
- }
- }
-
- catch (IOException ioe)
- {
- }
-
- return readWaiting;
- }
-
- /**
- * Get read timed out flag.
- */
- boolean isReadTimedOut()
- {
- return this.readTimedOut;
- }
-
- /**
- * Message context contains information about the message that is being processed.
- */
- class MessageContext
- {
- StringBuffer messageBuffer;
- ChunkedData chunkedData;
- String timestamp;
- int bom;
- String encoding;
-
- /**
- * Create new message context.
- */
- MessageContext()
- {
- messageBuffer = new StringBuffer();
- chunkedData = new ChunkedData();
- timestamp = null;
- bom = 0;
- encoding = WSIConstants.DEFAULT_XML_ENCODING;
- }
- }
-}

Back to the top