📄 jhbservlet.java
字号:
/* JabberHTTPBind - An implementation of JEP-0124 (HTTP Binding) * Please see http://www.jabber.org/jeps/jep-0124.html for details. * * Copyright (c) 2005 Stefan Strigler <steve@zeank.in-berlin.de> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */package org.jabber.JabberHTTPBind;import java.io.IOException;import java.io.PrintWriter;import java.io.StringWriter;import java.net.UnknownHostException;import javax.servlet.ServletException;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import org.w3c.dom.Document;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;/** * An implementation of JEP-0124 (HTTP Binding). See * http://www.jabber.org/jeps/jep-0124.html for details. * * @author Stefan Strigler <steve@zeank.in-berlin.de> */public final class JHBServlet extends HttpServlet { private DocumentBuilder db; private Janitor janitor; private static TransformerFactory tff = TransformerFactory.newInstance(); public static final String APP_VERSION = "0.2.3"; public static final String APP_NAME = "Jabber HTTP Binding Servlet"; public static final boolean DEBUG = true; public void init() throws ServletException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { db = dbf.newDocumentBuilder(); } catch (ParserConfigurationException e) { log("failed to create DocumentBuilderFactory", e); } janitor = new Janitor(); // cleans up sessions new Thread(janitor).start(); } public void destroy() { Session.stopSessions(); janitor.stop(); } /** * We only need to respond to POST requests ... * * @param request The servlet request we are processing * @param response The servlet response we are producing * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { try { ServletInputStream sis = request.getInputStream(); /* * parse request */ Document doc = db.newDocument(); synchronized (db) { doc = db.parse(sis); } Node rootNode = doc.getDocumentElement(); if (rootNode == null || !rootNode.getNodeName().equals("body")) // not a <body>-tag - don't know what to do with it response.sendError(HttpServletResponse.SC_BAD_REQUEST); else { /* * we got a <body /> request - let's look if there * something useful we could do with it */ NamedNodeMap attribs = rootNode.getAttributes(); if (attribs.getNamedItem("sid") != null) { /* *** * lookup existing session * *** */ Session sess = Session.getSession( attribs.getNamedItem("sid").getNodeValue()); if (sess != null) { /* *** * check if request is valid */ // polling too frequently if (System.currentTimeMillis() - sess.lastActive() < Session.MIN_POLLING) { response.sendError( HttpServletResponse.SC_FORBIDDEN); sess.terminate(); return; } // TODO: too many simultaneous requests // check if rid valid if (attribs.getNamedItem("rid") == null) { // rid missing response.sendError( HttpServletResponse.SC_UNAUTHORIZED); sess.terminate(); } /* *** * we got a valid request start processing it */ /* * check if we got sth to forward to remote jabber server */ if (rootNode.hasChildNodes()) sess.sendNodes(rootNode.getChildNodes()); /* * send response */ Response jresp = new Response(response, db.newDocument()); jresp.setContentType(sess.getContent()); /* * TODO: check for errors to inform client of */ // global one's // errors local to session /* * check incoming queue */ if (attribs.getNamedItem("type") != null) { String rType = attribs.getNamedItem("type") .getNodeValue(); if (rType.equals("terminate")) sess.terminate(); } NodeList nl = sess.checkInQ(); if (nl != null) for (int i=0; i<nl.getLength(); i++) jresp.addNode(nl.item(i)); /* * finally send it */ jresp.send(); } else { // no such session response.sendError( HttpServletResponse.SC_UNAUTHORIZED); } } else { /* *** * request to create a new session * *** */ if (attribs.getNamedItem("rid") == null) { response.sendError( HttpServletResponse.SC_BAD_REQUEST); return; } Response jresp = new Response( response,db.newDocument()); if (attribs.getNamedItem("to") == null || attribs.getNamedItem("to").getNodeValue() == "") { /* * ERROR: 'to' attribute missing or emtpy */ if (attribs.getNamedItem("content") != null) jresp.setContentType( attribs.getNamedItem("content").getNodeValue()); else jresp.setContentType(Session.DEFAULT_CONTENT); jresp.setAttribute("type", "terminate"); jresp.setAttribute("condition", "improper-addressing"); jresp.send(); return; } /* * really create new session */ try { Session sess = new Session(attribs.getNamedItem( "to").getNodeValue()); if (attribs.getNamedItem("content") != null) sess.setContent(attribs.getNamedItem("content") .getNodeValue()); if (attribs.getNamedItem("wait") != null) sess.setWait(Integer.parseInt(attribs.getNamedItem( "wait").getNodeValue())); if (attribs.getNamedItem("hold") != null) sess.setHold(Integer.parseInt(attribs.getNamedItem( "hold").getNodeValue())); if (attribs.getNamedItem("xml:lang") != null) sess.setXMLLang( attribs.getNamedItem("xml:lang").getNodeValue()); /* * send back response */ jresp.setContentType(sess.getContent()); jresp.setAttribute("sid", sess.getSID()); jresp.setAttribute("wait", String.valueOf(sess.getWait())); jresp.setAttribute("inactivity", String.valueOf(Session.MAX_INACTIVITY)); jresp.setAttribute("polling", String.valueOf(Session.MIN_POLLING)); if (sess.getAuthid() != "") jresp.setAttribute("authid",sess.getAuthid()); jresp.send(); } catch (UnknownHostException uhe) { /* * ERROR: remote host unknown */ jresp.setContentType( attribs.getNamedItem("content").getNodeValue()); jresp.setAttribute("type","terminate"); jresp.setAttribute("condition","host-unknown"); jresp.send(); } catch (IOException ioe) { /* * ERROR: could not connect to remote host */ jresp.setContentType( attribs.getNamedItem("content").getNodeValue()); jresp.setAttribute("type","terminate"); jresp.setAttribute("condition","remote-connection-failed"); jresp.send(); } } } } catch (SAXException se) { /* * ERROR: Parser error */ response.sendError(HttpServletResponse.SC_BAD_REQUEST); } catch (Exception e) { log(e.toString()); e.printStackTrace(); try { Response jresp = new Response(response,db.newDocument()); jresp.setAttribute("type","terminate"); jresp.setAttribute("condition","internal-server-error"); jresp.send(); } catch (Exception e2) { e2.printStackTrace(); response.sendError(HttpServletResponse.SC_BAD_REQUEST); } } } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { /* * This one's just for convenience to inform of improper use of * component */ response.setContentType("text/html"); PrintWriter writer = response.getWriter(); String title = APP_NAME + " v" + APP_VERSION; writer.println( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); writer.println( "<html>\n<head>\n<title>" + title + "</title>\n</head>\n<body>\n"); writer.println("<h1>" + title + "</h1>"); writer.println( "This is an implementation of JEP-0124 (HTTP-Binding). Please see <a href=\"http://www.jabber.org/jeps/jep-0124.html\">http://www.jabber.org/jeps/jep-0124.html</a> for details."); writer.println("\n</body>\n</html>"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -