| /* |
| * Copyright (c) 2008, 2009, 2011-2013, 2015 Eike Stepper (Berlin, Germany) 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: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.net4j.http.internal.server; |
| |
| import org.eclipse.net4j.buffer.IBufferHandler; |
| import org.eclipse.net4j.channel.IChannel; |
| import org.eclipse.net4j.http.common.IHTTPConnector; |
| import org.eclipse.net4j.http.internal.common.HTTPConnector; |
| import org.eclipse.net4j.http.internal.server.bundle.OM; |
| import org.eclipse.net4j.http.internal.server.messages.Messages; |
| import org.eclipse.net4j.http.server.INet4jTransportServlet; |
| import org.eclipse.net4j.protocol.IProtocol; |
| import org.eclipse.net4j.util.container.IPluginContainer; |
| import org.eclipse.net4j.util.io.ExtendedDataInputStream; |
| import org.eclipse.net4j.util.io.ExtendedDataOutputStream; |
| import org.eclipse.net4j.util.om.trace.ContextTracer; |
| |
| import org.eclipse.spi.net4j.AcceptorFactory; |
| |
| import javax.servlet.ServletException; |
| import javax.servlet.ServletInputStream; |
| import javax.servlet.ServletOutputStream; |
| import javax.servlet.http.HttpServlet; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public class Net4jTransportServlet extends HttpServlet implements INet4jTransportServlet |
| { |
| private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, Net4jTransportServlet.class); |
| |
| private static final long serialVersionUID = 1L; |
| |
| private RequestHandler requestHandler; |
| |
| public Net4jTransportServlet() |
| { |
| if (TRACER.isEnabled()) |
| { |
| TRACER.trace("Creating " + getClass().getName()); //$NON-NLS-1$ |
| } |
| } |
| |
| public RequestHandler getRequestHandler() |
| { |
| return requestHandler; |
| } |
| |
| public void setRequestHandler(RequestHandler requestHandler) |
| { |
| this.requestHandler = requestHandler; |
| } |
| |
| @Override |
| protected final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| doRequest(req, resp); |
| } |
| |
| @Override |
| protected final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| doRequest(req, resp); |
| } |
| |
| @SuppressWarnings("resource") |
| protected void doRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| if (requestHandler == null) |
| { |
| throw new ServletException(Messages.getString("Net4jTransportServlet_0")); //$NON-NLS-1$ |
| } |
| |
| String connectorID = req.getParameter("list"); //$NON-NLS-1$ |
| if (connectorID != null) |
| { |
| doList(connectorID, resp); |
| return; |
| } |
| |
| ServletInputStream servletInputStream = req.getInputStream(); |
| ExtendedDataInputStream in = new ExtendedDataInputStream(servletInputStream); |
| |
| ServletOutputStream servletOutputStream = resp.getOutputStream(); |
| ExtendedDataOutputStream out = new ExtendedDataOutputStream(servletOutputStream); |
| |
| int opcode = servletInputStream.read(); |
| switch (opcode) |
| { |
| case HTTPConnector.OPCODE_CONNECT: |
| doConnect(in, out); |
| break; |
| |
| case HTTPConnector.OPCODE_DISCONNECT: |
| doDisconnect(in, out); |
| break; |
| |
| case HTTPConnector.OPCODE_OPERATIONS: |
| doOperations(in, out); |
| break; |
| |
| default: |
| throw new IOException("Invalid opcaode: " + opcode); //$NON-NLS-1$ |
| } |
| |
| out.flush(); |
| } |
| |
| protected void doList(String connectorID, HttpServletResponse resp) throws IOException |
| { |
| if (TRACER.isEnabled()) |
| { |
| TRACER.format("Received List request: {0}", connectorID); //$NON-NLS-1$ |
| } |
| |
| IHTTPConnector[] connectors = requestHandler.handleList(connectorID); |
| PrintWriter writer = resp.getWriter(); |
| for (IHTTPConnector connector : connectors) |
| { |
| // TODO Security: Hide connectorID! |
| writer.write(connector.getConnectorID()); |
| writer.write(":"); //$NON-NLS-1$ |
| |
| String userID = connector.getUserID(); |
| if (userID != null) |
| { |
| writer.write(" userID=" + userID); //$NON-NLS-1$ |
| } |
| |
| if (connector instanceof HTTPServerConnector) |
| { |
| long idleTime = System.currentTimeMillis() - ((HTTPServerConnector)connector).getLastTraffic(); |
| writer.write(" idleTime=" + idleTime); //$NON-NLS-1$ |
| } |
| |
| writer.write("\n"); //$NON-NLS-1$ |
| |
| for (IChannel channel : connector.getChannels()) |
| { |
| writer.write(" "); //$NON-NLS-1$ |
| writer.write(String.valueOf(channel.getID())); |
| writer.write(": "); //$NON-NLS-1$ |
| IBufferHandler receiveHandler = channel.getReceiveHandler(); |
| if (receiveHandler instanceof IProtocol<?>) |
| { |
| writer.write(((IProtocol<?>)receiveHandler).getType()); |
| } |
| else |
| { |
| String string = receiveHandler.toString(); |
| if (string.length() > 256) |
| { |
| string = string.substring(0, 256); |
| } |
| |
| writer.write(string); |
| } |
| |
| writer.write(" ("); //$NON-NLS-1$ |
| writer.write(String.valueOf(channel.getID())); |
| writer.write(")\n"); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| protected void doConnect(ExtendedDataInputStream in, ExtendedDataOutputStream out) |
| throws ServletException, IOException |
| { |
| try |
| { |
| String userID = in.readString(); |
| if (TRACER.isEnabled()) |
| { |
| TRACER.format("Received Connect request: {0}", userID); //$NON-NLS-1$ |
| } |
| |
| IHTTPConnector connector = requestHandler.handleConnect(userID); |
| out.writeString(connector.getConnectorID()); |
| out.writeInt(connector.getMaxIdleTime()); |
| } |
| catch (Exception ex) |
| { |
| OM.LOG.error(ex); |
| out.writeString(null); |
| } |
| } |
| |
| protected void doDisconnect(ExtendedDataInputStream in, ExtendedDataOutputStream out) |
| throws ServletException, IOException |
| { |
| try |
| { |
| String connectorID = in.readString(); |
| if (TRACER.isEnabled()) |
| { |
| TRACER.format("Received Disconnect request: {0}", connectorID); //$NON-NLS-1$ |
| } |
| |
| requestHandler.handleDisonnect(connectorID); |
| } |
| catch (Exception ex) |
| { |
| OM.LOG.error(ex); |
| } |
| } |
| |
| protected void doOperations(ExtendedDataInputStream in, ExtendedDataOutputStream out) |
| throws ServletException, IOException |
| { |
| String connectorID = in.readString(); |
| if (TRACER.isEnabled()) |
| { |
| TRACER.format("Received Operations request: {0}", connectorID); //$NON-NLS-1$ |
| } |
| |
| requestHandler.handleOperations(connectorID, in, out); |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public static class ContainerAware extends Net4jTransportServlet |
| { |
| private static final String ACCEPTORS_GROUP = AcceptorFactory.PRODUCT_GROUP; |
| |
| private static final String HTTP_TYPE = HTTPAcceptorFactory.TYPE; |
| |
| private static final long serialVersionUID = 1L; |
| |
| private HTTPAcceptor acceptor; |
| |
| public ContainerAware() |
| { |
| } |
| |
| @Override |
| public void init() throws ServletException |
| { |
| super.init(); |
| |
| acceptor = (HTTPAcceptor)IPluginContainer.INSTANCE.getElement(ACCEPTORS_GROUP, HTTP_TYPE, null); |
| if (acceptor == null) |
| { |
| throw new ServletException(Messages.getString("Net4jTransportServlet_1")); //$NON-NLS-1$ |
| } |
| |
| acceptor.setServlet(this); |
| setRequestHandler(acceptor); |
| } |
| |
| @Override |
| public void destroy() |
| { |
| setRequestHandler(null); |
| acceptor.setServlet(null); |
| acceptor = null; |
| super.destroy(); |
| } |
| } |
| } |