001: /*
002: * <copyright>
003: * Copyright 1999-2004 Cougaar Software, Inc.
004: * under sponsorship of the Defense Advanced Research Projects
005: * Agency (DARPA).
006: *
007: * You can redistribute this software and/or modify it under the
008: * terms of the Cougaar Open Source License as published on the
009: * Cougaar Open Source Website (www.cougaar.org).
010: *
011: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
012: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
013: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
014: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
015: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
016: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
017: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
018: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
019: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
020: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
021: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
022: *
023: * </copyright>
024: */
025:
026: package org.cougaar.mts.http;
027:
028: import java.io.BufferedInputStream;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.io.ObjectInputStream;
032: import java.io.ObjectOutputStream;
033: import java.io.PrintWriter;
034: import java.util.Enumeration;
035:
036: import javax.servlet.ServletException;
037: import javax.servlet.http.HttpServlet;
038: import javax.servlet.http.HttpServletRequest;
039: import javax.servlet.http.HttpServletResponse;
040:
041: import org.cougaar.core.service.LoggingService;
042: import org.cougaar.mts.base.CommFailureException;
043: import org.cougaar.mts.base.MessageDeliverer;
044: import org.cougaar.mts.base.MisdeliveredMessageException;
045: import org.cougaar.mts.std.AttributedMessage;
046:
047: /**
048: * Pulled out of HTTPLinkProtocol to simplify maintenance.
049: */
050: class HTTPLinkProtocolServlet extends HttpServlet {
051: private LoggingService logger;
052: private MessageDeliverer deliverer;
053:
054: // Logging is from the owner's logger (HTTPLinkProtocol)
055: HTTPLinkProtocolServlet(MessageDeliverer deliverer,
056: LoggingService logger) {
057: this .deliverer = deliverer;
058: this .logger = logger;
059: }
060:
061: public void usage(HttpServletResponse resp) throws IOException {
062: resp.setContentType("text/html");
063: PrintWriter out = resp.getWriter();
064: out
065: .println("<html><head><title>HTTP MTS Servlet</title></head>");
066: out.println("<body><h1>HTTP MTS Servlet</h1>");
067: out
068: .println("This Servlet is only for use by the HTTPLinkProtocol.");
069: out.println("</body></html>");
070: }
071:
072: public void doGet(HttpServletRequest req, HttpServletResponse resp)
073: throws ServletException, IOException {
074: usage(resp);
075: }
076:
077: public void doPost(HttpServletRequest req, HttpServletResponse resp)
078: throws ServletException, IOException {
079: Object result = null;
080:
081: if (logger.isDebugEnabled()) {
082: debugHeaders(req);
083: }
084:
085: try {
086: Object obj = readMessage(req.getInputStream(),
087: getContentLength(req));
088: if (!(obj instanceof AttributedMessage)) {
089: Exception e = new IllegalArgumentException(
090: "send message content of class: "
091: + obj.getClass().getName());
092: result = new CommFailureException(e);
093: if (logger.isDebugEnabled()) {
094: logger.debug(
095: "object not AttributedMessage but is a "
096: + obj.getClass().getName(), e);
097: }
098: } else {
099: AttributedMessage message = (AttributedMessage) obj;
100: // deliver the message by obtaining the
101: // MessageDeliverer from the LinkProtocol
102: result = deliverer.deliverMessage(message, message
103: .getTarget());
104: if (logger.isDebugEnabled()) {
105: logger.debug("DELIVERED "
106: + message.getRawMessage().getClass()
107: .getName() + "("
108: + message.getOriginator() + "->"
109: + message.getTarget() + ") with result="
110: + result);
111: }
112: }
113: } catch (MisdeliveredMessageException e) {
114: result = e;
115: } catch (Exception e) {
116: result = new CommFailureException(e);
117: } finally {
118: // return result
119: resp.setContentType("application/x-www-form-urlencoded");
120: ObjectOutputStream oos = new ObjectOutputStream(resp
121: .getOutputStream());
122: oos.writeObject(result);
123: oos.flush();
124: }
125: }
126:
127: // this method reads a serialized java object from the HTTP input
128: // stream, but can be overridden to read different message formats
129: // (e.g., SOAP messages).
130: protected Object readMessage(InputStream is, int mlen)
131: throws Exception {
132: // NOTE: Not sure if this is a hack or a solution to a
133: // problem, but we need to wrap the ServletInputStream in a
134: // BufferedInputStream. Otherwise, bytes on the stream
135: // disappear(?) and reading from the input stream hangs during
136: // readObject->readExternal->finishInput->verifySignature.
137: ObjectInputStream ois = new ObjectInputStream(
138: new BufferedInputStream(is, mlen));
139: Object obj = ois.readObject();
140: if (logger.isDebugEnabled()) {
141: logger.debug("read object from input stream");
142: }
143: ois.close();
144: return obj;
145: }
146:
147: private int getContentLength(HttpServletRequest req) {
148: int contentLength = 512;
149: try {
150: String header = req.getHeader("Content-length");
151: if (header != null) {
152: contentLength = Integer.parseInt(header);
153: } else {
154: if (logger.isDebugEnabled()) {
155: logger.debug("Content-length not available");
156: }
157: }
158: } catch (NumberFormatException nfe) {
159: logger.warn("Cannot parse Content-length", nfe);
160: }
161: return contentLength;
162: }
163:
164: private void debugHeaders(HttpServletRequest req) {
165: logger.debug("########## HTTP HEADERS ##########");
166: Enumeration e = req.getHeaderNames();
167: while (e.hasMoreElements()) {
168: String hdr = (String) e.nextElement();
169: logger.debug(hdr + ": " + req.getHeader(hdr));
170: }
171: logger.debug("##################################");
172: }
173: }
|